@sentry/junior 0.141.0 → 0.143.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 (70) hide show
  1. package/dist/{agent-hooks-HIRVKUQJ.js → agent-hooks-2EP3QS47.js} +10 -10
  2. package/dist/api/schema/task.d.ts +8 -0
  3. package/dist/api/schema.js +1 -1
  4. package/dist/api.js +34 -22
  5. package/dist/app.js +62 -91
  6. package/dist/{catalog-runtime-XVLED5UH.js → catalog-runtime-IAVW4W3B.js} +5 -5
  7. package/dist/chat/event-tasks/types.d.ts +7 -1
  8. package/dist/chat/runtime/turn.d.ts +0 -4
  9. package/dist/chat/scheduled-tasks/tools/create.d.ts +1 -0
  10. package/dist/chat/scheduled-tasks/types.d.ts +5 -0
  11. package/dist/chat/services/conversation-memory.d.ts +2 -1
  12. package/dist/chat/services/short-title.d.ts +25 -0
  13. package/dist/chat/state/conversation.d.ts +6 -17
  14. package/dist/chat/tools/create-event-task.d.ts +1 -0
  15. package/dist/{chunk-3H42HMA2.js → chunk-2KLMGRRQ.js} +5 -1
  16. package/dist/{chunk-HN4UZTG7.js → chunk-2T5CHXRZ.js} +2 -2
  17. package/dist/{chunk-PGJUJCOQ.js → chunk-5YJBS4I5.js} +1 -1
  18. package/dist/{chunk-BBLO66XT.js → chunk-7GVX5SOG.js} +2 -2
  19. package/dist/{chunk-2DOVDDZJ.js → chunk-A3XPSABC.js} +3 -3
  20. package/dist/{chunk-FZFJZZR3.js → chunk-AEFJN7OK.js} +4 -4
  21. package/dist/{chunk-DK3GQWJK.js → chunk-ANG7IWAI.js} +6 -6
  22. package/dist/{chunk-LMGKSDO4.js → chunk-BJ6ISBOA.js} +1 -1
  23. package/dist/{chunk-H4WNQFBH.js → chunk-F6RWNJBK.js} +5 -5
  24. package/dist/{chunk-UFEU4UX6.js → chunk-GZRWULXF.js} +1 -1
  25. package/dist/{chunk-DVIJ6DP6.js → chunk-I25V3XRN.js} +2 -2
  26. package/dist/{chunk-A2O7SGK5.js → chunk-I4NQNZVW.js} +6 -6
  27. package/dist/{chunk-DKH4WGZU.js → chunk-I5PIM72M.js} +341 -16
  28. package/dist/{chunk-FWXSPJRN.js → chunk-LSBQHDI2.js} +1 -1
  29. package/dist/{chunk-6U44QGXL.js → chunk-M2T7MHQJ.js} +1 -1
  30. package/dist/{chunk-5MFCEKR6.js → chunk-NAINBOZQ.js} +3 -3
  31. package/dist/{chunk-EYD523BV.js → chunk-NVFVM67W.js} +1 -1
  32. package/dist/{chunk-43OPSFUY.js → chunk-OB7ZJK7Y.js} +1 -1
  33. package/dist/{chunk-HQAFIN6O.js → chunk-OG5JQHKR.js} +1 -1
  34. package/dist/{chunk-YWM6MJT4.js → chunk-OGQGJAD7.js} +2 -0
  35. package/dist/{chunk-PIQKV7IR.js → chunk-PBV7VXUA.js} +10 -451
  36. package/dist/{chunk-LIVSCWI5.js → chunk-QFWXGUAH.js} +23 -26
  37. package/dist/{chunk-UONUDOJP.js → chunk-RABHACKG.js} +7 -7
  38. package/dist/{chunk-7ULXCNOZ.js → chunk-SNBTWIQO.js} +6 -6
  39. package/dist/chunk-STX5WIH6.js +75 -0
  40. package/dist/{chunk-44NWPKY3.js → chunk-TPJK6AVJ.js} +1 -1
  41. package/dist/{chunk-6FRAWWGR.js → chunk-U5ATCOHE.js} +2 -2
  42. package/dist/{chunk-5LPWHC7Q.js → chunk-UFCA4EZB.js} +80 -46
  43. package/dist/chunk-WJHWOAVZ.js +67 -0
  44. package/dist/{chunk-NFL4FRIU.js → chunk-WM4PRM7W.js} +4 -4
  45. package/dist/{chunk-OFQBDHVG.js → chunk-WSWVWP2V.js} +1 -1
  46. package/dist/{chunk-DBKS7JR2.js → chunk-X5SC2UGE.js} +3 -3
  47. package/dist/{chunk-OHO46E7F.js → chunk-XYJNNZYR.js} +88 -36
  48. package/dist/cli/chat.js +32 -30
  49. package/dist/cli/check.js +6 -6
  50. package/dist/cli/plugins.js +13 -13
  51. package/dist/cli/snapshot-create.js +9 -9
  52. package/dist/cli/upgrade.js +7 -7
  53. package/dist/db/schema/event-tasks.d.ts +20 -52
  54. package/dist/db/schema/scheduled-tasks.d.ts +17 -0
  55. package/dist/db/schema.d.ts +36 -52
  56. package/dist/{db-PSMQZR4P.js → db-RBXBVEVO.js} +7 -7
  57. package/dist/instrumentation.js +4 -4
  58. package/dist/nitro.js +2 -2
  59. package/dist/{oauth-callback-server-XZUK2AT6.js → oauth-callback-server-LRB6BX6C.js} +23 -21
  60. package/dist/{runner-5EKJCQWP.js → runner-WK5VUOW6.js} +24 -25
  61. package/dist/{skills-2PRM42SE.js → skills-MJWRME3A.js} +6 -6
  62. package/dist/{spawn-UGTLRTFP.js → spawn-ZCW6UOAA.js} +17 -17
  63. package/dist/{validation-XLXAIRTR.js → validation-556WSWVU.js} +6 -6
  64. package/dist/version.js +1 -1
  65. package/dist/{work-CNTNEQ2Q.js → work-W6IXSPY3.js} +16 -16
  66. package/dist/{worker-BGW7CKZ7.js → worker-5KM346HH.js} +10 -10
  67. package/migrations/0023_task_title_columns.sql +2 -0
  68. package/migrations/meta/0023_snapshot.json +2198 -0
  69. package/migrations/meta/_journal.json +7 -0
  70. package/package.json +5 -5
