@sentry/junior 0.73.0 → 0.74.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 (54) hide show
  1. package/dist/api-reference.d.ts +1 -1
  2. package/dist/app.js +258 -62
  3. package/dist/chat/app/production.d.ts +3 -0
  4. package/dist/chat/config.d.ts +3 -0
  5. package/dist/chat/conversations/configured.d.ts +5 -0
  6. package/dist/chat/conversations/sql/migrations.d.ts +11 -0
  7. package/dist/chat/conversations/sql/schema/conversations.d.ts +435 -0
  8. package/dist/chat/conversations/sql/schema/destinations.d.ts +200 -0
  9. package/dist/chat/conversations/sql/schema/identities.d.ts +214 -0
  10. package/dist/chat/conversations/sql/schema/migrations.d.ts +58 -0
  11. package/dist/chat/conversations/sql/schema/timestamps.d.ts +1 -0
  12. package/dist/chat/conversations/sql/schema.d.ts +910 -0
  13. package/dist/chat/conversations/sql/store.d.ts +52 -0
  14. package/dist/chat/conversations/state.d.ts +4 -0
  15. package/dist/chat/conversations/store.d.ts +57 -0
  16. package/dist/chat/ingress/slack-webhook.d.ts +2 -0
  17. package/dist/chat/plugins/agent-hooks.d.ts +2 -2
  18. package/dist/chat/respond.d.ts +1 -1
  19. package/dist/chat/services/mcp-auth-orchestration.d.ts +6 -5
  20. package/dist/chat/services/pending-auth.d.ts +2 -0
  21. package/dist/chat/services/plugin-auth-orchestration.d.ts +7 -6
  22. package/dist/chat/sql/db.d.ts +20 -0
  23. package/dist/chat/sql/neon.d.ts +9 -0
  24. package/dist/chat/sql/schema.d.ts +906 -0
  25. package/dist/chat/state/turn-session.d.ts +3 -0
  26. package/dist/chat/task-execution/slack-work.d.ts +2 -0
  27. package/dist/chat/task-execution/state.d.ts +209 -0
  28. package/dist/chat/task-execution/store.d.ts +30 -114
  29. package/dist/chat/task-execution/vercel-callback.d.ts +2 -0
  30. package/dist/chat/task-execution/worker.d.ts +2 -0
  31. package/dist/{chunk-ZDA2HYX5.js → chunk-2LUZA3LY.js} +3 -3
  32. package/dist/{chunk-RY6AL5C7.js → chunk-6UP2Z2RZ.js} +2 -2
  33. package/dist/{chunk-DIMX5F3T.js → chunk-F6HWCPOC.js} +1 -1
  34. package/dist/{chunk-WS2EG3GW.js → chunk-GM7HTXYC.js} +6 -0
  35. package/dist/{chunk-UZVHXZ7V.js → chunk-HYHKTFG2.js} +59 -15
  36. package/dist/chunk-JL2SLRAT.js +1970 -0
  37. package/dist/{chunk-OQSYYOLM.js → chunk-SQGMG7OD.js} +128 -114
  38. package/dist/{chunk-QUXPUKBH.js → chunk-Y7X25LFY.js} +1 -1
  39. package/dist/{chunk-UOTZ3EEQ.js → chunk-YOHFWWBV.js} +1 -1
  40. package/dist/{chunk-V4VYUY4A.js → chunk-YRDS7VKO.js} +1 -1
  41. package/dist/cli/chat.js +2 -2
  42. package/dist/cli/init.js +1 -1
  43. package/dist/cli/snapshot-warmup.js +3 -3
  44. package/dist/cli/upgrade.js +77 -7
  45. package/dist/instrumentation.js +0 -1
  46. package/dist/nitro.js +3 -3
  47. package/dist/reporting/conversations.d.ts +13 -3
  48. package/dist/reporting.d.ts +9 -2
  49. package/dist/reporting.js +101 -37
  50. package/dist/{runner-LMAM4OGD.js → runner-27NP2TEO.js} +7 -7
  51. package/dist/vercel.d.ts +6 -1
  52. package/dist/vercel.js +1 -1
  53. package/package.json +9 -4
  54. package/dist/chunk-AL5T52ZD.js +0 -1119
