@interactive-inc/claude-funnel 0.67.0 → 0.68.1

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 (54) hide show
  1. package/README.md +24 -3
  2. package/dist/bin.js +276 -270
  3. package/dist/{channels-BBA3GTAa.d.ts → channels-B0cifCfw.d.ts} +2 -1
  4. package/dist/claude.d.ts +2 -2
  5. package/dist/claude.js +5 -5
  6. package/dist/connector-descriptor-D4XtEsH8.d.ts +215 -0
  7. package/dist/connectors/discord.d.ts +3 -2
  8. package/dist/connectors/discord.js +1 -1
  9. package/dist/connectors/gh.d.ts +3 -2
  10. package/dist/connectors/gh.js +1 -1
  11. package/dist/connectors/schedule.d.ts +13 -11
  12. package/dist/connectors/schedule.js +3 -3
  13. package/dist/connectors/slack.d.ts +3 -2
  14. package/dist/connectors/slack.js +1 -1
  15. package/dist/diagnostic-event-CxMM5Bl2.js +78 -0
  16. package/dist/diagnostic-log-BsAg5qZK.d.ts +186 -0
  17. package/dist/diagnostics.d.ts +2 -2
  18. package/dist/diagnostics.js +3 -2
  19. package/dist/{discord-connector-CdjwPoty.js → discord-connector-CAcWifJn.js} +1 -1
  20. package/dist/docs.js +1 -1
  21. package/dist/doctor.d.ts +1 -1
  22. package/dist/event-log.d.ts +2 -0
  23. package/dist/event-log.js +3 -0
  24. package/dist/{file-process-guard-DAYe9Ndt.d.ts → file-process-guard-D-QatrwL.d.ts} +1 -1
  25. package/dist/{flume-source-listener-CLtsdcT2.d.ts → flume-source-listener-Ba8_1Mg-.d.ts} +2 -1
  26. package/dist/{funnel-diagnostics-B-PCuv_E.js → funnel-diagnostics-7rV3HxY3.js} +100 -143
  27. package/dist/{funnel-diagnostics-CnKus3Jg.d.ts → funnel-diagnostics-CDrZznTB.d.ts} +10 -13
  28. package/dist/{funnel-docs-BFcqITFA.js → funnel-docs-CI4hMkhq.js} +8 -3
  29. package/dist/{funnel-doctor-CviUTINw.d.ts → funnel-doctor-CY4S5cnz.d.ts} +1 -1
  30. package/dist/gateway/daemon.js +63 -83
  31. package/dist/gateway.d.ts +2 -2
  32. package/dist/gateway.js +1 -1
  33. package/dist/{gh-connector-D-iyjl-d.js → gh-connector-DMwI6zJA.js} +1 -1
  34. package/dist/{index-B4RvEaW-.d.ts → index-fHrKn4jm.d.ts} +7 -2
  35. package/dist/index.d.ts +18 -14
  36. package/dist/index.js +124 -30
  37. package/dist/local-config.d.ts +1 -1
  38. package/dist/logger.d.ts +6 -270
  39. package/dist/logger.js +6 -141
  40. package/dist/memory-event-log-BY8XjFzi.js +147 -0
  41. package/dist/{memory-token-prompter-D3R_kgM_.d.ts → memory-token-prompter-B20tl_aU.d.ts} +1 -1
  42. package/dist/{schedule-connector-teeDMHUe.js → schedule-connector-BXUOYgwZ.js} +59 -95
  43. package/dist/schedule-connector-schema-CNV8PgWX.js +137 -0
  44. package/dist/schedule-connector-schema-Tq5kJul-.d.ts +127 -0
  45. package/dist/{slack-connector-BE0KAjCs.js → slack-connector-BTtUiXAU.js} +2 -2
  46. package/dist/{slot-fields-5ERhytIA.js → slot-fields-eCWizJqS.js} +1 -1
  47. package/dist/{sqlite-diagnostic-log-BDxfXGZy.js → sqlite-diagnostic-log-Qs4cf9I_.js} +53 -84
  48. package/dist/sqlite-event-log-BYgCFMxC.d.ts +284 -0
  49. package/dist/{funnel-log-sqlite-sink-CXbs3qQp.js → sqlite-event-log-eZuXKszJ.js} +52 -11
  50. package/package.json +16 -1
  51. package/dist/connector-descriptor-F75ZI8Fh.d.ts +0 -391
  52. package/dist/diagnostic-sql-reader-CoBk_EFF.js +0 -83
  53. package/dist/schedule-connector-schema-C2AChpwX.js +0 -31
  54. package/dist/schedule-connector-schema-DBko_Bf7.d.ts +0 -48