@@ -4,8 +4,9 @@ import {
4
4
  import {
5
5
  ensureConversationWake,
6
6
  requestConversationWork
7
- } from "./chunk-NFL4FRIU.js";
7
+ } from "./chunk-WM4PRM7W.js";
8
8
  import {
9
+ buildConversationContext,
9
10
  buildDeliveredTurnStatePatch,
10
11
  finalizeFailedTurnReplyWithEvent,
11
12
  getInterruptionMarker,
@@ -13,11 +14,14 @@ import {
13
14
  getTurnUserMessageId,
14
15
  getTurnUserReplyAttachmentContext,
15
16
  getTurnUserSlackMessageTs,
17
+ markConversationMessage,
16
18
  persistAuthPauseTurnState,
19
+ recordDeliveredAssistantMessage,
17
20
  requireTurnFailureEventId,
18
21
  resolveTurnSessionRouting,
19
- scheduleSessionCompletedPluginTasks
20
- } from "./chunk-DKH4WGZU.js";
22
+ scheduleSessionCompletedPluginTasks,
23
+ turnHasReply
24
+ } from "./chunk-I5PIM72M.js";
21
25
  import {
22
26
  ConversationTurnLifecycleService
23
27
  } from "./chunk-Q6QZTTLS.js";
@@ -35,7 +39,7 @@ import {
35
39
  getMcpProviderErrorAttributes,
36
40
  getMcpStoredOAuthCredentials,
37
41
  resolvePluginOAuthAccount
38
- } from "./chunk-UONUDOJP.js";
42
+ } from "./chunk-RABHACKG.js";
39
43
  import {
40
44
  RetryableDeliveryError
41
45
  } from "./chunk-R776HKPK.js";
