@sentry/junior 0.68.0 → 0.70.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.
- package/dist/app.js +1779 -746
- package/dist/build/virtual-config.d.ts +2 -2
- package/dist/chat/agent-dispatch/heartbeat.d.ts +2 -2
- package/dist/chat/agent-dispatch/store.d.ts +4 -1
- package/dist/chat/agent-dispatch/types.d.ts +2 -4
- package/dist/chat/agent-dispatch/validation.d.ts +3 -2
- package/dist/chat/credentials/context.d.ts +49 -24
- package/dist/chat/credentials/user-token-store.d.ts +6 -0
- package/dist/chat/destination.d.ts +12 -0
- package/dist/chat/ingress/message-router.d.ts +1 -1
- package/dist/chat/mcp/auth-store.d.ts +2 -0
- package/dist/chat/mcp/oauth.d.ts +2 -0
- package/dist/chat/oauth-flow.d.ts +7 -0
- package/dist/chat/plugins/agent-hooks.d.ts +9 -9
- package/dist/chat/plugins/auth/auth-token-placeholder.d.ts +2 -2
- package/dist/chat/plugins/auth/oauth-request.d.ts +3 -1
- package/dist/chat/plugins/credential-hooks.d.ts +53 -0
- package/dist/chat/plugins/logging.d.ts +1 -1
- package/dist/chat/plugins/state.d.ts +1 -1
- package/dist/chat/plugins/types.d.ts +19 -23
- package/dist/chat/respond.d.ts +2 -0
- package/dist/chat/runtime/reply-executor.d.ts +3 -1
- package/dist/chat/runtime/slack-runtime.d.ts +8 -3
- package/dist/chat/sandbox/egress-credentials.d.ts +34 -0
- package/dist/chat/sandbox/egress-schemas.d.ts +105 -0
- package/dist/chat/sandbox/egress-session.d.ts +17 -17
- package/dist/chat/sandbox/sandbox.d.ts +3 -0
- package/dist/chat/sandbox/session.d.ts +1 -0
- package/dist/chat/services/mcp-auth-orchestration.d.ts +2 -0
- package/dist/chat/services/pending-auth.d.ts +2 -0
- package/dist/chat/services/plugin-auth-orchestration.d.ts +2 -0
- package/dist/chat/services/provider-retry.d.ts +13 -4
- package/dist/chat/services/timeout-resume.d.ts +2 -0
- package/dist/chat/services/turn-session-record.d.ts +6 -0
- package/dist/chat/slack/attachment-fetchers.d.ts +11 -0
- package/dist/chat/state/conversation-details.d.ts +46 -0
- package/dist/chat/state/conversation.d.ts +1 -0
- package/dist/chat/state/turn-session.d.ts +4 -3
- package/dist/chat/task-execution/queue.d.ts +2 -0
- package/dist/chat/task-execution/store.d.ts +5 -0
- package/dist/chat/task-execution/vercel-callback.d.ts +4 -0
- package/dist/chat/task-execution/vercel-queue.d.ts +2 -0
- package/dist/chat/task-execution/worker.d.ts +4 -2
- package/dist/chat/tools/slack/context.d.ts +3 -0
- package/dist/chat/tools/types.d.ts +21 -2
- package/dist/chunk-76YMBKW7.js +326 -0
- package/dist/{chunk-PIVOJIUD.js → chunk-B5HKWWQB.js} +9 -5
- package/dist/chunk-BBXYXOJW.js +1858 -0
- package/dist/{chunk-V47RLIO2.js → chunk-GT67ZWZQ.js} +4 -4
- package/dist/{chunk-UQQSW7QB.js → chunk-HOGQL2H6.js} +197 -343
- package/dist/{chunk-75UZ4JLC.js → chunk-IGLNC5H6.js} +21 -9
- package/dist/{chunk-EBVQXCD2.js → chunk-JS4HURDT.js} +362 -280
- package/dist/chunk-R62YWUNO.js +264 -0
- package/dist/{chunk-OIIXZOOC.js → chunk-UXG6TU2U.js} +311 -2015
- package/dist/cli/check.js +4 -4
- package/dist/cli/init.js +18 -1
- package/dist/cli/snapshot-warmup.js +5 -4
- package/dist/nitro.d.ts +1 -1
- package/dist/nitro.js +21 -19
- package/dist/plugins.d.ts +2 -2
- package/dist/reporting.d.ts +8 -4
- package/dist/reporting.js +72 -29
- package/package.json +6 -4
- package/dist/chat/plugins/auth/github-app-broker.d.ts +0 -4
- package/dist/chat/plugins/github-permissions.d.ts +0 -11
- package/dist/chat/queue/thread-message-dispatcher.d.ts +0 -33
- package/dist/chunk-KVZL5NZS.js +0 -519
package/dist/cli/check.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseSkillFile
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-GT67ZWZQ.js";
|
|
4
4
|
import {
|
|
5
5
|
parseInlinePluginManifest,
|
|
6
6
|
parsePluginManifest
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-Z3YD6NHK.js";
|
|
7
|
+
} from "../chunk-UXG6TU2U.js";
|
|
9
8
|
import {
|
|
10
9
|
JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
|
|
11
10
|
JUNIOR_HEARTBEAT_ROUTE,
|
|
12
11
|
LEGACY_JUNIOR_CONVERSATION_WORK_FUNCTION
|
|
13
12
|
} from "../chunk-6YY4Q3D4.js";
|
|
14
|
-
import "../chunk-
|
|
13
|
+
import "../chunk-BBXYXOJW.js";
|
|
14
|
+
import "../chunk-Z3YD6NHK.js";
|
|
15
15
|
import "../chunk-2KG3PWR4.js";
|
|
16
16
|
|
|
17
17
|
// src/cli/check.ts
|
package/dist/cli/init.js
CHANGED
|
@@ -31,6 +31,17 @@ export const POST = (request: Request) => app.fetch(request);
|
|
|
31
31
|
`
|
|
32
32
|
);
|
|
33
33
|
}
|
|
34
|
+
function writePluginsFile(targetDir) {
|
|
35
|
+
fs.writeFileSync(
|
|
36
|
+
path.join(targetDir, "plugins.ts"),
|
|
37
|
+
`import { defineJuniorPlugins } from "@sentry/junior";
|
|
38
|
+
|
|
39
|
+
export const plugins = defineJuniorPlugins([
|
|
40
|
+
"@sentry/junior-maintenance",
|
|
41
|
+
]);
|
|
42
|
+
`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
34
45
|
function writeNitroConfig(targetDir) {
|
|
35
46
|
fs.writeFileSync(
|
|
36
47
|
path.join(targetDir, "nitro.config.ts"),
|
|
@@ -39,7 +50,11 @@ import { juniorNitro } from "@sentry/junior/nitro";
|
|
|
39
50
|
|
|
40
51
|
export default defineConfig({
|
|
41
52
|
preset: "vercel",
|
|
42
|
-
modules: [
|
|
53
|
+
modules: [
|
|
54
|
+
juniorNitro({
|
|
55
|
+
plugins: "./plugins",
|
|
56
|
+
}),
|
|
57
|
+
],
|
|
43
58
|
routes: {
|
|
44
59
|
"/**": { handler: "./server.ts" },
|
|
45
60
|
},
|
|
@@ -129,6 +144,7 @@ async function runInit(dir, log = console.log) {
|
|
|
129
144
|
},
|
|
130
145
|
dependencies: {
|
|
131
146
|
"@sentry/junior": "latest",
|
|
147
|
+
"@sentry/junior-maintenance": "latest",
|
|
132
148
|
hono: "^4.12.0"
|
|
133
149
|
},
|
|
134
150
|
devDependencies: {
|
|
@@ -199,6 +215,7 @@ SENTRY_ORG_SLUG=
|
|
|
199
215
|
);
|
|
200
216
|
writeServerEntry(target);
|
|
201
217
|
writeQueueConsumerEntry(target);
|
|
218
|
+
writePluginsFile(target);
|
|
202
219
|
writeNitroConfig(target);
|
|
203
220
|
writeViteConfig(target);
|
|
204
221
|
writeVercelJson(target);
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveRuntimeDependencySnapshot
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-B5HKWWQB.js";
|
|
4
4
|
import {
|
|
5
5
|
disconnectStateAdapter
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-R62YWUNO.js";
|
|
7
7
|
import {
|
|
8
8
|
getPluginProviders,
|
|
9
9
|
getPluginRuntimeDependencies,
|
|
10
10
|
getPluginRuntimePostinstall
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-UXG6TU2U.js";
|
|
12
|
+
import "../chunk-JS4HURDT.js";
|
|
13
|
+
import "../chunk-BBXYXOJW.js";
|
|
12
14
|
import "../chunk-Z3YD6NHK.js";
|
|
13
|
-
import "../chunk-KVZL5NZS.js";
|
|
14
15
|
import "../chunk-2KG3PWR4.js";
|
|
15
16
|
|
|
16
17
|
// src/cli/snapshot-warmup.ts
|
package/dist/nitro.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export interface JuniorNitroOptions {
|
|
|
11
11
|
maxDuration?: number;
|
|
12
12
|
/** Vercel Queue topic for durable conversation work. Must match the runtime queue producer topic. */
|
|
13
13
|
conversationWorkQueueTopic?: string;
|
|
14
|
-
/** Plugin catalog set or runtime-safe plugin module. Direct sets must not include
|
|
14
|
+
/** Plugin catalog set or runtime-safe plugin module. Direct sets must not include runtime hooks. */
|
|
15
15
|
plugins?: JuniorNitroPluginSource;
|
|
16
16
|
/**
|
|
17
17
|
* Extra file patterns to copy into the server output for files that the
|
package/dist/nitro.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
|
-
DEFAULT_CONVERSATION_WORK_QUEUE_TOPIC,
|
|
3
2
|
pluginCatalogConfigFromPluginSet,
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
pluginHookRegistrationsFromPluginSet,
|
|
4
|
+
resolveConversationWorkQueueTopic
|
|
5
|
+
} from "./chunk-IGLNC5H6.js";
|
|
6
|
+
import "./chunk-76YMBKW7.js";
|
|
6
7
|
import {
|
|
7
8
|
JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
|
|
8
9
|
JUNIOR_HEARTBEAT_CRON_SCHEDULE,
|
|
9
10
|
JUNIOR_HEARTBEAT_ROUTE
|
|
10
11
|
} from "./chunk-6YY4Q3D4.js";
|
|
12
|
+
import "./chunk-JS4HURDT.js";
|
|
11
13
|
import {
|
|
12
14
|
discoverInstalledPluginPackageContent,
|
|
13
15
|
isValidPackageName,
|
|
14
16
|
resolvePackageDir
|
|
15
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-BBXYXOJW.js";
|
|
18
|
+
import "./chunk-Z3YD6NHK.js";
|
|
16
19
|
import "./chunk-2KG3PWR4.js";
|
|
17
20
|
|
|
18
21
|
// src/nitro.ts
|
|
@@ -192,7 +195,7 @@ function renderVirtualConfig(options) {
|
|
|
192
195
|
"export const pluginSet = juniorRuntimePluginSet;"
|
|
193
196
|
] : ["export const pluginSet = undefined;"],
|
|
194
197
|
`export const plugins = ${JSON.stringify(options.plugins ?? { packages: [] })};`,
|
|
195
|
-
`export const
|
|
198
|
+
`export const pluginHookRegistrations = ${JSON.stringify(options.pluginHookRegistrations ?? [])};`
|
|
196
199
|
];
|
|
197
200
|
return lines.join("\n");
|
|
198
201
|
}
|
|
@@ -205,7 +208,7 @@ function injectVirtualConfig(nitro, options = {}) {
|
|
|
205
208
|
return renderVirtualConfig({
|
|
206
209
|
pluginModule: options.pluginModule,
|
|
207
210
|
plugins: pluginCatalogConfigFromPluginSet(pluginSet),
|
|
208
|
-
|
|
211
|
+
pluginHookRegistrations: pluginHookRegistrationsFromPluginSet(
|
|
209
212
|
pluginSet
|
|
210
213
|
).map((plugin) => plugin.name)
|
|
211
214
|
});
|
|
@@ -300,19 +303,16 @@ async function loadPluginSetFromModule(moduleRef) {
|
|
|
300
303
|
);
|
|
301
304
|
}
|
|
302
305
|
function assertSerializableDirectPluginSet(pluginSet) {
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
)
|
|
306
|
-
if (
|
|
306
|
+
const pluginHookNames = pluginHookRegistrationsFromPluginSet(pluginSet).map(
|
|
307
|
+
(plugin) => plugin.name
|
|
308
|
+
);
|
|
309
|
+
if (pluginHookNames.length === 0) {
|
|
307
310
|
return;
|
|
308
311
|
}
|
|
309
312
|
throw new Error(
|
|
310
|
-
`juniorNitro({ plugins }) cannot receive a direct defineJuniorPlugins(...) set with
|
|
313
|
+
`juniorNitro({ plugins }) cannot receive a direct defineJuniorPlugins(...) set with runtime hook registration(s): ${pluginHookNames.join(", ")}. Export the set from a runtime-safe plugin module and pass juniorNitro({ plugins: "./plugins" }) so createApp() can import the same hooks at runtime.`
|
|
311
314
|
);
|
|
312
315
|
}
|
|
313
|
-
function resolveConversationWorkQueueTopic(options) {
|
|
314
|
-
return options.conversationWorkQueueTopic?.trim() || process.env.JUNIOR_CONVERSATION_WORK_QUEUE_TOPIC?.trim() || DEFAULT_CONVERSATION_WORK_QUEUE_TOPIC;
|
|
315
|
-
}
|
|
316
316
|
function bundleOpenTelemetryLoaderHooks(nitro) {
|
|
317
317
|
const existing = Array.isArray(nitro.options.noExternals) ? nitro.options.noExternals : [];
|
|
318
318
|
const additions = ["import-in-the-middle", "require-in-the-middle"].filter(
|
|
@@ -324,7 +324,9 @@ function bundleOpenTelemetryLoaderHooks(nitro) {
|
|
|
324
324
|
}
|
|
325
325
|
function configureVercelDeployment(nitro, options) {
|
|
326
326
|
const defaultMaxDuration = options.maxDuration ?? DEFAULT_FUNCTION_MAX_DURATION_SECONDS;
|
|
327
|
-
const queueTopic = resolveConversationWorkQueueTopic(
|
|
327
|
+
const queueTopic = resolveConversationWorkQueueTopic({
|
|
328
|
+
topic: options.conversationWorkQueueTopic
|
|
329
|
+
});
|
|
328
330
|
nitro.options.vercel ??= {};
|
|
329
331
|
nitro.options.vercel.config ??= { version: 3 };
|
|
330
332
|
nitro.options.vercel.config.crons ??= [];
|
|
@@ -379,16 +381,16 @@ function juniorNitro(options = {}) {
|
|
|
379
381
|
return pluginSetPromise;
|
|
380
382
|
};
|
|
381
383
|
const pluginCatalogConfig = pluginCatalogConfigFromPluginSet(directPluginSet);
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
);
|
|
384
|
+
const pluginHookRegistrations = pluginHookRegistrationsFromPluginSet(
|
|
385
|
+
directPluginSet
|
|
386
|
+
).map((plugin) => plugin.name);
|
|
385
387
|
injectVirtualConfig(nitro, {
|
|
386
388
|
...pluginModule ? {
|
|
387
389
|
loadPluginSet: loadConfiguredPluginSet,
|
|
388
390
|
pluginModule: pluginModule.runtimeModule
|
|
389
391
|
} : {},
|
|
390
392
|
plugins: pluginCatalogConfig,
|
|
391
|
-
|
|
393
|
+
pluginHookRegistrations
|
|
392
394
|
});
|
|
393
395
|
const copyBuildContent = async () => {
|
|
394
396
|
const pluginSet = await loadConfiguredPluginSet();
|
package/dist/plugins.d.ts
CHANGED
|
@@ -18,5 +18,5 @@ export interface JuniorPluginSet {
|
|
|
18
18
|
export declare function defineJuniorPlugins(inputs: JuniorPluginInput[], options?: JuniorPluginSetOptions): JuniorPluginSet;
|
|
19
19
|
/** Build the manifest catalog config implied by one plugin set. */
|
|
20
20
|
export declare function pluginCatalogConfigFromPluginSet(pluginSet: JuniorPluginSet | undefined): PluginCatalogConfig | undefined;
|
|
21
|
-
/** Return registrations that expose
|
|
22
|
-
export declare function
|
|
21
|
+
/** Return registrations that expose in-process runtime hooks. */
|
|
22
|
+
export declare function pluginHookRegistrationsFromPluginSet(pluginSet: JuniorPluginSet | undefined): JuniorPluginRegistration[];
|
package/dist/reporting.d.ts
CHANGED
|
@@ -37,7 +37,10 @@ export interface DashboardRequesterIdentity {
|
|
|
37
37
|
slackUserName?: string;
|
|
38
38
|
}
|
|
39
39
|
export interface DashboardSessionReport {
|
|
40
|
-
|
|
40
|
+
/** Always-populated display title. LLM-generated title when available, otherwise the
|
|
41
|
+
* Slack channel/conversation location label or a generic fallback. Privacy redaction
|
|
42
|
+
* wins over everything else for non-public conversations. */
|
|
43
|
+
displayTitle: string;
|
|
41
44
|
cumulativeDurationMs: number;
|
|
42
45
|
cumulativeUsage?: DashboardTurnUsage;
|
|
43
46
|
conversationId: string;
|
|
@@ -48,7 +51,6 @@ export interface DashboardSessionReport {
|
|
|
48
51
|
lastProgressAt: string;
|
|
49
52
|
completedAt?: string;
|
|
50
53
|
surface: DashboardSurface;
|
|
51
|
-
title: string;
|
|
52
54
|
requesterIdentity?: DashboardRequesterIdentity;
|
|
53
55
|
channel?: string;
|
|
54
56
|
channelName?: string;
|
|
@@ -93,6 +95,8 @@ export interface DashboardTurnReport extends DashboardSessionReport {
|
|
|
93
95
|
}
|
|
94
96
|
export interface DashboardConversationReport {
|
|
95
97
|
conversationId: string;
|
|
98
|
+
/** Always-populated display title, computed the same way as DashboardSessionReport.displayTitle. */
|
|
99
|
+
displayTitle: string;
|
|
96
100
|
generatedAt: string;
|
|
97
101
|
turns: DashboardTurnReport[];
|
|
98
102
|
}
|
|
@@ -133,7 +137,7 @@ export type { PluginOperationalReport } from "@sentry/junior-plugin-api";
|
|
|
133
137
|
export interface PluginOperationalReportFeed {
|
|
134
138
|
generatedAt: string;
|
|
135
139
|
reports: PluginOperationalReport[];
|
|
136
|
-
source: "
|
|
140
|
+
source: "plugins";
|
|
137
141
|
}
|
|
138
142
|
export interface JuniorReporting {
|
|
139
143
|
/** Read the public runtime health snapshot without exposing discovery data. */
|
|
@@ -153,7 +157,7 @@ export interface JuniorReporting {
|
|
|
153
157
|
getSessions(): Promise<DashboardSessionFeed>;
|
|
154
158
|
/** Read aggregate conversation stats for authenticated dashboard views. */
|
|
155
159
|
getConversationStats?(): Promise<DashboardConversationStatsReport>;
|
|
156
|
-
/** Read sanitized operational summaries contributed by
|
|
160
|
+
/** Read sanitized operational summaries contributed by plugins. */
|
|
157
161
|
getPluginOperationalReports?(): Promise<PluginOperationalReportFeed>;
|
|
158
162
|
/**
|
|
159
163
|
* Read one conversation transcript for the dashboard.
|
package/dist/reporting.js
CHANGED
|
@@ -6,27 +6,31 @@ import {
|
|
|
6
6
|
formatSlackConversationRedactedLabel,
|
|
7
7
|
getAgentPluginOperationalReports,
|
|
8
8
|
getAgentTurnSessionRecord,
|
|
9
|
+
getConversationDetails,
|
|
10
|
+
getConversationDetailsForIds,
|
|
9
11
|
listAgentTurnSessionSummaries,
|
|
10
12
|
listAgentTurnSessionSummariesForConversation,
|
|
11
13
|
resolveSlackConversationContextFromThreadId
|
|
12
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-HOGQL2H6.js";
|
|
13
15
|
import {
|
|
14
16
|
discoverSkills
|
|
15
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-GT67ZWZQ.js";
|
|
18
|
+
import "./chunk-R62YWUNO.js";
|
|
19
|
+
import {
|
|
20
|
+
getPluginPackageContent,
|
|
21
|
+
getPluginProviders
|
|
22
|
+
} from "./chunk-UXG6TU2U.js";
|
|
23
|
+
import "./chunk-76YMBKW7.js";
|
|
16
24
|
import {
|
|
17
25
|
canExposeConversationPayload,
|
|
18
26
|
parseSlackThreadId,
|
|
19
27
|
resolveConversationPrivacy
|
|
20
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-JS4HURDT.js";
|
|
21
29
|
import {
|
|
22
|
-
|
|
23
|
-
getPluginProviders,
|
|
30
|
+
homeDir,
|
|
24
31
|
isRecord
|
|
25
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-BBXYXOJW.js";
|
|
26
33
|
import "./chunk-Z3YD6NHK.js";
|
|
27
|
-
import {
|
|
28
|
-
homeDir
|
|
29
|
-
} from "./chunk-KVZL5NZS.js";
|
|
30
34
|
import "./chunk-2KG3PWR4.js";
|
|
31
35
|
|
|
32
36
|
// src/reporting.ts
|
|
@@ -87,12 +91,6 @@ function surfaceFromConversationId(conversationId) {
|
|
|
87
91
|
function surfaceFromSummary(summary) {
|
|
88
92
|
return summary.surface ?? surfaceFromConversationId(summary.conversationId);
|
|
89
93
|
}
|
|
90
|
-
function titleFromSummary(summary) {
|
|
91
|
-
if (summary.state === "awaiting_resume" && summary.resumeReason) {
|
|
92
|
-
return `Awaiting ${summary.resumeReason} resume`;
|
|
93
|
-
}
|
|
94
|
-
return `Turn ${summary.sessionId}`;
|
|
95
|
-
}
|
|
96
94
|
function requesterIdentityReport(requester) {
|
|
97
95
|
if (!requester) return void 0;
|
|
98
96
|
const identity = {
|
|
@@ -114,27 +112,33 @@ function turnUsageReport(usage) {
|
|
|
114
112
|
};
|
|
115
113
|
return Object.keys(report).length > 0 ? report : void 0;
|
|
116
114
|
}
|
|
117
|
-
function sessionReportFromSummary(summary, nowMs = Date.now()) {
|
|
115
|
+
function sessionReportFromSummary(summary, nowMs = Date.now(), details) {
|
|
118
116
|
const slackThread = parseSlackThreadId(summary.conversationId);
|
|
119
117
|
const privacy = resolveConversationPrivacy({
|
|
120
118
|
conversationId: summary.conversationId
|
|
121
119
|
});
|
|
120
|
+
const effectiveChannelName = details?.channelName ?? summary.channelName;
|
|
122
121
|
const slackConversation = resolveSlackConversationContextFromThreadId({
|
|
123
122
|
threadId: summary.conversationId,
|
|
124
|
-
channelName:
|
|
123
|
+
channelName: effectiveChannelName
|
|
125
124
|
});
|
|
126
125
|
const privateLabel = privacy !== "public" ? slackConversation ? formatSlackConversationRedactedLabel(slackConversation) : PRIVATE_CONVERSATION_LABEL : void 0;
|
|
127
|
-
const
|
|
128
|
-
const
|
|
126
|
+
const channelName = privateLabel ?? effectiveChannelName;
|
|
127
|
+
const effectiveSurface = details?.originSurface ?? surfaceFromSummary(summary);
|
|
128
|
+
const displayTitle = privateLabel ?? details?.displayTitle ?? slackStatsLocationLabel({
|
|
129
|
+
channel: slackThread?.channelId,
|
|
130
|
+
channelName: effectiveChannelName
|
|
131
|
+
}) ?? surfaceFallbackLabel(effectiveSurface);
|
|
132
|
+
const effectiveRequester = details?.originRequester ?? summary.requester;
|
|
129
133
|
const sentryConversationUrl = buildSentryConversationUrl(
|
|
130
134
|
summary.conversationId
|
|
131
135
|
);
|
|
132
136
|
const sentryTraceUrl = summary.traceId ? buildSentryTraceUrl(summary.traceId) : void 0;
|
|
133
|
-
const requesterIdentity = requesterIdentityReport(
|
|
137
|
+
const requesterIdentity = requesterIdentityReport(effectiveRequester);
|
|
134
138
|
const cumulativeUsage = turnUsageReport(summary.cumulativeUsage);
|
|
135
139
|
return {
|
|
136
140
|
conversationId: summary.conversationId,
|
|
137
|
-
|
|
141
|
+
displayTitle,
|
|
138
142
|
id: summary.sessionId,
|
|
139
143
|
status: statusFromCheckpoint(summary, nowMs),
|
|
140
144
|
startedAt: new Date(summary.startedAtMs).toISOString(),
|
|
@@ -143,8 +147,7 @@ function sessionReportFromSummary(summary, nowMs = Date.now()) {
|
|
|
143
147
|
...summary.state === "completed" ? { completedAt: new Date(summary.updatedAtMs).toISOString() } : {},
|
|
144
148
|
cumulativeDurationMs: summary.cumulativeDurationMs,
|
|
145
149
|
...cumulativeUsage ? { cumulativeUsage } : {},
|
|
146
|
-
surface:
|
|
147
|
-
title: titleFromSummary(summary),
|
|
150
|
+
surface: effectiveSurface,
|
|
148
151
|
...requesterIdentity ? { requesterIdentity } : {},
|
|
149
152
|
...slackThread ? { channel: slackThread.channelId } : {},
|
|
150
153
|
...channelName ? { channelName } : {},
|
|
@@ -235,8 +238,27 @@ function slackStatsLocationLabel(input) {
|
|
|
235
238
|
}
|
|
236
239
|
return name || channelId;
|
|
237
240
|
}
|
|
241
|
+
function surfaceFallbackLabel(surface) {
|
|
242
|
+
if (surface === "scheduler") return "Scheduler";
|
|
243
|
+
if (surface === "api") return "API";
|
|
244
|
+
if (surface === "internal") return "Internal";
|
|
245
|
+
return "Conversation";
|
|
246
|
+
}
|
|
247
|
+
function displayTitleFromDetails(conversationId, details) {
|
|
248
|
+
if (!details) return void 0;
|
|
249
|
+
const slackThread = parseSlackThreadId(conversationId);
|
|
250
|
+
const slackConversation = resolveSlackConversationContextFromThreadId({
|
|
251
|
+
threadId: conversationId,
|
|
252
|
+
channelName: details.channelName
|
|
253
|
+
});
|
|
254
|
+
const privateLabel = resolveConversationPrivacy({ conversationId }) !== "public" ? formatSlackConversationRedactedLabel(slackConversation) ?? PRIVATE_CONVERSATION_LABEL : void 0;
|
|
255
|
+
return privateLabel ?? details.displayTitle ?? slackStatsLocationLabel({
|
|
256
|
+
channel: slackThread?.channelId,
|
|
257
|
+
channelName: details.channelName
|
|
258
|
+
}) ?? (details.originSurface ? surfaceFallbackLabel(details.originSurface) : void 0);
|
|
259
|
+
}
|
|
238
260
|
function locationLabel(turn) {
|
|
239
|
-
return slackStatsLocationLabel(turn) ?? (turn.surface
|
|
261
|
+
return slackStatsLocationLabel(turn) ?? surfaceFallbackLabel(turn.surface);
|
|
240
262
|
}
|
|
241
263
|
function emptyStatsItem(label) {
|
|
242
264
|
return {
|
|
@@ -618,11 +640,18 @@ async function readSessions() {
|
|
|
618
640
|
const summaries = await listAgentTurnSessionSummaries(
|
|
619
641
|
DASHBOARD_SESSION_FEED_LIMIT
|
|
620
642
|
);
|
|
643
|
+
const detailsByConversationId = await getConversationDetailsForIds(
|
|
644
|
+
summaries.map((s) => s.conversationId)
|
|
645
|
+
);
|
|
621
646
|
return {
|
|
622
647
|
source: "turn_session_records",
|
|
623
648
|
generatedAt: new Date(nowMs).toISOString(),
|
|
624
649
|
sessions: summaries.map(
|
|
625
|
-
(summary) => sessionReportFromSummary(
|
|
650
|
+
(summary) => sessionReportFromSummary(
|
|
651
|
+
summary,
|
|
652
|
+
nowMs,
|
|
653
|
+
detailsByConversationId.get(summary.conversationId)
|
|
654
|
+
)
|
|
626
655
|
)
|
|
627
656
|
};
|
|
628
657
|
}
|
|
@@ -641,13 +670,20 @@ async function readConversationStats() {
|
|
|
641
670
|
summaries: sampledSummaries,
|
|
642
671
|
truncated
|
|
643
672
|
});
|
|
673
|
+
const detailsByConversationId = await getConversationDetailsForIds(
|
|
674
|
+
reportSummaries.map((summary) => summary.conversationId)
|
|
675
|
+
);
|
|
644
676
|
return buildConversationStatsReport({
|
|
645
677
|
generatedAt,
|
|
646
678
|
nowMs,
|
|
647
679
|
sampleLimit: DASHBOARD_CONVERSATION_STATS_LIMIT,
|
|
648
680
|
sampleSize: sampledSummaries.length,
|
|
649
681
|
sessions: reportSummaries.map(
|
|
650
|
-
(summary) => sessionReportFromSummary(
|
|
682
|
+
(summary) => sessionReportFromSummary(
|
|
683
|
+
summary,
|
|
684
|
+
nowMs,
|
|
685
|
+
detailsByConversationId.get(summary.conversationId)
|
|
686
|
+
)
|
|
651
687
|
),
|
|
652
688
|
truncated
|
|
653
689
|
});
|
|
@@ -655,13 +691,17 @@ async function readConversationStats() {
|
|
|
655
691
|
async function readPluginOperationalReports() {
|
|
656
692
|
const nowMs = Date.now();
|
|
657
693
|
return {
|
|
658
|
-
source: "
|
|
694
|
+
source: "plugins",
|
|
659
695
|
generatedAt: new Date(nowMs).toISOString(),
|
|
660
696
|
reports: await getAgentPluginOperationalReports(nowMs)
|
|
661
697
|
};
|
|
662
698
|
}
|
|
663
699
|
async function readConversation(conversationId) {
|
|
664
|
-
const
|
|
700
|
+
const [rawSummaries, details] = await Promise.all([
|
|
701
|
+
listAgentTurnSessionSummariesForConversation(conversationId),
|
|
702
|
+
getConversationDetails(conversationId)
|
|
703
|
+
]);
|
|
704
|
+
const summaries = rawSummaries.sort(
|
|
665
705
|
(left, right) => left.startedAtMs - right.startedAtMs || left.updatedAtMs - right.updatedAtMs || left.sessionId.localeCompare(right.sessionId)
|
|
666
706
|
);
|
|
667
707
|
const turns = await Promise.all(
|
|
@@ -684,7 +724,7 @@ async function readConversation(conversationId) {
|
|
|
684
724
|
const traceId = summary.traceId ?? sessionRecord?.traceId ?? (canExposeTranscript ? traceIdFromTranscript(transcript) : void 0);
|
|
685
725
|
const sentryTraceUrl = traceId ? buildSentryTraceUrl(traceId) : void 0;
|
|
686
726
|
return {
|
|
687
|
-
...sessionReportFromSummary(summary),
|
|
727
|
+
...sessionReportFromSummary(summary, Date.now(), details),
|
|
688
728
|
...traceId ? { traceId } : {},
|
|
689
729
|
...sentryTraceUrl ? { sentryTraceUrl } : {},
|
|
690
730
|
transcriptAvailable: Boolean(sessionRecord) && canExposeTranscript,
|
|
@@ -698,8 +738,11 @@ async function readConversation(conversationId) {
|
|
|
698
738
|
};
|
|
699
739
|
})
|
|
700
740
|
);
|
|
741
|
+
const firstTurn = turns[0];
|
|
742
|
+
const displayTitle = firstTurn?.displayTitle ?? displayTitleFromDetails(conversationId, details) ?? surfaceFallbackLabel(firstTurn?.surface ?? "slack");
|
|
701
743
|
return {
|
|
702
744
|
conversationId,
|
|
745
|
+
displayTitle,
|
|
703
746
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
704
747
|
turns
|
|
705
748
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.70.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -65,10 +65,11 @@
|
|
|
65
65
|
"node-html-markdown": "^2.0.0",
|
|
66
66
|
"yaml": "^2.9.0",
|
|
67
67
|
"zod": "^4.4.3",
|
|
68
|
-
"@sentry/junior-plugin-api": "0.
|
|
68
|
+
"@sentry/junior-plugin-api": "0.70.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.9.1",
|
|
72
|
+
"@vitest/coverage-v8": "^4.1.7",
|
|
72
73
|
"dependency-cruiser": "^17.4.0",
|
|
73
74
|
"msw": "^2.14.6",
|
|
74
75
|
"nitro": "3.0.260522-beta",
|
|
@@ -77,7 +78,7 @@
|
|
|
77
78
|
"typescript": "^6.0.3",
|
|
78
79
|
"vercel": "^54.4.0",
|
|
79
80
|
"vitest": "^4.1.7",
|
|
80
|
-
"@sentry/junior-scheduler": "0.
|
|
81
|
+
"@sentry/junior-scheduler": "0.70.0"
|
|
81
82
|
},
|
|
82
83
|
"scripts": {
|
|
83
84
|
"build": "tsup && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
@@ -88,6 +89,7 @@
|
|
|
88
89
|
"test:slack-boundary": "node scripts/check-slack-test-boundary.mjs",
|
|
89
90
|
"test:arch-boundary": "depcruise --config .dependency-cruiser.mjs src/chat",
|
|
90
91
|
"typecheck": "tsc --noEmit",
|
|
91
|
-
"skills:check": "node scripts/check-skills.mjs"
|
|
92
|
+
"skills:check": "node scripts/check-skills.mjs",
|
|
93
|
+
"test:coverage": "pnpm run test:slack-boundary && pnpm run test:arch-boundary && vitest run --maxWorkers=4 --coverage --reporter=default --reporter=junit --outputFile.junit=coverage/results.junit.xml"
|
|
92
94
|
}
|
|
93
95
|
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { CredentialBroker } from "@/chat/credentials/broker";
|
|
2
|
-
import type { GitHubAppCredentials, PluginManifest } from "../types";
|
|
3
|
-
/** Create a broker that keeps GitHub App tokens on the host while authorizing provider traffic. */
|
|
4
|
-
export declare function createGitHubAppBroker(manifest: PluginManifest, credentials: GitHubAppCredentials): CredentialBroker;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
type GitHubPermissionRequest = Record<string, "read" | "write">;
|
|
2
|
-
export declare const DEFAULT_GITHUB_SYSTEM_READ_SCOPES: Set<string>;
|
|
3
|
-
/** Validate and normalize GitHub App read scopes from plugin configuration. */
|
|
4
|
-
export declare function normalizeGitHubSystemReadPermissionScopes(scopes: string[], context: string): string[];
|
|
5
|
-
/** Convert plugin capabilities into the GitHub App installation permission body. */
|
|
6
|
-
export declare function githubCapabilitiesToPermissions(capabilities: string[], pluginName: string): GitHubPermissionRequest;
|
|
7
|
-
/** Convert configured system scopes into read-only GitHub App permissions. */
|
|
8
|
-
export declare function githubSystemReadPermissionsFromScopes(scopes: string[]): GitHubPermissionRequest;
|
|
9
|
-
/** Intersect installation permissions with the allowed system read scope set. */
|
|
10
|
-
export declare function githubInstallationReadPermissions(permissions: Record<string, string> | undefined, allowedScopes: Set<string>): GitHubPermissionRequest;
|
|
11
|
-
export {};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { Message, Thread } from "chat";
|
|
2
|
-
import type { SlackTurnRuntime } from "@/chat/runtime/slack-runtime";
|
|
3
|
-
import { downloadPrivateSlackFile as downloadPrivateSlackFileImpl } from "@/chat/slack/client";
|
|
4
|
-
export type ThreadMessageKind = "new_mention" | "subscribed_message";
|
|
5
|
-
export interface ThreadMessageDispatchArgs {
|
|
6
|
-
beforeFirstResponsePost?: () => Promise<void>;
|
|
7
|
-
kind: ThreadMessageKind;
|
|
8
|
-
message: Message;
|
|
9
|
-
thread: Thread;
|
|
10
|
-
}
|
|
11
|
-
export type ThreadMessageRuntime = Pick<SlackTurnRuntime<unknown>, "handleNewMention" | "handleSubscribedMessage">;
|
|
12
|
-
export type ThreadMessageDispatcher = (args: ThreadMessageDispatchArgs) => Promise<void>;
|
|
13
|
-
export interface CreateThreadMessageDispatcherOptions {
|
|
14
|
-
downloadPrivateSlackFile?: typeof downloadPrivateSlackFileImpl;
|
|
15
|
-
runtime: ThreadMessageRuntime;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Attach Slack private-file download functions to deserialized attachments.
|
|
19
|
-
*
|
|
20
|
-
* The Chat SDK's `concurrency: "queue"` strategy serializes queued messages
|
|
21
|
-
* via `Message.toJSON()`, which strips `fetchData` (a function) and `data`
|
|
22
|
-
* (a Buffer). When dequeued, attachments have a `url` but no fetcher.
|
|
23
|
-
* This re-attaches a bot-token-auth'd download callback.
|
|
24
|
-
*
|
|
25
|
-
* No-ops when `fetchData` is already present, so safe to call unconditionally.
|
|
26
|
-
*/
|
|
27
|
-
export declare function rehydrateAttachmentFetchers(message: {
|
|
28
|
-
attachments: Array<{
|
|
29
|
-
fetchData?: unknown;
|
|
30
|
-
url?: string;
|
|
31
|
-
}>;
|
|
32
|
-
}, downloadPrivateSlackFile?: typeof downloadPrivateSlackFileImpl): void;
|
|
33
|
-
export declare function createThreadMessageDispatcher(options: CreateThreadMessageDispatcherOptions): ThreadMessageDispatcher;
|