@@ -1,6 +1,6 @@
1
1
  import type { PluginOperationalReport } from "@sentry/junior-plugin-api";
2
- import { type ConversationFeed, type ConversationReport, type ConversationStatsReport } from "./reporting/conversations";
3
- export type { ConversationFeed, ConversationReport, ConversationReportStatus, ConversationRunReport, ConversationStatsItem, ConversationStatsReport, ConversationSummaryReport, ConversationSurface, ConversationUsage, RequesterIdentity, TranscriptMessage, TranscriptPart, TranscriptPartType, TranscriptRole, } from "./reporting/conversations";
2
+ import { type ConversationFeed, type AgentPluginConversationSummary, type ConversationReport, type ConversationStatsReport } from "./reporting/conversations";
3
+ export type { AgentPluginConversationStatus, AgentPluginConversations, AgentPluginConversationSummary, ConversationFeed, ConversationReport, ConversationReportStatus, ConversationRunReport, ConversationStatsItem, ConversationStatsReport, ConversationSummaryReport, ConversationSurface, ConversationUsage, RequesterIdentity, TranscriptMessage, TranscriptPart, TranscriptPartType, TranscriptRole, } from "./reporting/conversations";
4
4
  export interface HealthReport {
5
5
  status: "ok";
6
6
  service: string;
@@ -52,6 +52,10 @@ export interface JuniorReporting {
52
52
  getSessions(): Promise<ConversationFeed>;
53
53
  /** Read aggregate conversation stats for reporting consumers. */
54
54
  getConversationStats?(): Promise<ConversationStatsReport>;
55
+ /** Read recent conversation summaries without transcript payloads. */
56
+ listRecentConversations?(options?: {
57
+ limit?: number;
58
+ }): Promise<AgentPluginConversationSummary[]>;
55
59
  /** Read sanitized operational summaries contributed by plugins. */
56
60
  getPluginOperationalReports?(): Promise<PluginOperationalReportFeed>;
57
61
  /**
@@ -66,5 +70,8 @@ export interface JuniorReporting {
66
70
  /** Create the read-only reporting boundary used by plugins and other consumers. */
67
71
  export declare function createJuniorReporting(): JuniorReporting & {
68
72
  getConversationStats(): Promise<ConversationStatsReport>;
73
+ listRecentConversations(options?: {
74
+ limit?: number;
75
+ }): Promise<AgentPluginConversationSummary[]>;
69
76
  getPluginOperationalReports(): Promise<PluginOperationalReportFeed>;
70
77
  };
package/dist/reporting.js CHANGED
@@ -6,21 +6,19 @@ import {
6
6
  getConversationDetails,
7
7
  getConversationDetailsForIds,
8
8
  resolveSlackConversationContextFromThreadId
9
- } from "./chunk-ZDA2HYX5.js";
9
+ } from "./chunk-2LUZA3LY.js";
10
10
  import {
11
11
  buildSystemPrompt,
12
12
  getAgentPluginOperationalReports,
13
13
  getAgentTurnSessionRecord,
14
+ getConfiguredConversationStore,
14
15
  listAgentTurnSessionSummariesForConversation
15
- } from "./chunk-UZVHXZ7V.js";
16
+ } from "./chunk-HYHKTFG2.js";
16
17
  import {
17
18
  discoverSkills
18
19
  } from "./chunk-OR6NQJ5E.js";
19
- import {
20
- getConversation,
21
- listConversationsByActivity
22
- } from "./chunk-AL5T52ZD.js";
23
- import "./chunk-V4VYUY4A.js";
20
+ import "./chunk-JL2SLRAT.js";
21
+ import "./chunk-YRDS7VKO.js";
24
22
  import "./chunk-G3E7SCME.js";