@@ -51,11 +55,10 @@ import {
51
55
  removeReactionFromMessage,
52
56
  resolveBaseUrl,
53
57
  truncateStatusText
54
- } from "./chunk-DK3GQWJK.js";
58
+ } from "./chunk-ANG7IWAI.js";
55
59
  import {
56
60
  TurnSliceLimitExceededError,
57
61
  abandonAgentTurnSessionRecord,
58
- buildConversationContext,
59
62
  buildTurnLimitResponse,
60
63
  clearPendingAuth,
61
64
  coerceThreadArtifactsState,
@@ -71,43 +74,39 @@ import {
71
74
  hydrateConversationMessages,
72
75
  isPendingAuthLatestRequest,
73
76
  loadProjection,
74
- markConversationMessage,
75
77
  markTurnFailed,
76
78
  persistCompletedSessionRecord,
77
79
  persistThreadStateById,
78
80
  persistWithRetry,
79
81
  recordAgentTurnSessionSummary,
80
82
  recordAuthenticationLinked,
81
- recordAuthorizationCompleted,
82
- recordDeliveredAssistantMessage,
83
- turnHasReply,
84
- updateConversationStats
85
- } from "./chunk-PIQKV7IR.js";
83
+ recordAuthorizationCompleted
84
+ } from "./chunk-PBV7VXUA.js";
86
85
  import {
87
86
  parseSlackThreadId,
88
87
  readSlackRawMessageContext,
89
88
  resolveSlackChannelIdFromMessage,
90
89
  resolveSlackChannelIdFromThreadId
91
- } from "./chunk-HQAFIN6O.js";
90
+ } from "./chunk-OG5JQHKR.js";
92
91
  import {
93
92
  getDashboardConversationLink,
94
93
  getPluginSlackConversationLink
95
- } from "./chunk-7ULXCNOZ.js";
94
+ } from "./chunk-SNBTWIQO.js";
96
95
  import {
97
96
  SlackActionError,
98
97
  getHeaderString,
99
98
  getSlackClient,
100
99
  isDmChannel,
101
100
  normalizeSlackConversationId
102
- } from "./chunk-DVIJ6DP6.js";
101
+ } from "./chunk-I25V3XRN.js";
103
102
  import {
104
103
  getConversationEventStore,
105
104
  requireSlackDestination
106
- } from "./chunk-5MFCEKR6.js";
105
+ } from "./chunk-NAINBOZQ.js";
107
106
  import {
108
107
  acquireActiveLock,
109
108
  getStateAdapter
110
- } from "./chunk-6U44QGXL.js";
109
+ } from "./chunk-M2T7MHQJ.js";
111
110
  import {
112
111
  FUNCTION_TIMEOUT_BUFFER_SECONDS,
113
112
  botConfig,
@@ -116,18 +115,18 @@ import {
116
115
  getRuntimeMetadata,
117
116
  normalizeSlackEmojiName,
118
117
  standardModelId
119
- } from "./chunk-BBLO66XT.js";
118
+ } from "./chunk-7GVX5SOG.js";
120
119
  import {
121
120
  discoverSkills
122
- } from "./chunk-6FRAWWGR.js";
121
+ } from "./chunk-U5ATCOHE.js";
123
122
  import {
124
123
  pluginCatalogRuntime
125
- } from "./chunk-EYD523BV.js";
124
+ } from "./chunk-NVFVM67W.js";
126
125
  import {
127
126
  buildOAuthTokenRequest,
128
127
  hasRequiredOAuthScope,
129
128
  parseOAuthTokenResponse
130
- } from "./chunk-LMGKSDO4.js";
129
+ } from "./chunk-BJ6ISBOA.js";
131
130
  import {
132
131
  createSlackResumeActor,
133
132
  isUserActor
@@ -143,7 +142,7 @@ import {
143
142
  setTags,
144
143
  toOptionalString,
145
144
  withLogContext
146
- } from "./chunk-UFEU4UX6.js";
145
+ } from "./chunk-GZRWULXF.js";
147
146
  import {
148
147
  homeDir
149
148
  } from "./chunk-H4HBKISO.js";
@@ -1925,8 +1924,7 @@ async function persistFailedReplyState(channelId, threadTs, sessionId, expectedV
1925
1924
  nowMs: Date.now(),
1926
1925
  sessionId,
1927
1926
  userMessageId: getTurnUserMessageId(conversation, sessionId),
1928
- markConversationMessage,
1929
- updateConversationStats
1927
+ markConversationMessage
1930
1928
  });
1931
1929
  await failSessionRecordBestEffort({
1932
1930
  conversationId: threadId,
@@ -2533,8 +2531,7 @@ async function persistFailedOAuthReplyState(args) {
2533
2531
  nowMs: Date.now(),
2534
2532
  sessionId: args.sessionId,
2535
2533
  userMessageId: getTurnUserMessage(conversation, args.sessionId)?.id,
2536
- markConversationMessage,
2537
- updateConversationStats
2534
+ markConversationMessage
2538
2535
  });
2539
2536
  await failSessionRecordBestEffort2({
2540
2537
  conversationId: args.conversationId,
@@ -1,30 +1,30 @@
1
1
  import {
2
2
  resolveBaseUrl
3
- } from "./chunk-DK3GQWJK.js";
3
+ } from "./chunk-ANG7IWAI.js";
4
4
  import {
5
5
  createPluginLogger,
6
6
  getPlugins
7
- } from "./chunk-7ULXCNOZ.js";
7
+ } from "./chunk-SNBTWIQO.js";
8
8
  import {
9
9
  getDb,
10
10
  parseDestination
11
- } from "./chunk-5MFCEKR6.js";
11
+ } from "./chunk-NAINBOZQ.js";
12
12
  import {
13
13
  sleep
14
14
  } from "./chunk-EM225ITJ.js";
15
15
  import {
16
16
  acquireActiveLock,
17
17
  getStateAdapter
18
- } from "./chunk-6U44QGXL.js";
18
+ } from "./chunk-M2T7MHQJ.js";
19
19
  import {
20
20
  pluginCatalogRuntime
21
- } from "./chunk-EYD523BV.js";
21
+ } from "./chunk-NVFVM67W.js";
22
22
  import {
23
23
  fetchWithBoundedOAuthErrorBodies
24
- } from "./chunk-LMGKSDO4.js";
24
+ } from "./chunk-BJ6ISBOA.js";
25
25
  import {
26
26
  isRecord
27
- } from "./chunk-UFEU4UX6.js";
27
+ } from "./chunk-GZRWULXF.js";
28
28
 
