@sentry/junior 0.267.0 → 0.269.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/README.md +2 -9
- package/dist/{actor-DZSokpwj.js → actor-CP9K2Idu.js} +2 -1
- package/dist/{adapter-BybMEezj.js → adapter-2-CG25be.js} +3 -51
- package/dist/{admin-DOs1_EiW.js → admin-DSs8S5Uy.js} +1 -1
- package/dist/{agent-invocations-CxKldAeB.js → agent-invocations-C1RNOCs8.js} +2 -0
- package/dist/{agent-runner-DgNATN4D.js → agent-runner-CrDrPUtY.js} +3411 -1640
- package/dist/api/schema.d.ts +2 -5630
- package/dist/api/schema.js +7 -7
- package/dist/api.d.ts +3 -1
- package/dist/api.js +268 -287
- package/dist/{app-DAB3fzyp.d.ts → app-BrMMzjYm.d.ts} +10 -3
- package/dist/app.d.ts +1 -1
- package/dist/app.js +371 -223
- package/dist/{automation-CmeFBSEh.js → automation-p87hg_AV.js} +74 -74
- package/dist/{briefs-CWKjka7v.js → briefs-PtODdLNu.js} +4 -4
- package/dist/{catalog-runtime-cMlAI5LY.js → catalog-runtime-BsoSmTM0.js} +1 -1
- package/dist/cli/chat.js +16 -26
- package/dist/cli/check.js +3 -3
- package/dist/cli/main.js +5 -3
- package/dist/cli/plugins.js +4 -4
- package/dist/cli/snapshot-create.js +4 -4
- package/dist/cli/upgrade.d.ts +1 -1
- package/dist/cli/upgrade.js +3 -3
- package/dist/{client-BjgbMawj.js → client-Cqf4TboL.js} +20 -15
- package/dist/{config-CdB6yJj5.js → config-CPsE4T5L.js} +2 -2
- package/dist/{connections-RE_65jzK.js → connections-upFXLmhG.js} +10 -11
- package/dist/{conversation-DSo310Ps.js → conversation-CTpD_PGk.js} +7 -84
- package/dist/{conversation-privacy-BzgJC5k0.js → conversation-privacy-D6zJc8ff.js} +1 -1
- package/dist/{credential-sync-DhEGEpgq.js → credential-sync-CS_6IC-f.js} +30 -34
- package/dist/{credentialed-CIGwoLU2.js → credentialed-BU-OW7HP.js} +577 -74
- package/dist/{store-B8CABbmR.d.ts → db-BzOCzVb1.d.ts} +17 -7
- package/dist/{executor-VYrx_K4w.js → executor-CNS7ONt-.js} +78 -4
- package/dist/instrumentation.js +2 -2
- package/dist/{assistant-reply-CT7VcXQe.js → interruption-marker-g6Xup3Fk.js} +8 -2
- package/dist/{job-queue-C0BZSa7r.js → job-queue-DI-k-Bbk.js} +2 -2
- package/dist/{list-1XQP-o6K.js → list-CGoQdXTp.js} +429 -1401
- package/dist/locks-D-0h111u.js +48 -0
- package/dist/{logging-DuZ1A4ab.js → logging-n7knse-O.js} +1 -1
- package/dist/{history-C84mlAwO.js → media-85PDJxO_.js} +83 -1
- package/dist/{message-NKSbbnA6.js → message-BpaWd8TT.js} +4 -4
- package/dist/nitro.d.ts +1 -1
- package/dist/nitro.js +3 -3
- package/dist/{oauth-callback-server-qAHLPtml.js → oauth-callback-server-CpGmEw_i.js} +2 -2
- package/dist/{prompt-BW9jFsqZ.js → prompt-BlQB0QQt.js} +1 -1
- package/dist/{registry-FQutO926.js → registry-By36_xsm.js} +2 -2
- package/dist/reporting-schema-CZREhYc-.js +104 -0
- package/dist/reporting-window-CVarfId9.js +255 -0
- package/dist/{resolve-Bk4yeuHy.js → resolve-CUIBcdPd.js} +3 -3
- package/dist/{result-B9e9ATOU.js → result-BemsOMOO.js} +31 -12
- package/dist/{runner-C3S2ObH-.js → runner-BVok7PAA.js} +12 -11
- package/dist/{sandbox-egress-signals-DqpGzzMB.js → sandbox-egress-signals-BSUWQI95.js} +1 -1
- package/dist/{schema-X7Fj4fv1.js → schema-ChnFo5f2.js} +98 -6
- package/dist/schema-jK4-1u_H.d.ts +5927 -0
- package/dist/{service-account-Do30HUNv.js → service-account-DHvlLnZw.js} +4 -3
- package/dist/{service-account-BQasl-qq.js → service-account-hMmESDcr.js} +3 -3
- package/dist/{session-stop-DkOjt46_.js → session-stop-BQW_iFcd.js} +499 -23
- package/dist/{skills-CQHrwfOa.js → skills-DmJJIuLF.js} +2 -2
- package/dist/{spawn-BHuqN14f.js → spawn-ChCm46i-.js} +2 -2
- package/dist/{store-6EetVP-m.js → store-1DVhoKOL.js} +4 -4
- package/dist/{store-DvNZIsCr.js → store-DCo2n5iJ.js} +3 -3
- package/dist/{task-queue-B0DLgd2P.js → task-queue-HMC4QjFm.js} +3 -3
- package/dist/task-runner-cA6yjn_E.js +269 -0
- package/dist/{thread-state-DRmdJ2QN.js → thread-state-CHy8LS0C.js} +8 -18
- package/dist/{turn-failure-response-G11cs2gE.js → turn-failure-response-Dr7erLWs.js} +11 -16
- package/dist/{turn-lifecycle-OzLIwvi1.js → turn-lifecycle-bf2fIYi_.js} +1 -1
- package/dist/{tasks-0ilmuCux.js → turn-session-routing-BqO0qXLk.js} +959 -44
- package/dist/{validation-CxEmt1id.js → validation-DHR1ivfh.js} +1 -1
- package/dist/{version-Bapedn4A.js → version-CXCHLgWm.js} +1 -1
- package/dist/version.js +1 -1
- package/dist/{viewer-DrN3oC2X.js → viewer-DSbD6DF6.js} +503 -241
- package/dist/{work-DUQoNcqP.js → work-BE_qTYGi.js} +17 -36
- package/dist/{worker-D1l4Ugk0.js → worker-Cm9_sWXg.js} +15 -7
- package/migrations/0065_user_customization.sql +1 -0
- package/migrations/0066_review_items.sql +53 -0
- package/migrations/0067_review_item_dedupe_tenant.sql +2 -0
- package/migrations/0068_review_item_slack_cards.sql +10 -0
- package/migrations/0069_system_identity.sql +25 -0
- package/migrations/0070_review_item_foreign_keys.sql +5 -0
- package/migrations/AGENTS.md +17 -0
- package/migrations/meta/0065_snapshot.json +3511 -0
- package/migrations/meta/0066_snapshot.json +4099 -0
- package/migrations/meta/0067_snapshot.json +3921 -0
- package/migrations/meta/0068_snapshot.json +4176 -0
- package/migrations/meta/0069_snapshot.json +3979 -0
- package/migrations/meta/0070_snapshot.json +3997 -0
- package/migrations/meta/_journal.json +42 -0
- package/package.json +5 -5
- package/dist/db-Bg-zC3r5.d.ts +0 -5
- package/dist/history-BgI33Kie.d.ts +0 -78
- package/dist/images-CecjXAAz.js +0 -64
- package/dist/task-runner-B-PD_JOj.js +0 -1074
- package/dist/turn-session-routing-Dyut9l7Y.js +0 -76
- package/dist/user-input-request-BDFBdF8r.js +0 -116
- package/dist/web-message-id-CJSUiksE.js +0 -236
- package/migrations/README.md +0 -30
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
// src/chat/services/turn-session-routing.ts
|
|
2
|
-
async function loadConversationChain(conversationId, conversationStore) {
|
|
3
|
-
const chain = [];
|
|
4
|
-
const seen = /* @__PURE__ */ new Set();
|
|
5
|
-
let cursor = conversationId;
|
|
6
|
-
while (cursor && !seen.has(cursor)) {
|
|
7
|
-
seen.add(cursor);
|
|
8
|
-
const conversation = await conversationStore.get({ conversationId: cursor });
|
|
9
|
-
if (!conversation) break;
|
|
10
|
-
chain.push(conversation);
|
|
11
|
-
cursor = conversation.parentConversationId;
|
|
12
|
-
}
|
|
13
|
-
return chain;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Normalize a stored Slack session source against the conversation destination.
|
|
17
|
-
*
|
|
18
|
-
* Does not create channel or thread values from the conversation id.
|
|
19
|
-
*/
|
|
20
|
-
function slackSourceForDestination(args) {
|
|
21
|
-
if (args.source?.kind !== "slack" || args.source.channelId !== args.destination.channelId) return;
|
|
22
|
-
const threadTs = args.source.threadTs?.trim();
|
|
23
|
-
return {
|
|
24
|
-
kind: "slack",
|
|
25
|
-
visibility: args.source.visibility ?? "public",
|
|
26
|
-
teamId: args.source.teamId?.trim() || args.destination.teamId,
|
|
27
|
-
channelId: args.source.channelId,
|
|
28
|
-
...threadTs ? { threadTs } : void 0
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Resolve the Conversation Location, Destination, and session Source.
|
|
33
|
-
*
|
|
34
|
-
* Reads parent Conversations when this Conversation has no Destination.
|
|
35
|
-
*/
|
|
36
|
-
async function resolveConversationRouting(args) {
|
|
37
|
-
const conversationStore = args.conversationStore ?? (await import("./viewer-DrN3oC2X.js").then((n) => n.l)).getConversationStore();
|
|
38
|
-
const chain = await loadConversationChain(args.conversationId, conversationStore);
|
|
39
|
-
let destination;
|
|
40
|
-
let source;
|
|
41
|
-
let location;
|
|
42
|
-
for (const conversation of chain) {
|
|
43
|
-
destination ??= conversation.destination;
|
|
44
|
-
source ??= conversation.sessionSource;
|
|
45
|
-
location ??= conversation.location;
|
|
46
|
-
if (destination && source) break;
|
|
47
|
-
}
|
|
48
|
-
if (!destination) return;
|
|
49
|
-
if (destination.platform === "slack") {
|
|
50
|
-
const slackSource = slackSourceForDestination({
|
|
51
|
-
destination,
|
|
52
|
-
source
|
|
53
|
-
});
|
|
54
|
-
return {
|
|
55
|
-
destination,
|
|
56
|
-
...location ? { location } : void 0,
|
|
57
|
-
...slackSource ? { source: slackSource } : void 0
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
destination,
|
|
62
|
-
...location ? { location } : void 0,
|
|
63
|
-
...source ? { source } : void 0
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/** Require the Conversation Destination and Source from SQL. */
|
|
67
|
-
async function resolveTurnSessionRouting(args) {
|
|
68
|
-
const routing = await resolveConversationRouting(args);
|
|
69
|
-
if (!routing?.destination || !routing.source) throw new Error(`Conversation ${args.conversationId} is missing durable routing metadata`);
|
|
70
|
-
return {
|
|
71
|
-
destination: routing.destination,
|
|
72
|
-
...routing.location ? { location: routing.location } : void 0,
|
|
73
|
-
source: routing.source
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
export { resolveTurnSessionRouting as n, resolveConversationRouting as t };
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
// src/chat/tools/runtime/user-input-request.ts
|
|
3
|
-
const USER_INPUT_LIMITS = {
|
|
4
|
-
maxButtonOptions: 5,
|
|
5
|
-
maxDescriptionChars: 200,
|
|
6
|
-
maxFields: 4,
|
|
7
|
-
maxLabelChars: 75,
|
|
8
|
-
maxOptions: 10,
|
|
9
|
-
maxTextChars: 3e3,
|
|
10
|
-
maxQuestionChars: 3e3,
|
|
11
|
-
minOptions: 2
|
|
12
|
-
};
|
|
13
|
-
const labelSchema = z.string().trim().min(1).max(USER_INPUT_LIMITS.maxLabelChars);
|
|
14
|
-
const descriptionSchema = z.string().trim().min(1).max(USER_INPUT_LIMITS.maxDescriptionChars).optional();
|
|
15
|
-
const optionSchema = z.object({
|
|
16
|
-
label: labelSchema.describe("Short choice text, such as `Accept` or `Decline`. The answer uses this exact text."),
|
|
17
|
-
description: descriptionSchema.describe("Optional short note about what this choice does.")
|
|
18
|
-
});
|
|
19
|
-
const fieldBase = {
|
|
20
|
-
id: z.string().regex(/^[a-z][a-z0-9_]{0,31}$/).describe("Stable key for this field, such as `approach`."),
|
|
21
|
-
label: labelSchema.describe("Short field name, such as `Approach`."),
|
|
22
|
-
description: descriptionSchema.describe("Optional short help text for this field.")
|
|
23
|
-
};
|
|
24
|
-
const optionsSchema = z.array(optionSchema).min(USER_INPUT_LIMITS.minOptions).max(USER_INPUT_LIMITS.maxOptions).describe("Choices in display order.");
|
|
25
|
-
const userInputFieldSchema = z.discriminatedUnion("kind", [
|
|
26
|
-
z.object({
|
|
27
|
-
...fieldBase,
|
|
28
|
-
kind: z.literal("choice").describe("The person picks one option."),
|
|
29
|
-
options: optionsSchema
|
|
30
|
-
}),
|
|
31
|
-
z.object({
|
|
32
|
-
...fieldBase,
|
|
33
|
-
kind: z.literal("multi_choice").describe("The person picks any number of options."),
|
|
34
|
-
options: optionsSchema
|
|
35
|
-
}),
|
|
36
|
-
z.object({
|
|
37
|
-
...fieldBase,
|
|
38
|
-
kind: z.literal("text").describe("The person types a short answer.")
|
|
39
|
-
})
|
|
40
|
-
]);
|
|
41
|
-
const userInputRequestSchema = z.object({
|
|
42
|
-
question: z.string().trim().min(1).max(USER_INPUT_LIMITS.maxQuestionChars).describe("The question, in markdown. Include the facts the person needs to decide."),
|
|
43
|
-
fields: z.array(userInputFieldSchema).min(1).max(USER_INPUT_LIMITS.maxFields).describe("What to ask, in display order. Use one `choice` field for a simple decision.")
|
|
44
|
-
}).superRefine((request, context) => {
|
|
45
|
-
const ids = /* @__PURE__ */ new Set();
|
|
46
|
-
for (const field of request.fields) {
|
|
47
|
-
if (ids.has(field.id)) context.addIssue({
|
|
48
|
-
code: "custom",
|
|
49
|
-
message: "Each field needs a different id."
|
|
50
|
-
});
|
|
51
|
-
ids.add(field.id);
|
|
52
|
-
if (field.kind === "text") continue;
|
|
53
|
-
const labels = field.options.map((option) => option.label.toLowerCase());
|
|
54
|
-
if (new Set(labels).size !== labels.length) context.addIssue({
|
|
55
|
-
code: "custom",
|
|
56
|
-
message: "Each choice of a field needs a different label."
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
/**
|
|
61
|
-
* Return the single choice field of a request that a surface can show as
|
|
62
|
-
* one row of buttons, where one click is the whole answer.
|
|
63
|
-
*/
|
|
64
|
-
function buttonUserInputField(request) {
|
|
65
|
-
const [field, ...rest] = request.fields;
|
|
66
|
-
if (rest.length || field?.kind !== "choice") return void 0;
|
|
67
|
-
return field.options.length <= USER_INPUT_LIMITS.maxButtonOptions ? field : void 0;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Keep only answer values that match the request: known field ids, known
|
|
71
|
-
* option labels, one value for a `choice` field, and trimmed text.
|
|
72
|
-
*/
|
|
73
|
-
function normalizeUserInputAnswer(request, answer) {
|
|
74
|
-
const values = {};
|
|
75
|
-
for (const field of request.fields) {
|
|
76
|
-
const raw = (answer.values[field.id] ?? []).map((value) => value.trim()).filter(Boolean);
|
|
77
|
-
if (field.kind === "text") {
|
|
78
|
-
const text = raw.join("\n").slice(0, USER_INPUT_LIMITS.maxTextChars);
|
|
79
|
-
if (text) values[field.id] = [text];
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
const picked = field.options.map((option) => option.label).filter((label) => raw.includes(label));
|
|
83
|
-
const kept = field.kind === "choice" ? picked.slice(0, 1) : picked;
|
|
84
|
-
if (kept.length) values[field.id] = kept;
|
|
85
|
-
}
|
|
86
|
-
const other = answer.other?.trim().slice(0, USER_INPUT_LIMITS.maxTextChars);
|
|
87
|
-
return {
|
|
88
|
-
requestId: answer.requestId,
|
|
89
|
-
values,
|
|
90
|
-
...other ? { other } : void 0
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
/** Return true when an answer has no value and no free text. */
|
|
94
|
-
function isEmptyUserInputAnswer(answer) {
|
|
95
|
-
return !answer.other && Object.keys(answer.values).length === 0;
|
|
96
|
-
}
|
|
97
|
-
function answerLine(text) {
|
|
98
|
-
return text.split("\n").map((line) => line.trim()).filter(Boolean).join("\n");
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Write an answer as the text of the person's message. Slack and the web
|
|
102
|
-
* dashboard both send this text, so the model reads one format. The first
|
|
103
|
-
* line names the request, and each field starts its own line.
|
|
104
|
-
*/
|
|
105
|
-
function formatUserInputAnswer(request, answer) {
|
|
106
|
-
const normalized = normalizeUserInputAnswer(request, answer);
|
|
107
|
-
const lines = [`Answer to request ${normalized.requestId}:`];
|
|
108
|
-
for (const field of request.fields) {
|
|
109
|
-
const values = normalized.values[field.id];
|
|
110
|
-
const value = values?.length ? values.join(", ") : "(no answer)";
|
|
111
|
-
lines.push(answerLine(`${field.label} (${field.id}): ${value}`));
|
|
112
|
-
}
|
|
113
|
-
if (normalized.other) lines.push(answerLine(`Other: ${normalized.other}`));
|
|
114
|
-
return lines.join("\n");
|
|
115
|
-
}
|
|
116
|
-
export { normalizeUserInputAnswer as a, isEmptyUserInputAnswer as i, buttonUserInputField as n, userInputRequestSchema as o, formatUserInputAnswer as r, USER_INPUT_LIMITS as t };
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
// src/reporting-schema.ts
|
|
3
|
-
const healthReportSchema = z.object({
|
|
4
|
-
status: z.literal("ok"),
|
|
5
|
-
service: z.string(),
|
|
6
|
-
timestamp: z.string()
|
|
7
|
-
}).strict();
|
|
8
|
-
const pluginSchema = z.object({
|
|
9
|
-
configKeys: z.array(z.string()),
|
|
10
|
-
description: z.string(),
|
|
11
|
-
displayName: z.string(),
|
|
12
|
-
name: z.string()
|
|
13
|
-
}).strict();
|
|
14
|
-
const pluginsSchema = z.array(pluginSchema);
|
|
15
|
-
const skillReportSchema = z.object({
|
|
16
|
-
name: z.string(),
|
|
17
|
-
pluginProvider: z.string().optional()
|
|
18
|
-
}).strict();
|
|
19
|
-
const skillReportsSchema = z.array(skillReportSchema);
|
|
20
|
-
const pluginPackageContentItemReportSchema = z.object({
|
|
21
|
-
dir: z.string(),
|
|
22
|
-
hasMigrationsDir: z.boolean(),
|
|
23
|
-
hasSkillsDir: z.boolean(),
|
|
24
|
-
packageName: z.string()
|
|
25
|
-
}).strict();
|
|
26
|
-
const pluginPackageContentReportSchema = z.object({
|
|
27
|
-
packageNames: z.array(z.string()),
|
|
28
|
-
packages: z.array(pluginPackageContentItemReportSchema),
|
|
29
|
-
manifestRoots: z.array(z.string()),
|
|
30
|
-
skillRoots: z.array(z.string()),
|
|
31
|
-
tracingIncludes: z.array(z.string())
|
|
32
|
-
}).strict();
|
|
33
|
-
const runtimeInfoReportSchema = z.object({
|
|
34
|
-
cwd: z.string(),
|
|
35
|
-
homeDir: z.string(),
|
|
36
|
-
descriptionText: z.string().optional(),
|
|
37
|
-
providers: z.array(z.string()),
|
|
38
|
-
skills: z.array(skillReportSchema),
|
|
39
|
-
packagedContent: pluginPackageContentReportSchema
|
|
40
|
-
}).strict();
|
|
41
|
-
const pluginOperationalToneSchema = z.enum([
|
|
42
|
-
"danger",
|
|
43
|
-
"good",
|
|
44
|
-
"neutral",
|
|
45
|
-
"warning"
|
|
46
|
-
]);
|
|
47
|
-
const pluginOperationalMetricSchema = z.object({
|
|
48
|
-
label: z.string(),
|
|
49
|
-
tone: pluginOperationalToneSchema.optional(),
|
|
50
|
-
value: z.string()
|
|
51
|
-
}).strict();
|
|
52
|
-
const pluginOperationalFieldSchema = z.object({
|
|
53
|
-
key: z.string(),
|
|
54
|
-
label: z.string()
|
|
55
|
-
}).strict();
|
|
56
|
-
const pluginOperationalRecordSchema = z.object({
|
|
57
|
-
id: z.string(),
|
|
58
|
-
tone: pluginOperationalToneSchema.optional(),
|
|
59
|
-
values: z.record(z.string(), z.string())
|
|
60
|
-
}).strict();
|
|
61
|
-
const pluginOperationalRecordSetSchema = z.object({
|
|
62
|
-
fields: z.array(pluginOperationalFieldSchema).optional(),
|
|
63
|
-
emptyText: z.string().optional(),
|
|
64
|
-
records: z.array(pluginOperationalRecordSchema).optional(),
|
|
65
|
-
title: z.string()
|
|
66
|
-
}).strict();
|
|
67
|
-
const pluginOperationalBarChartWidgetSchema = z.object({
|
|
68
|
-
categories: z.array(z.object({
|
|
69
|
-
id: z.string().min(1),
|
|
70
|
-
label: z.string().min(1),
|
|
71
|
-
values: z.record(z.string(), z.number().finite())
|
|
72
|
-
}).strict()).max(100),
|
|
73
|
-
description: z.string().optional(),
|
|
74
|
-
emptyText: z.string().optional(),
|
|
75
|
-
id: z.string().min(1),
|
|
76
|
-
series: z.array(z.object({
|
|
77
|
-
format: z.literal("usd").optional(),
|
|
78
|
-
key: z.string().min(1),
|
|
79
|
-
label: z.string().min(1),
|
|
80
|
-
tone: pluginOperationalToneSchema.optional()
|
|
81
|
-
}).strict()).min(1).max(8),
|
|
82
|
-
timeRangeDays: z.array(z.union([
|
|
83
|
-
z.literal(1),
|
|
84
|
-
z.literal(7),
|
|
85
|
-
z.literal(30),
|
|
86
|
-
z.literal(90)
|
|
87
|
-
])).min(1).max(4).optional(),
|
|
88
|
-
title: z.string().min(1),
|
|
89
|
-
type: z.literal("bar_chart")
|
|
90
|
-
}).strict();
|
|
91
|
-
const pluginOperationalReportSchema = z.object({
|
|
92
|
-
generatedAt: z.string().optional(),
|
|
93
|
-
metrics: z.array(pluginOperationalMetricSchema).optional(),
|
|
94
|
-
recordSets: z.array(pluginOperationalRecordSetSchema).optional(),
|
|
95
|
-
title: z.string().optional(),
|
|
96
|
-
pluginName: z.string(),
|
|
97
|
-
widgets: z.array(pluginOperationalBarChartWidgetSchema).max(12).optional()
|
|
98
|
-
}).strict();
|
|
99
|
-
const pluginOperationalReportFeedSchema = z.object({
|
|
100
|
-
generatedAt: z.string(),
|
|
101
|
-
reports: z.array(pluginOperationalReportSchema),
|
|
102
|
-
source: z.literal("plugins")
|
|
103
|
-
}).strict();
|
|
104
|
-
// src/api/reporting-window.ts
|
|
105
|
-
/** Shared UTC day/hour/six-hour windows for dashboard activity series. */
|
|
106
|
-
const HOUR_MS = 36e5;
|
|
107
|
-
const SIX_HOUR_MS = 6 * HOUR_MS;
|
|
108
|
-
const DAY_MS = 24 * HOUR_MS;
|
|
109
|
-
/** Start of the UTC calendar day containing `valueMs`. */
|
|
110
|
-
function startOfUtcDay(valueMs) {
|
|
111
|
-
const date = new Date(valueMs);
|
|
112
|
-
date.setUTCHours(0, 0, 0, 0);
|
|
113
|
-
return date;
|
|
114
|
-
}
|
|
115
|
-
/** Start of the UTC hour containing `valueMs`. */
|
|
116
|
-
function startOfUtcHour(valueMs) {
|
|
117
|
-
const date = new Date(valueMs);
|
|
118
|
-
date.setUTCMinutes(0, 0, 0);
|
|
119
|
-
return date;
|
|
120
|
-
}
|
|
121
|
-
/** Start of the UTC 6-hour bucket containing `valueMs` (00/06/12/18). */
|
|
122
|
-
function startOfUtcSixHour(valueMs) {
|
|
123
|
-
const date = startOfUtcHour(valueMs);
|
|
124
|
-
date.setUTCHours(Math.floor(date.getUTCHours() / 6) * 6, 0, 0, 0);
|
|
125
|
-
return date;
|
|
126
|
-
}
|
|
127
|
-
/** UTC day key `YYYY-MM-DD`. */
|
|
128
|
-
function utcDayKey(value) {
|
|
129
|
-
return (typeof value === "number" ? new Date(value) : value).toISOString().slice(0, 10);
|
|
130
|
-
}
|
|
131
|
-
/** UTC hour key `YYYY-MM-DDTHH`. */
|
|
132
|
-
function utcHourKey(value) {
|
|
133
|
-
return (typeof value === "number" ? new Date(value) : value).toISOString().slice(0, 13);
|
|
134
|
-
}
|
|
135
|
-
/** UTC 6-hour bucket key `YYYY-MM-DDTHH` at 00/06/12/18. */
|
|
136
|
-
function utcSixHourKey(value) {
|
|
137
|
-
return utcHourKey(startOfUtcSixHour(typeof value === "number" ? value : value.getTime()));
|
|
138
|
-
}
|
|
139
|
-
/** Inclusive trailing UTC day window ending on today's UTC day. */
|
|
140
|
-
function trailingUtcDayWindow(nowMs, dayCount) {
|
|
141
|
-
const end = startOfUtcDay(nowMs);
|
|
142
|
-
const start = new Date(end);
|
|
143
|
-
start.setUTCDate(start.getUTCDate() - (dayCount - 1));
|
|
144
|
-
return {
|
|
145
|
-
end,
|
|
146
|
-
start
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
/** Inclusive trailing UTC hour window ending on the current UTC hour. */
|
|
150
|
-
function trailingUtcHourWindow(nowMs, hourCount = 24) {
|
|
151
|
-
const end = startOfUtcHour(nowMs);
|
|
152
|
-
return {
|
|
153
|
-
end,
|
|
154
|
-
start: /* @__PURE__ */ new Date(end.getTime() - (hourCount - 1) * HOUR_MS)
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
/** Inclusive trailing UTC 6-hour window ending on the current 6h bucket. */
|
|
158
|
-
function trailingUtcSixHourWindow(nowMs, bucketCount = 28) {
|
|
159
|
-
const end = startOfUtcSixHour(nowMs);
|
|
160
|
-
return {
|
|
161
|
-
end,
|
|
162
|
-
start: /* @__PURE__ */ new Date(end.getTime() - (bucketCount - 1) * SIX_HOUR_MS)
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
/** Fill a fixed UTC day window from a sparse map. */
|
|
166
|
-
function fillUtcDays(args) {
|
|
167
|
-
const { end, start } = trailingUtcDayWindow(args.nowMs, args.count);
|
|
168
|
-
const items = [];
|
|
169
|
-
for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setUTCDate(cursor.getUTCDate() + 1)) {
|
|
170
|
-
const date = utcDayKey(cursor);
|
|
171
|
-
items.push(args.rows.get(date) ?? args.empty(date));
|
|
172
|
-
}
|
|
173
|
-
return items;
|
|
174
|
-
}
|
|
175
|
-
/** Fill a fixed UTC hour window from a sparse map. */
|
|
176
|
-
function fillUtcHours(args) {
|
|
177
|
-
const hourCount = args.count ?? 24;
|
|
178
|
-
const { end, start } = trailingUtcHourWindow(args.nowMs, hourCount);
|
|
179
|
-
const items = [];
|
|
180
|
-
for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setTime(cursor.getTime() + HOUR_MS)) {
|
|
181
|
-
const date = utcHourKey(cursor);
|
|
182
|
-
items.push(args.rows.get(date) ?? args.empty(date));
|
|
183
|
-
}
|
|
184
|
-
return items;
|
|
185
|
-
}
|
|
186
|
-
/** Fill a fixed UTC 6-hour window from a map of known rows. */
|
|
187
|
-
function fillUtcSixHours(args) {
|
|
188
|
-
const bucketCount = args.count ?? 28;
|
|
189
|
-
const { end, start } = trailingUtcSixHourWindow(args.nowMs, bucketCount);
|
|
190
|
-
const items = [];
|
|
191
|
-
for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setTime(cursor.getTime() + SIX_HOUR_MS)) {
|
|
192
|
-
const date = utcSixHourKey(cursor);
|
|
193
|
-
items.push(args.rows.get(date) ?? args.empty(date));
|
|
194
|
-
}
|
|
195
|
-
return items;
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Sum hour rows into trailing 6-hour buckets.
|
|
199
|
-
* Adds number fields. Keeps other fields from the first row in the bucket.
|
|
200
|
-
* Sets `date` to the 6-hour bucket key.
|
|
201
|
-
*/
|
|
202
|
-
function sumUtcHoursIntoSixHours(args) {
|
|
203
|
-
const bucketCount = args.count ?? 28;
|
|
204
|
-
const bySix = /* @__PURE__ */ new Map();
|
|
205
|
-
for (const hour of args.hours) {
|
|
206
|
-
const key = utcSixHourKey(Date.parse(`${hour.date}:00:00.000Z`));
|
|
207
|
-
const next = {
|
|
208
|
-
...bySix.get(key) ?? args.empty(key),
|
|
209
|
-
date: key
|
|
210
|
-
};
|
|
211
|
-
for (const [field, value] of Object.entries(hour)) {
|
|
212
|
-
if (field === "date") continue;
|
|
213
|
-
if (typeof value === "number") {
|
|
214
|
-
const prior = next[field];
|
|
215
|
-
next[field] = (typeof prior === "number" ? prior : 0) + value;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
bySix.set(key, next);
|
|
219
|
-
}
|
|
220
|
-
return fillUtcSixHours({
|
|
221
|
-
count: bucketCount,
|
|
222
|
-
empty: args.empty,
|
|
223
|
-
nowMs: args.nowMs,
|
|
224
|
-
rows: bySix
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
// src/chat/conversations/web-message-id.ts
|
|
228
|
-
/**
|
|
229
|
-
* Build the retry-stable Message id shared by web ingress and browser sends.
|
|
230
|
-
* Keep the existing hash and prefix so retries still address stored Messages.
|
|
231
|
-
*/
|
|
232
|
-
async function webMessageId(args) {
|
|
233
|
-
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(`${args.conversationId}\u0000${args.idempotencyKey}`));
|
|
234
|
-
return `api-msg:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, 24)}`;
|
|
235
|
-
}
|
|
236
|
-
export { skillReportsSchema as C, skillReportSchema as S, pluginPackageContentItemReportSchema as _, fillUtcHours as a, pluginsSchema as b, sumUtcHoursIntoSixHours as c, trailingUtcSixHourWindow as d, utcDayKey as f, pluginOperationalReportSchema as g, pluginOperationalReportFeedSchema as h, fillUtcDays as i, trailingUtcDayWindow as l, healthReportSchema as m, DAY_MS as n, fillUtcSixHours as o, utcHourKey as p, HOUR_MS as r, startOfUtcHour as s, webMessageId as t, trailingUtcHourWindow as u, pluginPackageContentReportSchema as v, runtimeInfoReportSchema as x, pluginSchema as y };
|
package/migrations/README.md
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# SQL migrations
|
|
2
|
-
|
|
3
|
-
`src/db/schema.ts` is the Drizzle schema entrypoint. This directory is the
|
|
4
|
-
append-only history used to bring an existing database to that schema.
|
|
5
|
-
|
|
6
|
-
`junior upgrade` applies core migrations and enabled plugins' packaged Drizzle
|
|
7
|
-
migrations. Core SQL is recorded in `drizzle.__drizzle_junior_core`. Reruns
|
|
8
|
-
check that journal before taking the migration lock, so an already-current
|
|
9
|
-
schema returns without opening a second SQL connection.
|
|
10
|
-
|
|
11
|
-
An existing Junior schema without the core Drizzle journal cannot be upgraded
|
|
12
|
-
directly. Upgrade it with `@sentry/junior@0.107.1` first so that bridge release
|
|
13
|
-
can establish the journal, then continue to the target version. A database with
|
|
14
|
-
no Junior tables remains a normal fresh install.
|
|
15
|
-
|
|
16
|
-
## Add a migration
|
|
17
|
-
|
|
18
|
-
1. Change the owning table definition under `src/db/schema/`.
|
|
19
|
-
2. Run `pnpm --filter @sentry/junior db:generate --name <migration_name>`.
|
|
20
|
-
3. Review the generated SQL and commit it with `meta/_journal.json` and its
|
|
21
|
-
snapshot.
|
|
22
|
-
|
|
23
|
-
- Put deterministic row transformations in the SQL migration that requires
|
|
24
|
-
them.
|
|
25
|
-
- Never edit, rename, reorder, or delete an applied SQL migration or its
|
|
26
|
-
metadata. Add a new migration to correct it.
|
|
27
|
-
|
|
28
|
-
Migration loading, locking, and the bridge-version guard live in
|
|
29
|
-
`src/chat/conversations/sql/migrations.ts`. Their integration coverage lives in
|
|
30
|
-
`tests/integration/conversation-sql.test.ts`.
|