@@ -1,85 +1,10 @@
1
1
  import { t as NodeFunnelFileSystem } from "./node-file-system-xJx7dymE.js";
2
2
  import { t as errorMessageOf } from "./error-message-of-BG4ezZ_s.js";
3
3
  import { t as FunnelConnectorListener } from "./connector-listener-BcQMzY6Q.js";
4
- import { n as scheduleConnectorSchema, r as scheduleEntrySchema } from "./schedule-connector-schema-C2AChpwX.js";
4
+ import { a as scheduleConnectorSchema, c as matchCron, o as scheduleEntryInputSchema, s as scheduleEntrySchema } from "./schedule-connector-schema-CNV8PgWX.js";
5
5
  import { t as FunnelConnectorDiagnosticsRecorder } from "./connector-diagnostics-recorder-BmOijU1p.js";
6
6
  import { dirname, join } from "node:path";
7
7
  import { z } from "zod";
8
- //#region lib/engine/connectors/match-cron.ts
9
- const parseField = (expr, min, max) => {
10
- const values = /* @__PURE__ */ new Set();
11
- for (const part of expr.split(",")) {
12
- const [rangePart, stepPart] = part.split("/");
13
- const step = stepPart ? Number(stepPart) : 1;
14
- if (!Number.isFinite(step) || step <= 0) throw new Error(`invalid cron step: "${stepPart}"`);
15
- let lo = min;
16
- let hi = max;
17
- if (rangePart === "*" || rangePart === void 0 || rangePart === "") {
18
- lo = min;
19
- hi = max;
20
- } else if (rangePart.includes("-")) {
21
- const [aStr, bStr] = rangePart.split("-");
22
- const a = Number(aStr);
23
- const b = Number(bStr);
24
- if (!Number.isFinite(a) || !Number.isFinite(b)) throw new Error(`invalid cron range: "${rangePart}"`);
25
- lo = a;
26
- hi = b;
27
- } else {
28
- const n = Number(rangePart);
29
- if (!Number.isFinite(n)) throw new Error(`invalid cron value: "${rangePart}"`);
30
- lo = n;
31
- hi = stepPart ? max : n;
32
- }
33
- if (lo < min || hi > max || lo > hi) throw new Error(`cron value out of range: ${rangePart} (must be ${min}-${max})`);
34
- for (let i = lo; i <= hi; i += step) values.add(i);
35
- }
36
- return {
37
- min,
38
- max,
39
- values
40
- };
41
- };
42
- /**
43
- * Returns true when `date` (local time) satisfies a 5-field cron expression.
44
- *
45
- * Two deliberate deviations from Vixie cron, called out so schedules are not
46
- * written expecting the other behavior:
47
- * - Day-of-month and day-of-week are ANDed, not ORed. Vixie cron fires when
48
- * EITHER matches once both are restricted; here every field must match.
49
- * - Day-of-week is 0-6 (Sunday=0). `7` for Sunday is NOT accepted (it throws
50
- * as out-of-range); use `0`.
51
- */
52
- const matchCron = (expr, date) => {
53
- const parts = expr.trim().split(/\s+/);
54
- if (parts.length !== 5) throw new Error(`cron must have 5 fields (got ${parts.length}): "${expr}"`);
55
- const [minute, hour, dom, month, dow] = parts;
56
- if (!minute || !hour || !dom || !month || !dow) throw new Error(`cron has empty fields: "${expr}"`);
57
- const fields = [
58
- {
59
- field: parseField(minute, 0, 59),
60
- value: date.getMinutes()
61
- },
62
- {
63
- field: parseField(hour, 0, 23),
64
- value: date.getHours()
65
- },
66
- {
67
- field: parseField(dom, 1, 31),
68
- value: date.getDate()
69
- },
70
- {
71
- field: parseField(month, 1, 12),
72
- value: date.getMonth() + 1
73
- },
74
- {
75
- field: parseField(dow, 0, 6),
76
- value: date.getDay()
77
- }
78
- ];
79
- for (const { field, value } of fields) if (!field.values.has(value)) return false;
80
- return true;
81
- };
82
- //#endregion
83
8
  //#region lib/engine/connectors/schedule-state-store.ts