29
29
  // src/chat/capabilities/router.ts
30
30
  var ProviderCredentialRouter = class {
@@ -4,30 +4,30 @@ import {
4
4
  isConversationScopedChannel,
5
5
  isDmChannel,
6
6
  normalizeSlackConversationId
7
- } from "./chunk-DVIJ6DP6.js";
7
+ } from "./chunk-I25V3XRN.js";
8
8
  import {
9
9
  getConversationEventStore,
10
10
  getDb
11
- } from "./chunk-5MFCEKR6.js";
11
+ } from "./chunk-NAINBOZQ.js";
12
12
  import {
13
13
  juniorConversationAnnotations,
14
14
  juniorConversationEvents,
15
15
  juniorIdentities,
16
16
  juniorUsers
17
- } from "./chunk-3H42HMA2.js";
17
+ } from "./chunk-2KLMGRRQ.js";
18
18
  import {
19
19
  SANDBOX_WORKSPACE_ROOT
20
20
  } from "./chunk-EM225ITJ.js";
21
21
  import {
22
22
  getStateAdapter
23
- } from "./chunk-6U44QGXL.js";
23
+ } from "./chunk-M2T7MHQJ.js";
24
24
  import {
25
25
  botConfig,
26
26
  completeObject,
27
27
  embedTexts,
28
28
  getSlackBotToken,
29
29
  standardModelId
30
- } from "./chunk-BBLO66XT.js";
30
+ } from "./chunk-7GVX5SOG.js";
31
31
  import {
32
32
  isActorUserId,
33
33
  parseActorUserId
@@ -42,7 +42,7 @@ import {
42
42
  logInfo,
43
43
  logWarn,
44
44
  normalizeIdentityEmail
45
- } from "./chunk-UFEU4UX6.js";
45
+ } from "./chunk-GZRWULXF.js";
46
46
 
47
47
  // src/chat/plugins/agent-hooks.ts
48
48
  import {
@@ -0,0 +1,75 @@
1
+ import {
2
+ botConfig
3
+ } from "./chunk-7GVX5SOG.js";
4
+ import {
5
+ logWarn
6
+ } from "./chunk-GZRWULXF.js";
7
+
8
+ // src/chat/services/short-title.ts
9
+ var SHORT_TITLE_MAX_LENGTH = 60;
10
+ var TITLE_PROMPTS = {
11
+ conversation: [
12
+ "Generate a concise 5-8 word Slack conversation title from the first user message below.",
13
+ "Capture the user's main request.",
14
+ "Reply with ONLY the title, with no quotes or trailing punctuation."
15
+ ],
16
+ task: [
17
+ "Generate a concise 5-8 word task title from the task instruction below.",
18
+ "Capture the task's main purpose.",
19
+ "Reply with ONLY the title, with no quotes or trailing punctuation."
20
+ ]
21
+ };
22
+ function normalizeShortTitle(value) {
23
+ return value.replace(/\s+/g, " ").trim().slice(0, SHORT_TITLE_MAX_LENGTH);
24
+ }
25
+ function fallbackShortTitle(sourceText, fallback = "Untitled") {
26
+ const firstLine = sourceText.split(/\r?\n/).map((line) => line.trim()).find((line) => line.length > 0) ?? "";
27
+ return normalizeShortTitle(firstLine) || fallback;
28
+ }
29
+ async function generateShortTitle(args) {
30
+ const sourceText = args.sourceText.trim();
31
+ if (!sourceText) return void 0;
32
+ try {
33
+ const result = await args.completeText({
34
+ modelId: botConfig.fastModelId,
35
+ temperature: 0,
36
+ messages: [
37
+ {
38
+ role: "user",
39
+ content: [
40
+ ...TITLE_PROMPTS[args.kind],
41
+ "",
42
+ args.kind === "conversation" ? `First user message: ${sourceText.slice(0, 500)}` : `Task instruction: ${sourceText.slice(0, 500)}`
43
+ ].join("\n"),
44
+ timestamp: Date.now()
45
+ }
46
+ ],
47
+ metadata: {
48
+ modelId: botConfig.fastModelId
49
+ }
50
+ });
51
+ const title = normalizeShortTitle(result.text);
52
+ return title || void 0;
53
+ } catch (error) {
54
+ logWarn(`${args.kind}.title.generation.failed`, {
55
+ "exception.message": error instanceof Error ? error.message : String(error)
56
+ });
57
+ return void 0;
58
+ }
59
+ }
60
+ async function resolveTaskTitle(args) {
61
+ const explicit = normalizeShortTitle(args.title ?? "");
62
+ if (explicit) return explicit;
63
+ return generateShortTitle({
64
+ completeText: args.completeText,
65
+ kind: "task",
66
+ sourceText: args.instruction
67
+ });
68
+ }
69
+
70
+ export {
71
+ SHORT_TITLE_MAX_LENGTH,
72
+ fallbackShortTitle,
73
+ generateShortTitle,
74
+ resolveTaskTitle
75
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-EYD523BV.js";
3
+ } from "./chunk-NVFVM67W.js";
4
4
 
5
5
  // src/chat/plugins/validation.ts
6
6
  import { isDeepStrictEqual } from "util";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-EYD523BV.js";
3
+ } from "./chunk-NVFVM67W.js";
4
4
  import {
5
5
  logWarn
6
- } from "./chunk-UFEU4UX6.js";
6
+ } from "./chunk-GZRWULXF.js";
7
7
  import {
8
8
  skillRoots
9
9
  } from "./chunk-H4HBKISO.js";