25
23
  import {
26
24
  getPluginPackageContent,
@@ -29,12 +27,12 @@ import {
29
27
  import {
30
28
  homeDir
31
29
  } from "./chunk-KVZL5NZS.js";
32
- import "./chunk-DIMX5F3T.js";
30
+ import "./chunk-F6HWCPOC.js";
33
31
  import {
34
32
  canExposeConversationPayload,
35
33
  parseSlackThreadId,
36
34
  resolveConversationPrivacy
37
- } from "./chunk-WS2EG3GW.js";
35
+ } from "./chunk-GM7HTXYC.js";
38
36
  import "./chunk-CYUI7JU5.js";
39
37
  import {
40
38
  isRecord
@@ -53,6 +51,9 @@ var PRIVATE_CONVERSATION_LABEL = "Private Conversation";
53
51
  var CONVERSATION_FEED_LIMIT = 50;
54
52
  var CONVERSATION_STATS_LIMIT = 5e3;
55
53
  var RECENT_CONVERSATION_STATS_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
54
+ function conversationStore(options = {}) {
55
+ return options.conversationStore ?? getConfiguredConversationStore();
56
+ }
56
57
  function statusFromCheckpoint(summary, nowMs = Date.now()) {
57
58
  const state = summary.state;
58
59
  if (state === "running" && nowMs - summary.lastProgressAtMs > HUNG_TURN_PROGRESS_MS) {
@@ -147,10 +148,10 @@ function sessionReportFromSummary(summary, nowMs = Date.now(), details) {
147
148
  };
148
149
  }
149
150
  function statusFromConversation(conversation, fallback, nowMs) {
151
+ if (fallback) {
152
+ return fallback;
153
+ }
150
154
  if (conversation.execution.status === "idle") {
151
- if (fallback === "failed" || fallback === "superseded") {
152
- return fallback;
153
- }
154
155
  return "completed";
155
156
  }
156
157
  const updatedAtMs = conversation.execution.updatedAtMs ?? conversation.updatedAtMs;
@@ -174,13 +175,30 @@ function titleFromConversation(args) {
174
175
  channelName: effectiveChannelName
175
176
  }) ?? surfaceFallbackLabel(args.surface);
176
177
  }
178
+ function channelNameFromConversation(conversation, details) {
179
+ const effectiveChannelName = details?.channelName ?? conversation.channelName;
180
+ const slackThread = parseSlackThreadId(conversation.conversationId);
181
+ if (!effectiveChannelName && !slackThread) {
182
+ return void 0;
183
+ }
184
+ const slackConversation = resolveSlackConversationContextFromThreadId({
185
+ threadId: conversation.conversationId,
186
+ channelName: effectiveChannelName
187
+ });
188
+ if (resolveConversationPrivacy({
189
+ conversationId: conversation.conversationId
190
+ }) !== "public") {
191
+ return formatSlackConversationRedactedLabel(slackConversation) ?? (slackConversation ? void 0 : PRIVATE_CONVERSATION_LABEL);
192
+ }
193
+ return effectiveChannelName;
194
+ }
177
195
  function applyConversationIndexMetadata(args) {
178
196
  const surface = args.details?.originSurface ?? (args.conversation.source ? surfaceFromSource(
179
197
  args.conversation.source,
180
198
  args.conversation.conversationId
181
199
  ) : args.report.surface);
182
200
  const slackThread = parseSlackThreadId(args.conversation.conversationId);
183
- const effectiveChannelName = args.details?.channelName ?? args.conversation.channelName ?? args.report.channelName;
201
+ const effectiveChannelName = channelNameFromConversation(args.conversation, args.details) ?? args.report.channelName;
184
202
  const requesterIdentity = requesterIdentityReport(args.details?.originRequester) ?? args.report.requesterIdentity ?? requesterIdentityReport(args.conversation.requester);
185
203
  const status = statusFromConversation(
186
204
  args.conversation,
@@ -191,10 +209,6 @@ function applyConversationIndexMetadata(args) {
191
209
  reportTime(args.report.lastSeenAt) ?? 0,
192
210
  args.conversation.lastActivityAtMs
193
211
  );
194
- const lastProgressAtMs = Math.max(
195
- reportTime(args.report.lastProgressAt) ?? 0,
196
- args.conversation.execution.updatedAtMs ?? args.conversation.updatedAtMs
197
- );
198
212
  return {
199
213
  ...args.report,
200
214
  displayTitle: titleFromConversation({
@@ -204,7 +218,6 @@ function applyConversationIndexMetadata(args) {
204
218
  }),
205
219
  status,
206
220
  lastSeenAt: new Date(lastSeenAtMs).toISOString(),
207
- lastProgressAt: new Date(lastProgressAtMs).toISOString(),
208
221
  surface,
209
222
  ...requesterIdentity ? { requesterIdentity } : {},
210
223
  ...slackThread ? { channel: slackThread.channelId } : {},
@@ -220,6 +233,7 @@ function sessionReportFromConversation(conversation, nowMs, details) {
220
233
  details?.originRequester ?? conversation.requester
221
234
  );
222
235
  const slackThread = parseSlackThreadId(conversation.conversationId);
236
+ const channelName = channelNameFromConversation(conversation, details);
223
237
  return {
224
238
  conversationId: conversation.conversationId,
225
239
  cumulativeDurationMs: 0,
@@ -234,7 +248,7 @@ function sessionReportFromConversation(conversation, nowMs, details) {
234
248
  surface,
235
249
  ...requesterIdentity ? { requesterIdentity } : {},
236
250
  ...slackThread ? { channel: slackThread.channelId } : {},
237
- ...details?.channelName ?? conversation.channelName ? { channelName: details?.channelName ?? conversation.channelName } : {},
251
+ ...channelName ? { channelName } : {},
238
252
  ...sentryConversationUrl ? { sentryConversationUrl } : {}
239
253
  };
240
254
  }
@@ -729,9 +743,10 @@ async function reportsFromConversations(args) {
729
743
  }
730
744
  return reports;
731
745
  }
732
- async function readConversationFeed() {
746
+ async function readConversationFeed(options = {}) {
747
+ const store = conversationStore(options);
733
748
  const nowMs = Date.now();
734
- const conversations = await listConversationsByActivity({
749
+ const conversations = await store.listByActivity({
735
750
  limit: CONVERSATION_FEED_LIMIT
736
751
  });
737
752
  const detailsByConversationId = await getConversationDetailsForIds(
@@ -758,10 +773,11 @@ async function readConversationFeed() {
758
773
  )
759
774
  };
760
775
  }
761
- async function readConversationStatsReport() {
776
+ async function readConversationStatsReport(options = {}) {
777
+ const store = conversationStore(options);
762
778
  const nowMs = Date.now();
763
779
  const generatedAt = new Date(nowMs).toISOString();
764
- const conversations = await listConversationsByActivity({
780
+ const conversations = await store.listByActivity({
765
781
  limit: CONVERSATION_STATS_LIMIT + 1
766
782
  });
767
783
  const truncated = conversations.length > CONVERSATION_STATS_LIMIT;
@@ -792,12 +808,53 @@ async function readConversationStatsReport() {
792
808
  truncated
793
809
  });
794
810
  }
795
- async function readConversationReport(conversationId) {
811
+ async function listRecentConversationSummaries(options = {}) {
812
+ const store = conversationStore(options);
813
+ const nowMs = Date.now();
814
+ const limit = Math.max(0, Math.min(100, Math.floor(options.limit ?? 25)));
815
+ const conversations = await store.listByActivity({
816
+ limit
817
+ });
818
+ const detailsByConversationId = await getConversationDetailsForIds(
819
+ conversations.map((conversation) => conversation.conversationId)
820
+ );
821
+ const reportsByConversation = await reportsFromConversations({
822
+ conversations,
823
+ detailsByConversationId,
824
+ nowMs
825
+ });
826
+ return conversations.map((conversation) => {
827
+ const details = detailsByConversationId.get(conversation.conversationId);
828
+ const surface = surfaceFromSource(
829
+ conversation.source,
830
+ conversation.conversationId
831
+ );
832
+ const channelName = channelNameFromConversation(conversation, details);
833
+ const report = newestRun(
834
+ reportsByConversation.get(conversation.conversationId) ?? [
835
+ sessionReportFromConversation(conversation, nowMs, details)
836
+ ]
837
+ );
838
+ return {
839
+ conversationId: conversation.conversationId,
840
+ displayTitle: titleFromConversation({ conversation, details, surface }),
841
+ lastActivityAt: new Date(conversation.lastActivityAtMs).toISOString(),
842
+ lastUpdatedAt: new Date(
843
+ conversation.execution.updatedAtMs ?? conversation.updatedAtMs
844
+ ).toISOString(),
845
+ status: report.status,
846
+ ...channelName ? { channelName } : {},
847
+ ...conversation.source ? { source: conversation.source } : {}
848
+ };
849
+ });
850
+ }
851
+ async function readConversationReport(conversationId, options = {}) {
852
+ const store = conversationStore(options);
796
853
  const nowMs = Date.now();
797
854
  const [rawSummaries, details, conversation] = await Promise.all([
798
855
  listAgentTurnSessionSummariesForConversation(conversationId),
799
856
  getConversationDetails(conversationId),
800
- getConversation({ conversationId })
857
+ store.get({ conversationId })
801
858
  ]);
802
859
  const summaries = rawSummaries.sort(
803
860
  (left, right) => left.startedAtMs - right.startedAtMs || left.updatedAtMs - right.updatedAtMs || left.sessionId.localeCompare(right.sessionId)
@@ -893,15 +950,12 @@ async function readPlugins() {
893
950
  name: plugin.manifest.name
894
951
  }));
895
952
  }
896
- async function readPluginOperationalReports() {
897
- const nowMs = Date.now();
898
- return {
899
- source: "plugins",
900
- generatedAt: new Date(nowMs).toISOString(),
901
- reports: await getAgentPluginOperationalReports(nowMs)
902
- };
903
- }
904
953
  function createJuniorReporting() {
954
+ const conversationStore2 = getConfiguredConversationStore();
955
+ const listRecent = (listOptions) => listRecentConversationSummaries({
956
+ ...listOptions,
957
+ conversationStore: conversationStore2
958
+ });
905
959
  return {
906
960
  getHealth: readHealth,
907
961
  async getRuntimeInfo() {
@@ -920,10 +974,20 @@ function createJuniorReporting() {
920
974
  },
921
975
  getPlugins: readPlugins,
922
976
  getSkills: readSkills,
923
- getSessions: readConversationFeed,
924
- getConversationStats: readConversationStatsReport,
925
- getPluginOperationalReports: readPluginOperationalReports,
926
- getConversation: readConversationReport
977
+ getSessions: () => readConversationFeed({ conversationStore: conversationStore2 }),
978
+ getConversationStats: () => readConversationStatsReport({ conversationStore: conversationStore2 }),
979
+ listRecentConversations: listRecent,
980
+ getPluginOperationalReports: async () => {
981
+ const nowMs = Date.now();
982
+ return {
983
+ source: "plugins",
984
+ generatedAt: new Date(nowMs).toISOString(),
985
+ reports: await getAgentPluginOperationalReports(nowMs, {
986
+ listRecent
987
+ })
988
+ };
989
+ },
990
+ getConversation: (conversationId) => readConversationReport(conversationId, { conversationStore: conversationStore2 })
927
991
  };
928
992
  }
929
993
  export {
@@ -12,26 +12,26 @@ import {
12
12
  startActiveTurn,
13
13
  updateConversationStats,
14
14
  upsertConversationMessage
15
- } from "./chunk-OQSYYOLM.js";
15
+ } from "./chunk-SQGMG7OD.js";
16
16
  import {
17
17
  commitMessages,
18
18
  loadProjection
19
- } from "./chunk-UZVHXZ7V.js";
19
+ } from "./chunk-HYHKTFG2.js";
20
20
  import "./chunk-OR6NQJ5E.js";
21
21
  import {
22
22
  coerceThreadConversationState
23
23
  } from "./chunk-M4FLLXXD.js";
24
- import "./chunk-AL5T52ZD.js";
25
- import "./chunk-V4VYUY4A.js";
26
- import "./chunk-RY6AL5C7.js";
24
+ import "./chunk-JL2SLRAT.js";
25
+ import "./chunk-YRDS7VKO.js";
26
+ import "./chunk-6UP2Z2RZ.js";
27
27
  import "./chunk-G3E7SCME.js";
28
28
  import "./chunk-7Q5YOUUT.js";
29
29
  import "./chunk-KVZL5NZS.js";
30
- import "./chunk-DIMX5F3T.js";
30
+ import "./chunk-F6HWCPOC.js";
31
31
  import {
32
32
  stripRuntimeTurnContext,
33
33
  trimTrailingAssistantMessages
34
- } from "./chunk-WS2EG3GW.js";
34
+ } from "./chunk-GM7HTXYC.js";
35
35
  import "./chunk-CYUI7JU5.js";
36
36
  import "./chunk-3BYAPS6B.js";
37
37
  import "./chunk-SJHUF3DP.js";
package/dist/vercel.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  export interface JuniorVercelConfigOptions {
2
+ /** Override the Vercel build command, or pass null to omit it. */
2
3
  buildCommand?: string | null;
3
4
  }
4
- /** Return the root Vercel project config for scaffolded Junior apps. */
5
+ /** Return the root Vercel project config for scaffolded Junior apps.
6
+ *
7
+ * New apps run `junior upgrade` before `pnpm build`; older installs without
8
+ * Junior SQL configured can override `buildCommand` to keep their prior build.
9
+ */
5
10
  export declare function juniorVercelConfig(options?: JuniorVercelConfigOptions): Record<string, unknown>;
package/dist/vercel.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  juniorVercelConfig
3
- } from "./chunk-QUXPUKBH.js";
3
+ } from "./chunk-Y7X25LFY.js";
4
4
  import "./chunk-2KG3PWR4.js";
5
5
  export {
6
6
  juniorVercelConfig
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior",
3
- "version": "0.73.0",
3
+ "version": "0.74.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -50,6 +50,7 @@
50
50
  "@earendil-works/pi-agent-core": "0.74.2",
51
51
  "@earendil-works/pi-ai": "0.74.2",
52
52
  "@modelcontextprotocol/sdk": "1.29.0",
53
+ "@neondatabase/serverless": "^1.1.0",
53
54
  "@sinclair/typebox": "^0.34.49",
54
55
  "@slack/web-api": "^7.16.0",
55
56
  "@sentry/node": "10.53.1",
@@ -59,17 +60,20 @@
59
60
  "ai": "^6.0.190",
60
61
  "bash-tool": "^1.3.16",
61
62
  "chat": "4.29.0",
63
+ "drizzle-orm": "^0.45.2",
62
64
  "hono": "^4.12.22",
63
65
  "jose": "^6.2.3",
64
66
  "just-bash": "3.0.1",
65
67
  "node-html-markdown": "^2.0.0",
66
68
  "yaml": "^2.9.0",
67
69
  "zod": "^4.4.3",
68
- "@sentry/junior-plugin-api": "0.73.0"
70
+ "@sentry/junior-plugin-api": "0.74.0"
69
71
  },
70
72
  "devDependencies": {
73
+ "@emnapi/core": "^1.10.0",
74
+ "@emnapi/runtime": "^1.10.0",
71
75
  "@types/node": "^25.9.1",
72
- "@vitest/coverage-v8": "^4.1.7",
76
+ "@vitest/coverage-v8": "4.1.7",
73
77
  "dependency-cruiser": "^17.4.0",
74
78
  "msw": "^2.14.6",
75
79
  "nitro": "3.0.260522-beta",
@@ -78,7 +82,8 @@
78
82
  "typescript": "^6.0.3",
79
83
  "vercel": "^54.4.0",
80
84
  "vitest": "^4.1.7",
81
- "@sentry/junior-scheduler": "0.73.0"
85
+ "@sentry/junior-test-fixtures": "0.72.0",
86
+ "@sentry/junior-scheduler": "0.74.0"
82
87
  },
83
88
  "scripts": {
84
89
  "build": "tsup && tsc -p tsconfig.build.json --emitDeclarationOnly",