84
9
  const defaultFs = new NodeFunnelFileSystem();
85
10
  /**
@@ -190,16 +115,35 @@ var FunnelScheduleListener = class extends FunnelConnectorListener {
190
115
  async tick(notify) {
191
116
  const now = this.truncateToMinute(this.now());
192
117
  const state = this.lastFiredStore.load();
193
- let changed = false;
118
+ const changes = [this.pruneRemovedEntries(state)];
194
119
  for (const entry of this.config.entries) {
195
120
  if (!entry.enabled) continue;
196
- if (await this.fireEntry(entry, now, state, notify)) changed = true;
121
+ const fired = await this.fireEntry(entry, now, state, notify);
122
+ changes.push(fired);
197
123
  }
198
- if (changed) this.lastFiredStore.save(state);
124
+ if (changes.includes(true)) this.lastFiredStore.save(state);
199
125
  }
200
126
  async fireEntry(entry, now, state, notify) {
127
+ if (entry.kind === "once") return this.fireOnceEntry(entry, now, state, notify);
128
+ return this.fireCronEntry(entry, now, state, notify);
129
+ }
130
+ async fireOnceEntry(entry, now, state, notify) {
131
+ if (state.has(entry.id)) return false;
132
+ const runAt = new Date(entry.runAt);
133
+ if (now.getTime() < runAt.getTime()) return false;
134
+ const lateness = now.getTime() - runAt.getTime();
135
+ if (entry.catchupPolicy === "skip" && lateness >= 6e4) {
136
+ state.set(entry.id, runAt);
137
+ return true;
138
+ }
139
+ await this.notifyOne(entry, runAt, notify, lateness > 0);
140
+ state.set(entry.id, runAt);
141
+ return true;
142
+ }
143
+ async fireCronEntry(entry, now, state, notify) {
201
144
  const lastFired = state.get(entry.id);
202
- const searchFrom = lastFired ? new Date(lastFired.getTime() + 6e4) : now;
145
+ const createdAt = entry.createdAt ? this.truncateToMinute(new Date(entry.createdAt)) : now;
146
+ const searchFrom = lastFired ? new Date(lastFired.getTime() + 6e4) : createdAt;
203
147
  if (searchFrom.getTime() > now.getTime()) return false;
204
148
  if (entry.catchupPolicy === "skip") {
205
149
  try {
@@ -214,30 +158,38 @@ var FunnelScheduleListener = class extends FunnelConnectorListener {
214
158
  }
215
159
  if (entry.catchupPolicy === "all") {
216
160
  const matches = this.findAllMatches(entry.cron, searchFrom, now, entry.id);
217
- if (matches.length === 0) return false;
161
+ if (matches.length === 0) return this.seedSearchWatermark(entry.id, lastFired, now, state);
218
162
  for (const match of matches) await this.notifyOne(entry, match, notify, match.getTime() !== now.getTime());
219
163
  state.set(entry.id, matches[matches.length - 1] ?? now);
220
164
  return true;
221
165
  }
222
166
  const match = this.findMostRecentMatch(entry.cron, searchFrom, now, entry.id);
223
- if (!match) return false;
167
+ if (!match) return this.seedSearchWatermark(entry.id, lastFired, now, state);
224
168
  await this.notifyOne(entry, match, notify, match.getTime() !== now.getTime());
225
169
  state.set(entry.id, match);
226
170
  return true;
227
171
  }
172
+ seedSearchWatermark(entryId, lastFired, now, state) {
173
+ if (lastFired !== void 0) return false;
174
+ state.set(entryId, now);
175
+ return true;
176
+ }
228
177
  async notifyOne(entry, firedAt, notify, catchup) {
229
178
  const meta = {
230
179
  event_type: "schedule",
231
180
  schedule_id: entry.id,
232
- cron: entry.cron,
181
+ schedule_kind: entry.kind,
233
182
  fired_at: firedAt.toISOString(),
234
183
  catchup_policy: entry.catchupPolicy
235
184
  };
185
+ if (entry.kind === "cron") meta.cron = entry.cron;
186
+ else meta.run_at = entry.runAt;
236
187
  if (catchup) meta.catchup = "true";
237
188
  const eventId = `${entry.id}@${firedAt.toISOString()}`;
238
189
  this.diagnostics.recordRaw(eventId, JSON.stringify({
239
190
  schedule_id: entry.id,
240
- cron: entry.cron,
191
+ kind: entry.kind,
192
+ ...entry.kind === "cron" ? { cron: entry.cron } : { run_at: entry.runAt },
241
193
  prompt: entry.prompt,
242
194
  fired_at: firedAt.toISOString(),
243
195
  catchup
@@ -308,16 +260,19 @@ var FunnelScheduleListener = class extends FunnelConnectorListener {
308
260
  copy.setSeconds(0, 0);
309
261
  return copy;
310
262
  }
263
+ pruneRemovedEntries(state) {
264
+ const configuredIds = new Set(this.config.entries.map((entry) => entry.id));
265
+ const removedIds = [];
266
+ for (const id of state.keys()) {
267
+ if (configuredIds.has(id)) continue;
268
+ state.delete(id);
269
+ removedIds.push(id);
270
+ }
271
+ return removedIds.length > 0;
272
+ }
311
273
  };
312
274
  //#endregion
313
275
  //#region lib/engine/connectors/schedule-connector.ts
314
- const addEntryArgsSchema = z.object({
315
- cron: z.string(),
316
- prompt: z.string(),
317
- id: z.string().optional(),
318
- enabled: z.boolean().optional(),
319
- catchupPolicy: scheduleEntrySchema.shape.catchupPolicy.optional()
320
- });
321
276
  const removeEntryArgsSchema = z.object({ id: z.string() });
322
277
  /**
323
278
  * Schedule connector descriptor. Pass `scheduleConnector()` to
@@ -375,11 +330,20 @@ const scheduleConnector = (options = {}) => ({
375
330
  },
376
331
  addEntry(props) {
377
332
  const parsed = scheduleConnectorSchema.parse(props.config);
378
- const args = addEntryArgsSchema.parse(props.args);
333
+ const args = scheduleEntryInputSchema.parse(props.args);
334
+ const id = args.id ?? props.context.generateId();
335
+ if (parsed.entries.some((entry) => entry.id === id)) throw new Error(`schedule entry "${id}" already exists`);
379
336
  const entry = scheduleEntrySchema.parse({
380
- id: args.id ?? props.context.generateId(),
381
- cron: args.cron,
337
+ id,
338
+ ..."cron" in args ? {
339
+ kind: "cron",
340
+ cron: args.cron
341
+ } : {
342
+ kind: "once",
343
+ runAt: args.runAt
344
+ },
382
345
  prompt: args.prompt,
346
+ createdAt: props.context.now,
383
347
  ...args.enabled !== void 0 ? { enabled: args.enabled } : {},
384
348
  ...args.catchupPolicy !== void 0 ? { catchupPolicy: args.catchupPolicy } : {}
385
349
  });
@@ -408,4 +372,4 @@ const scheduleConnector = (options = {}) => ({
408
372
  }
409
373
  });
410
374
  //#endregion
411
- export { matchCron as i, FunnelScheduleListener as n, FunnelScheduleStateStore as r, scheduleConnector as t };
375
+ export { FunnelScheduleListener as n, FunnelScheduleStateStore as r, scheduleConnector as t };
@@ -0,0 +1,137 @@
1
+ import { z } from "zod";
2
+ //#region lib/engine/connectors/match-cron.ts
3
+ const parseField = (expr, min, max) => {
4
+ const values = /* @__PURE__ */ new Set();
5
+ for (const part of expr.split(",")) {
6
+ if (part.length === 0) throw new Error(`invalid empty cron list item: "${expr}"`);
7
+ const stepSegments = part.split("/");
8
+ if (stepSegments.length > 2) throw new Error(`invalid cron step: "${part}"`);
9
+ const rangePart = stepSegments[0];
10
+ const stepPart = stepSegments[1];
11
+ if (stepSegments.length === 2 && stepPart === "") throw new Error(`invalid cron step: "${part}"`);
12
+ const step = stepPart ? Number(stepPart) : 1;
13
+ if (!Number.isInteger(step) || step <= 0) throw new Error(`invalid cron step: "${stepPart}"`);
14
+ let lo = min;
15
+ let hi = max;
16
+ if (rangePart === "*" || rangePart === void 0 || rangePart === "") {
17
+ lo = min;
18
+ hi = max;
19
+ } else if (rangePart.includes("-")) {
20
+ const rangeSegments = rangePart.split("-");
21
+ if (rangeSegments.length !== 2) throw new Error(`invalid cron range: "${rangePart}"`);
22
+ const aStr = rangeSegments[0];
23
+ const bStr = rangeSegments[1];
24
+ const a = Number(aStr);
25
+ const b = Number(bStr);
26
+ if (!Number.isInteger(a) || !Number.isInteger(b)) throw new Error(`invalid cron range: "${rangePart}"`);
27
+ lo = a;
28
+ hi = b;
29
+ } else {
30
+ const n = Number(rangePart);
31
+ if (!Number.isInteger(n)) throw new Error(`invalid cron value: "${rangePart}"`);
32
+ lo = n;
33
+ hi = stepPart ? max : n;
34
+ }
35
+ if (lo < min || hi > max || lo > hi) throw new Error(`cron value out of range: ${rangePart} (must be ${min}-${max})`);
36
+ for (let i = lo; i <= hi; i += step) values.add(i);
37
+ }
38
+ return {
39
+ min,
40
+ max,
41
+ values
42
+ };
43
+ };
44
+ const parseCron = (expr) => {
45
+ const parts = expr.trim().split(/\s+/);
46
+ if (parts.length !== 5) throw new Error(`cron must have 5 fields (got ${parts.length}): "${expr}"`);
47
+ const [minute, hour, dom, month, dow] = parts;
48
+ if (!minute || !hour || !dom || !month || !dow) throw new Error(`cron has empty fields: "${expr}"`);
49
+ return {
50
+ minute: parseField(minute, 0, 59),
51
+ hour: parseField(hour, 0, 23),
52
+ dayOfMonth: parseField(dom, 1, 31),
53
+ month: parseField(month, 1, 12),
54
+ dayOfWeek: parseField(dow, 0, 7),
55
+ dayOfMonthRestricted: dom !== "*",
56
+ dayOfWeekRestricted: dow !== "*"
57
+ };
58
+ };
59
+ /** Throws with a user-facing reason when `expr` is not a supported cron expression. */
60
+ const validateCronExpression = (expr) => {
61
+ parseCron(expr);
62
+ };
63
+ /**
64
+ * Returns true when `date` (local time) satisfies a standard 5-field cron
65
+ * expression. Sunday accepts both 0 and 7. When day-of-month and day-of-week
66
+ * are both restricted, either field matching is sufficient (Vixie cron).
67
+ */
68
+ const matchCron = (expr, date) => {
69
+ const cron = parseCron(expr);
70
+ if (!cron.minute.values.has(date.getMinutes())) return false;
71
+ if (!cron.hour.values.has(date.getHours())) return false;
72
+ if (!cron.month.values.has(date.getMonth() + 1)) return false;
73
+ const dayOfMonthMatches = cron.dayOfMonth.values.has(date.getDate());
74
+ const day = date.getDay();
75
+ const dayOfWeekMatches = cron.dayOfWeek.values.has(day) || day === 0 && cron.dayOfWeek.values.has(7);
76
+ if (cron.dayOfMonthRestricted && cron.dayOfWeekRestricted) return dayOfMonthMatches || dayOfWeekMatches;
77
+ return dayOfMonthMatches && dayOfWeekMatches;
78
+ };
79
+ //#endregion
80
+ //#region lib/engine/connectors/schedule-connector-schema.ts
81
+ /**
82
+ * Catch-up behavior when the daemon was down past one or more matching minutes.
83
+ *
84
+ * - `latest`: fire once with the most recent missed match (default; preserves prior behavior).
85
+ * - `all`: fire once per missed minute, oldest first (capped at 24 h).
86
+ * - `skip`: never fire missed matches; only fire when the current minute matches.
87
+ */
88
+ const scheduleCatchupPolicySchema = z.enum([
89
+ "latest",
90
+ "all",
91
+ "skip"
92
+ ]);
93
+ const cronExpressionSchema = z.string().superRefine((expression, context) => {
94
+ try {
95
+ validateCronExpression(expression);
96
+ } catch (error) {
97
+ context.addIssue({
98
+ code: "custom",
99
+ message: error instanceof Error ? error.message : String(error)
100
+ });
101
+ }
102
+ });
103
+ const scheduleEntryBaseSchema = z.object({
104
+ id: z.string(),
105
+ prompt: z.string(),
106
+ enabled: z.boolean().default(true),
107
+ catchupPolicy: scheduleCatchupPolicySchema.default("latest"),
108
+ createdAt: z.string().datetime().optional()
109
+ });
110
+ const scheduleEntryInputBaseSchema = z.object({
111
+ id: z.string().optional(),
112
+ prompt: z.string(),
113
+ enabled: z.boolean().optional(),
114
+ catchupPolicy: scheduleCatchupPolicySchema.optional()
115
+ });
116
+ const cronScheduleEntryInputSchema = scheduleEntryInputBaseSchema.extend({ cron: cronExpressionSchema }).strict();
117
+ const onceScheduleEntryInputSchema = scheduleEntryInputBaseSchema.extend({ runAt: z.string().datetime({ offset: true }) }).strict();
118
+ const scheduleEntryInputSchema = z.union([onceScheduleEntryInputSchema, cronScheduleEntryInputSchema]);
119
+ const cronScheduleEntrySchema = scheduleEntryBaseSchema.extend({
120
+ kind: z.literal("cron").default("cron"),
121
+ cron: cronExpressionSchema
122
+ });
123
+ const onceScheduleEntrySchema = scheduleEntryBaseSchema.extend({
124
+ kind: z.literal("once"),
125
+ runAt: z.string().datetime({ offset: true })
126
+ });
127
+ const scheduleEntrySchema = z.union([onceScheduleEntrySchema, cronScheduleEntrySchema]);
128
+ const scheduleConnectorSchema = z.object({
129
+ id: z.string(),
130
+ name: z.string(),
131
+ type: z.literal("schedule"),
132
+ entries: z.array(scheduleEntrySchema).default([]),
133
+ createdAt: z.string().datetime().optional(),
134
+ updatedAt: z.string().datetime().optional()
135
+ });
136
+ //#endregion
137
+ export { scheduleConnectorSchema as a, matchCron as c, scheduleCatchupPolicySchema as i, validateCronExpression as l, cronScheduleEntrySchema as n, scheduleEntryInputSchema as o, onceScheduleEntrySchema as r, scheduleEntrySchema as s, cronExpressionSchema as t };
@@ -0,0 +1,127 @@
1
+ import { z } from "zod";
2
+ //#region lib/engine/connectors/schedule-connector-schema.d.ts
3
+ /**
4
+ * Catch-up behavior when the daemon was down past one or more matching minutes.
5
+ *
6
+ * - `latest`: fire once with the most recent missed match (default; preserves prior behavior).
7
+ * - `all`: fire once per missed minute, oldest first (capped at 24 h).
8
+ * - `skip`: never fire missed matches; only fire when the current minute matches.
9
+ */
10
+ declare const scheduleCatchupPolicySchema: z.ZodEnum<{
11
+ latest: "latest";
12
+ all: "all";
13
+ skip: "skip";
14
+ }>;
15
+ type ScheduleCatchupPolicy = z.infer<typeof scheduleCatchupPolicySchema>;
16
+ declare const cronExpressionSchema: z.ZodString;
17
+ declare const scheduleEntryInputSchema: z.ZodUnion<readonly [z.ZodObject<{
18
+ id: z.ZodOptional<z.ZodString>;
19
+ prompt: z.ZodString;
20
+ enabled: z.ZodOptional<z.ZodBoolean>;
21
+ catchupPolicy: z.ZodOptional<z.ZodEnum<{
22
+ latest: "latest";
23
+ all: "all";
24
+ skip: "skip";
25
+ }>>;
26
+ runAt: z.ZodString;
27
+ }, z.core.$strict>, z.ZodObject<{
28
+ id: z.ZodOptional<z.ZodString>;
29
+ prompt: z.ZodString;
30
+ enabled: z.ZodOptional<z.ZodBoolean>;
31
+ catchupPolicy: z.ZodOptional<z.ZodEnum<{
32
+ latest: "latest";
33
+ all: "all";
34
+ skip: "skip";
35
+ }>>;
36
+ cron: z.ZodString;
37
+ }, z.core.$strict>]>;
38
+ type ScheduleEntryInput = z.input<typeof scheduleEntryInputSchema>;
39
+ declare const cronScheduleEntrySchema: z.ZodObject<{
40
+ id: z.ZodString;
41
+ prompt: z.ZodString;
42
+ enabled: z.ZodDefault<z.ZodBoolean>;
43
+ catchupPolicy: z.ZodDefault<z.ZodEnum<{
44
+ latest: "latest";
45
+ all: "all";
46
+ skip: "skip";
47
+ }>>;
48
+ createdAt: z.ZodOptional<z.ZodString>;
49
+ kind: z.ZodDefault<z.ZodLiteral<"cron">>;
50
+ cron: z.ZodString;
51
+ }, z.core.$strip>;
52
+ declare const onceScheduleEntrySchema: z.ZodObject<{
53
+ id: z.ZodString;
54
+ prompt: z.ZodString;
55
+ enabled: z.ZodDefault<z.ZodBoolean>;
56
+ catchupPolicy: z.ZodDefault<z.ZodEnum<{
57
+ latest: "latest";
58
+ all: "all";
59
+ skip: "skip";
60
+ }>>;
61
+ createdAt: z.ZodOptional<z.ZodString>;
62
+ kind: z.ZodLiteral<"once">;
63
+ runAt: z.ZodString;
64
+ }, z.core.$strip>;
65
+ declare const scheduleEntrySchema: z.ZodUnion<readonly [z.ZodObject<{
66
+ id: z.ZodString;
67
+ prompt: z.ZodString;
68
+ enabled: z.ZodDefault<z.ZodBoolean>;
69
+ catchupPolicy: z.ZodDefault<z.ZodEnum<{
70
+ latest: "latest";
71
+ all: "all";
72
+ skip: "skip";
73
+ }>>;
74
+ createdAt: z.ZodOptional<z.ZodString>;
75
+ kind: z.ZodLiteral<"once">;
76
+ runAt: z.ZodString;
77
+ }, z.core.$strip>, z.ZodObject<{
78
+ id: z.ZodString;
79
+ prompt: z.ZodString;
80
+ enabled: z.ZodDefault<z.ZodBoolean>;
81
+ catchupPolicy: z.ZodDefault<z.ZodEnum<{
82
+ latest: "latest";
83
+ all: "all";
84
+ skip: "skip";
85
+ }>>;
86
+ createdAt: z.ZodOptional<z.ZodString>;
87
+ kind: z.ZodDefault<z.ZodLiteral<"cron">>;
88
+ cron: z.ZodString;
89
+ }, z.core.$strip>]>;
90
+ type ScheduleEntry = z.infer<typeof scheduleEntrySchema>;
91
+ type CronScheduleEntry = z.infer<typeof cronScheduleEntrySchema>;
92
+ type OnceScheduleEntry = z.infer<typeof onceScheduleEntrySchema>;
93
+ declare const scheduleConnectorSchema: z.ZodObject<{
94
+ id: z.ZodString;
95
+ name: z.ZodString;
96
+ type: z.ZodLiteral<"schedule">;
97
+ entries: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
98
+ id: z.ZodString;
99
+ prompt: z.ZodString;
100
+ enabled: z.ZodDefault<z.ZodBoolean>;
101
+ catchupPolicy: z.ZodDefault<z.ZodEnum<{
102
+ latest: "latest";
103
+ all: "all";
104
+ skip: "skip";
105
+ }>>;
106
+ createdAt: z.ZodOptional<z.ZodString>;
107
+ kind: z.ZodLiteral<"once">;
108
+ runAt: z.ZodString;
109
+ }, z.core.$strip>, z.ZodObject<{
110
+ id: z.ZodString;
111
+ prompt: z.ZodString;
112
+ enabled: z.ZodDefault<z.ZodBoolean>;
113
+ catchupPolicy: z.ZodDefault<z.ZodEnum<{
114
+ latest: "latest";
115
+ all: "all";
116
+ skip: "skip";
117
+ }>>;
118
+ createdAt: z.ZodOptional<z.ZodString>;
119
+ kind: z.ZodDefault<z.ZodLiteral<"cron">>;
120
+ cron: z.ZodString;
121
+ }, z.core.$strip>]>>>;
122
+ createdAt: z.ZodOptional<z.ZodString>;
123
+ updatedAt: z.ZodOptional<z.ZodString>;
124
+ }, z.core.$strip>;
125
+ type ScheduleConnectorConfig = z.infer<typeof scheduleConnectorSchema>;
126
+ //#endregion
127
+ export { ScheduleEntry as a, cronScheduleEntrySchema as c, scheduleConnectorSchema as d, scheduleEntryInputSchema as f, ScheduleConnectorConfig as i, onceScheduleEntrySchema as l, OnceScheduleEntry as n, ScheduleEntryInput as o, scheduleEntrySchema as p, ScheduleCatchupPolicy as r, cronExpressionSchema as s, CronScheduleEntry as t, scheduleCatchupPolicySchema as u };
@@ -5,7 +5,7 @@ import { t as slackConnectorSchema } from "./slack-connector-schema-EGVuuqSX.js"
5
5
  import { t as FunnelConnectorAdapter } from "./connector-adapter-BL2ehMej.js";