@@ -4,22 +4,22 @@ import {
4
4
  import {
5
5
  canRouteResourceEvents,
6
6
  getPlugins
7
- } from "./chunk-7ULXCNOZ.js";
7
+ } from "./chunk-SNBTWIQO.js";
8
8
  import {
9
9
  getDb
10
- } from "./chunk-5MFCEKR6.js";
10
+ } from "./chunk-NAINBOZQ.js";
11
11
  import {
12
12
  juniorEventTasks,
13
13
  juniorSchedulerRuns,
14
14
  juniorSchedulerTasks,
15
15
  juniorStats
16
- } from "./chunk-3H42HMA2.js";
16
+ } from "./chunk-2KLMGRRQ.js";
17
17
  import {
18
18
  juniorDestinations
19
19
  } from "./chunk-VFUK3X5B.js";
20
20
  import {
21
21
  logInfo
22
- } from "./chunk-UFEU4UX6.js";
22
+ } from "./chunk-GZRWULXF.js";
23
23
 
24
24
  // src/chat/event-tasks/store.ts
25
25
  import { and, asc, desc, eq, inArray, or, sql } from "drizzle-orm";
@@ -57,41 +57,55 @@ var eventTaskSchema = z.object({
57
57
  }).strict();
58
58
 
59
59
  // src/chat/event-tasks/store.ts
60
- function parseTask(value) {
61
- return eventTaskSchema.parse(value);
60
+ function eventTaskJsonPayload(task) {
61
+ const { title: _title, ...payload } = task;
62
+ return payload;
63
+ }
64
+ function parseTask(row) {
65
+ const raw = row.task && typeof row.task === "object" ? { ...row.task } : row.task;
66
+ if (raw && typeof raw === "object" && "title" in raw) {
67
+ delete raw.title;
68
+ }
69
+ const payload = eventTaskSchema.parse(raw);
70
+ const title = row.title?.trim();
71
+ return title ? { ...payload, title } : payload;
62
72
  }
63
73
  async function getEventTask(db, id) {
64
- const rows = await db.select({ task: juniorEventTasks.task }).from(juniorEventTasks).where(eq(juniorEventTasks.id, id)).limit(1);
65
- return rows[0] ? parseTask(rows[0].task) : void 0;
74
+ const rows = await db.select({ task: juniorEventTasks.task, title: juniorEventTasks.title }).from(juniorEventTasks).where(eq(juniorEventTasks.id, id)).limit(1);
75
+ return rows[0] ? parseTask(rows[0]) : void 0;
66
76
  }
67
77
  async function createEventTask(db, task) {
68
- const parsed = eventTaskSchema.parse(task);
78
+ const parsed = eventTaskSchema.parse(eventTaskJsonPayload(task));
79
+ const title = task.title?.trim() || null;
69
80
  await db.insert(juniorEventTasks).values({
70
81
  id: parsed.id,
71
82
  teamId: parsed.destination.teamId,
72
83
  namespace: parsed.trigger.namespace,
73
84
  identifier: parsed.trigger.identifier,
74
85
  createdAtMs: parsed.createdAtMs,
86
+ title,
75
87
  task: parsed
76
88
  }).onConflictDoNothing();
77
- return await getEventTask(db, parsed.id) ?? parsed;
89
+ return await getEventTask(db, parsed.id) ?? { ...parsed, ...title ? { title } : {} };
78
90
  }
79
91
  async function saveEventTask(db, task) {
80
- const parsed = eventTaskSchema.parse(task);
92
+ const parsed = eventTaskSchema.parse(eventTaskJsonPayload(task));
93
+ const title = task.title?.trim() || null;
81
94
  const rows = await db.update(juniorEventTasks).set({
82
95
  namespace: parsed.trigger.namespace,
83
96
  identifier: parsed.trigger.identifier,
97
+ title,
84
98
  task: parsed
85
- }).where(eq(juniorEventTasks.id, parsed.id)).returning({ task: juniorEventTasks.task });
86
- return rows[0] ? parseTask(rows[0].task) : void 0;
99
+ }).where(eq(juniorEventTasks.id, parsed.id)).returning({ task: juniorEventTasks.task, title: juniorEventTasks.title });
100
+ return rows[0] ? parseTask(rows[0]) : void 0;
87
101
  }
88
102
  async function deleteEventTask(db, id) {
89
- const rows = await db.delete(juniorEventTasks).where(eq(juniorEventTasks.id, id)).returning({ task: juniorEventTasks.task });
90
- return rows[0] ? parseTask(rows[0].task) : void 0;
103
+ const rows = await db.delete(juniorEventTasks).where(eq(juniorEventTasks.id, id)).returning({ task: juniorEventTasks.task, title: juniorEventTasks.title });
104
+ return rows[0] ? parseTask(rows[0]) : void 0;
91
105
  }
92
106
  async function listEventTasksForTeam(db, teamId) {
93
- const rows = await db.select({ task: juniorEventTasks.task }).from(juniorEventTasks).where(eq(juniorEventTasks.teamId, teamId)).orderBy(asc(juniorEventTasks.createdAtMs), asc(juniorEventTasks.id));
94
- return rows.map((row) => parseTask(row.task));
107
+ const rows = await db.select({ task: juniorEventTasks.task, title: juniorEventTasks.title }).from(juniorEventTasks).where(eq(juniorEventTasks.teamId, teamId)).orderBy(asc(juniorEventTasks.createdAtMs), asc(juniorEventTasks.id));
108
+ return rows.map(parseTask);
95
109
  }
96
110
  function viewerSlackIdentities(user) {
97
111
  return user.identities.filter(
@@ -114,12 +128,12 @@ async function listEventTasksCreatedBy(db, user, limit) {
114
128
  )
115
129
  );
116
130
  if (!ownership) return [];
117
- const rows = await db.select({ task: juniorEventTasks.task }).from(juniorEventTasks).where(ownership).orderBy(desc(juniorEventTasks.createdAtMs), desc(juniorEventTasks.id)).limit(limit);
118
- return rows.map((row) => parseTask(row.task));
131
+ const rows = await db.select({ task: juniorEventTasks.task, title: juniorEventTasks.title }).from(juniorEventTasks).where(ownership).orderBy(desc(juniorEventTasks.createdAtMs), desc(juniorEventTasks.id)).limit(limit);
132
+ return rows.map(parseTask);
119
133
  }