6
6
  import { t as FunnelSlackEventProcessor } from "./slack-event-processor-Cs_YuI3w.js";
7
7
  import { t as resolveConnectorToken } from "./resolve-connector-token-BwiJCu82.js";
8
- import { i as resolveFlumeDeps, n as FunnelFlumeSourceListener, r as flumeLogHandler, t as slotFields } from "./slot-fields-5ERhytIA.js";
8
+ import { i as resolveFlumeDeps, n as FunnelFlumeSourceListener, r as flumeLogHandler, t as slotFields } from "./slot-fields-eCWizJqS.js";
9
9
  import { z } from "zod";
10
10
  import { FlumeSlackSource } from "@interactive-inc/flume/slack";
11
11
  //#region lib/engine/connectors/slack-adapter.ts
@@ -219,7 +219,7 @@ var FunnelFlumeSlackListener = class extends FunnelFlumeSourceListener {
219
219
  }
220
220
  })).text();
221
221
  } catch (error) {
222
- this.diagnostics.recordConnection("auth-failed", errorMessageOf(error));
222
+ this.diagnostics.recordConnection("error", errorMessageOf(error));
223
223
  throw error;
224
224
  }
225
225
  const parsed = authTestResponseSchema.safeParse(safeJsonParse(text));
@@ -46,7 +46,7 @@ const flumeLogHandler = (logger) => {
46
46
  };
47
47
  };
48
48
  const buildMeta = (log) => {
49
- const meta = { ...log.detail ?? {} };
49
+ const meta = { ...log.detail };
50
50
  if (log.error) {
51
51
  meta.error = log.error.message;
52
52
  if (log.error.stack) meta.stack = log.error.stack;