120
134
  async function listPublicEventTasksForTeams(db, teamIds, limit) {
121
135
  if (teamIds.length === 0) return [];
122
- const rows = await db.select({ task: juniorEventTasks.task }).from(juniorEventTasks).innerJoin(
136
+ const rows = await db.select({ task: juniorEventTasks.task, title: juniorEventTasks.title }).from(juniorEventTasks).innerJoin(
123
137
  juniorDestinations,
124
138
  and(
125
139
  eq(juniorDestinations.provider, "slack"),
@@ -132,17 +146,17 @@ async function listPublicEventTasksForTeams(db, teamIds, limit) {
132
146
  eq(juniorDestinations.visibility, "public")
133
147
  )
134
148
  ).orderBy(desc(juniorEventTasks.createdAtMs), desc(juniorEventTasks.id)).limit(limit);
135
- return rows.map((row) => parseTask(row.task));
149
+ return rows.map(parseTask);
136
150
  }
137
151
  async function findMatchingEventTasks(db, event, teamId) {
138
- const rows = await db.select({ task: juniorEventTasks.task }).from(juniorEventTasks).where(
152
+ const rows = await db.select({ task: juniorEventTasks.task, title: juniorEventTasks.title }).from(juniorEventTasks).where(
139
153
  and(
140
154
  eq(juniorEventTasks.teamId, teamId),
141
155
  eq(juniorEventTasks.namespace, event.namespace),
142
156
  eq(juniorEventTasks.identifier, event.identifier)
143
157
  )
144
158
  ).orderBy(asc(juniorEventTasks.createdAtMs), asc(juniorEventTasks.id));
145
- return rows.map((row) => parseTask(row.task)).filter((task) => task.trigger.events.includes(event.eventType));
159
+ return rows.map(parseTask).filter((task) => task.trigger.events.includes(event.eventType));
146
160
  }
147
161
 
148
162
  // src/stats.ts
@@ -934,12 +948,18 @@ function canFinishRun(run, startedAtMs) {
934
948
  }
935
949
  return run.status === "running" && run.startedAtMs === startedAtMs;
936
950
  }
937
- function parseStoredTask(value) {
938
- const parsed = taskRecordSchema.safeParse(parseJsonRecord(value));
939
- return parsed.success ? stripLegacyTaskFields(parsed.data) : void 0;
940
- }
941
- function stripLegacyTaskFields(task) {
951
+ function parseStoredTask(value, title) {
952
+ const record = parseJsonRecord(value);
953
+ if (!record) return void 0;
954
+ const { title: recordTitle, ...rest } = record;
955
+ const parsed = taskRecordSchema.safeParse(rest);
956
+ if (!parsed.success) return void 0;
957
+ const storedTitle = title ?? (typeof recordTitle === "string" ? recordTitle : null);
958
+ return stripLegacyTaskFields(parsed.data, storedTitle);
959
+ }
960
+ function stripLegacyTaskFields(task, title) {
942
961
  const { version: _version, status, ...current } = task;
962
+ const storedTitle = title?.trim() || void 0;
943
963
  if (status === "paused") {
944
964
  const {
945
965
  nextRunAtMs: _nextRunAtMs,
@@ -948,14 +968,20 @@ function stripLegacyTaskFields(task) {
948
968
  } = current;
949
969
  return {
950
970
  ...rest,
951
- status: "deleted"
971
+ status: "deleted",
972
+ ...storedTitle ? { title: storedTitle } : {}
952
973
  };
953
974
  }
954
975
  return {
955
976
  ...current,
956
- status
977
+ status,
978
+ ...storedTitle ? { title: storedTitle } : {}
957
979
  };
958
980
  }
981
+ function scheduledTaskJsonRecord(task) {
982
+ const { title: _title, ...record } = task;
983
+ return record;
984
+ }
959
985
  function stripLegacyRunFields(run) {
960
986
  const {
961
987
  idempotencyKey: _idempotencyKey,
@@ -984,21 +1010,19 @@ function listedScheduledTask(task) {
984
1010
  return task !== void 0 && task.status !== "deleted";
985
1011
  }
986
1012
  function requireStoredTask(task) {
987
- const parsed = parseStoredTask(task);
1013
+ const parsed = parseStoredTask(task, task.title);
988
1014
  if (!parsed) {
989
1015
  throw new Error("Scheduled task routing context is invalid.");
990
1016
  }
991
1017
  return parsed;
992
1018
  }
993
- function parseSqlTaskRecord(value, creatorIdentityId) {
1019
+ function parseSqlTaskRecord(value, creatorIdentityId, title) {
994
1020
  const record = parseJsonRecord(value);
995
- const parsed = taskRecordSchema.safeParse(
996
- record && creatorIdentityId ? { ...record, creatorIdentityId } : record
997
- );
998
- return parsed.success ? stripLegacyTaskFields(parsed.data) : void 0;
1021
+ const withIdentity = record && creatorIdentityId ? { ...record, creatorIdentityId } : record;
1022
+ return parseStoredTask(withIdentity, title);
999
1023
  }
1000
1024
  function parseSqlTaskRow(row) {
1001
- return parseSqlTaskRecord(row.record, row.creatorIdentityId);
1025
+ return parseSqlTaskRecord(row.record, row.creatorIdentityId, row.title);
1002
1026
  }
1003
1027
  function parseSqlRunRow(row) {
1004
1028
  const parsed = runRecordSchema.safeParse(parseJsonRecord(row.record));
@@ -1011,6 +1035,7 @@ async function withSqlLock(db, key, callback) {
1011
1035
  });
1012
1036
  }
1013
1037
  async function upsertSqlTask(db, task) {
1038
+ const title = task.title?.trim() || null;
1014
1039
  await db.insert(juniorSchedulerTasks).values({
1015
1040
  createdAtMs: task.createdAtMs,
1016
1041
  creatorIdentityId: task.creatorIdentityId,
@@ -1018,10 +1043,11 @@ async function upsertSqlTask(db, task) {
1018
1043
  creatorSlackUserId: task.createdBy.slackUserId,
1019
1044
  id: task.id,
1020
1045
  nextRunAtMs: task.nextRunAtMs,
1021
- record: task,
1046
+ record: scheduledTaskJsonRecord(task),
1022
1047
  runNowAtMs: task.runNowAtMs,
1023
1048
  status: task.status,
1024
- teamId: task.destination.teamId
1049
+ teamId: task.destination.teamId,
1050
+ title
1025
1051
  }).onConflictDoUpdate({
1026
1052
  target: juniorSchedulerTasks.id,
1027
1053
  set: {
@@ -1032,7 +1058,8 @@ async function upsertSqlTask(db, task) {
1032
1058
  record: sql3`excluded.record`,
1033
1059
  runNowAtMs: sql3`excluded.run_now_at_ms`,
1034
1060
  status: sql3`excluded.status`,
1035
- teamId: sql3`excluded.team_id`
1061
+ teamId: sql3`excluded.team_id`,
1062
+ title: sql3`excluded.title`
1036
1063
  }
1037
1064
  });
1038
1065
  }
@@ -1056,7 +1083,8 @@ async function upsertSqlRun(db, run) {
1056
1083
  async function getTaskFromSql(db, taskId) {
1057
1084
  const rows = await db.select({
1058
1085
  creatorIdentityId: juniorSchedulerTasks.creatorIdentityId,
1059
- record: juniorSchedulerTasks.record
1086
+ record: juniorSchedulerTasks.record,
1087
+ title: juniorSchedulerTasks.title
1060
1088
  }).from(juniorSchedulerTasks).where(eq2(juniorSchedulerTasks.id, taskId)).limit(1);
1061
1089
  return rows[0] ? parseSqlTaskRow(rows[0]) : void 0;
1062
1090
  }
@@ -1067,7 +1095,8 @@ async function getRunFromSql(db, runId) {
1067
1095
  async function listTasksFromSql(db) {
1068
1096
  const rows = await db.select({
1069
1097
  creatorIdentityId: juniorSchedulerTasks.creatorIdentityId,
1070
- record: juniorSchedulerTasks.record
1098
+ record: juniorSchedulerTasks.record,
1099
+ title: juniorSchedulerTasks.title
1071
1100
  }).from(juniorSchedulerTasks).where(notInArray(juniorSchedulerTasks.status, ["deleted", "paused"])).orderBy(
1072
1101
  asc3(juniorSchedulerTasks.createdAtMs),
1073
1102
  asc3(juniorSchedulerTasks.id)
@@ -1088,6 +1117,7 @@ async function listTasksCreatedByFromSql(db, input) {
1088
1117
  )
1089
1118
  ) : void 0;
1090
1119
  const search = query ? or2(
1120
+ sql3`strpos(lower(${juniorSchedulerTasks.title}), ${query}) > 0`,
1091
1121
  sql3`strpos(lower(${juniorSchedulerTasks.record}->'task'->>'text'), ${query}) > 0`,
1092
1122
  sql3`strpos(lower(${juniorSchedulerTasks.record}->'schedule'->>'description'), ${query}) > 0`,
1093
1123
  sql3`strpos(lower(${juniorSchedulerTasks.record}->'schedule'->>'timezone'), ${query}) > 0`,
@@ -1097,7 +1127,8 @@ async function listTasksCreatedByFromSql(db, input) {
1097
1127
  createdAtMs: juniorSchedulerTasks.createdAtMs,
1098
1128
  creatorIdentityId: juniorSchedulerTasks.creatorIdentityId,
1099
1129
  id: juniorSchedulerTasks.id,
1100
- record: juniorSchedulerTasks.record
1130
+ record: juniorSchedulerTasks.record,
1131
+ title: juniorSchedulerTasks.title
1101
1132
  }).from(juniorSchedulerTasks).where(
1102
1133
  and3(
1103
1134
  notInArray(juniorSchedulerTasks.status, ["deleted", "paused"]),
@@ -1124,7 +1155,8 @@ async function listTasksCreatedByFromSql(db, input) {
1124
1155
  async function listTasksForTeamFromSql(db, teamId) {
1125
1156
  const rows = await db.select({
1126
1157
  creatorIdentityId: juniorSchedulerTasks.creatorIdentityId,
1127
- record: juniorSchedulerTasks.record
1158
+ record: juniorSchedulerTasks.record,
1159
+ title: juniorSchedulerTasks.title
1128
1160
  }).from(juniorSchedulerTasks).where(
1129
1161
  and3(
1130
1162
  eq2(juniorSchedulerTasks.teamId, teamId),
@@ -1140,7 +1172,8 @@ async function listPublicScheduledTasksForTeams(db, teamIds, limit) {
1140
1172
  if (teamIds.length === 0) return [];
1141
1173
  const rows = await db.select({
1142
1174
  creatorIdentityId: juniorSchedulerTasks.creatorIdentityId,
1143
- record: juniorSchedulerTasks.record
1175
+ record: juniorSchedulerTasks.record,
1176
+ title: juniorSchedulerTasks.title
1144
1177
  }).from(juniorSchedulerTasks).innerJoin(
1145
1178
  juniorDestinations,
1146
1179
  and3(
@@ -1236,7 +1269,8 @@ var SqlSchedulerStore = class {
1236
1269
  async (db) => {
1237
1270
  const rows = await db.select({
1238
1271
  creatorIdentityId: juniorSchedulerTasks.creatorIdentityId,
1239
- record: juniorSchedulerTasks.record
1272
+ record: juniorSchedulerTasks.record,
1273
+ title: juniorSchedulerTasks.title
1240
1274
  }).from(juniorSchedulerTasks).where(
1241
1275
  and3(
1242
1276
  eq2(juniorSchedulerTasks.status, "active"),