@sentry/junior 0.67.2 → 0.67.3

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 CHANGED
@@ -47,7 +47,7 @@ import {
47
47
  validateAgentPlugins,
48
48
  verifySlackDirectCredentialSubject,
49
49
  withSlackRetries
50
- } from "./chunk-PLJTW7IB.js";
50
+ } from "./chunk-UQQSW7QB.js";
51
51
  import {
52
52
  discoverSkills,
53
53
  findSkillByName,
@@ -1,12 +1,13 @@
1
1
  /** Insert blank lines between content blocks so Slack renders them with visual separation. */
2
2
  export declare function ensureBlockSpacing(text: string): string;
3
3
  /**
4
- * Render model-authored markdown into Slack-friendly `mrkdwn`.
4
+ * Normalize model-authored Slack markdown for delivery via `markdown_text`
5
+ * or `{ type: "markdown" }` blocks.
5
6
  *
6
- * Slack reply delivery owns chunking and continuation markers separately.
7
- * This helper only normalizes text into the repository's canonical Slack
8
- * rendering form.
7
+ * Pre-wraps bare URLs as Slack explicit links to prevent Slack's auto-linker
8
+ * from consuming adjacent formatting markers. Slack reply delivery owns
9
+ * chunking and continuation markers separately.
9
10
  */
10
- export declare function renderSlackMrkdwn(text: string): string;
11
+ export declare function normalizeSlackReplyMarkdown(text: string): string;
11
12
  /** Normalize assistant status text before handing it to Slack. */
12
13
  export declare function normalizeSlackStatusText(text: string): string;
@@ -1095,6 +1095,145 @@ function truncateStatusText(text) {
1095
1095
  }
1096
1096
 
1097
1097
  // src/chat/slack/mrkdwn.ts
1098
+ function readInlineCodeSpan(line, start) {
1099
+ if (line[start] !== "`") {
1100
+ return void 0;
1101
+ }
1102
+ let n = 1;
1103
+ while (line[start + n] === "`") {
1104
+ n++;
1105
+ }
1106
+ const marker = "`".repeat(n);
1107
+ let search = start + n;
1108
+ while (search < line.length) {
1109
+ const close = line.indexOf(marker, search);
1110
+ if (close === -1) {
1111
+ return void 0;
1112
+ }
1113
+ const after = close + n;
1114
+ if (line[after] !== "`") {
1115
+ return { text: line.slice(start, after), end: after };
1116
+ }
1117
+ search = after + 1;
1118
+ }
1119
+ return void 0;
1120
+ }
1121
+ function readExistingSlackAngleToken(line, start) {
1122
+ if (line[start] !== "<") {
1123
+ return void 0;
1124
+ }
1125
+ const close = line.indexOf(">", start + 1);
1126
+ if (close === -1) {
1127
+ return void 0;
1128
+ }
1129
+ const body = line.slice(start + 1, close);
1130
+ if (/^(?:https?:\/\/|@|#|!)/.test(body)) {
1131
+ return { text: line.slice(start, close + 1), end: close + 1 };
1132
+ }
1133
+ return void 0;
1134
+ }
1135
+ function readMarkdownLink(line, start) {
1136
+ if (line[start] !== "[") {
1137
+ return void 0;
1138
+ }
1139
+ const labelEnd = line.indexOf("](", start + 1);
1140
+ if (labelEnd === -1) {
1141
+ return void 0;
1142
+ }
1143
+ const destStart = labelEnd + 2;
1144
+ if (!line.startsWith("http://", destStart) && !line.startsWith("https://", destStart)) {
1145
+ return void 0;
1146
+ }
1147
+ const closeParens = line.indexOf(")", destStart);
1148
+ if (closeParens === -1) {
1149
+ return void 0;
1150
+ }
1151
+ return { text: line.slice(start, closeParens + 1), end: closeParens + 1 };
1152
+ }
1153
+ function hasUnmatchedClosingParen(text) {
1154
+ let balance = 0;
1155
+ for (const ch of text) {
1156
+ if (ch === "(") balance++;
1157
+ else if (ch === ")") balance--;
1158
+ }
1159
+ return balance < 0;
1160
+ }
1161
+ function readBareUrl(line, start) {
1162
+ let end = start;
1163
+ while (end < line.length) {
1164
+ const ch = line[end];
1165
+ if (/\s/.test(ch) || ch === "<" || ch === ">" || ch === '"' || ch === "`" || ch === "|" || ch === "*") {
1166
+ break;
1167
+ }
1168
+ end++;
1169
+ }
1170
+ if (end === start) {
1171
+ return void 0;
1172
+ }
1173
+ let raw = line.slice(start, end);
1174
+ let suffix = "";
1175
+ const peel = () => {
1176
+ suffix = raw.slice(-1) + suffix;
1177
+ raw = raw.slice(0, -1);
1178
+ };
1179
+ const shouldPeel = () => raw.endsWith("_") || /[.,!?;:]$/.test(raw) || raw.endsWith(")") && hasUnmatchedClosingParen(raw);
1180
+ while (raw.length > 0 && shouldPeel()) {
1181
+ peel();
1182
+ }
1183
+ if (!/^https?:\/\/.+/.test(raw)) {
1184
+ return void 0;
1185
+ }
1186
+ return { url: raw, suffix, end };
1187
+ }
1188
+ function wrapBareUrlsOnLine(line) {
1189
+ let result = "";
1190
+ let i = 0;
1191
+ while (i < line.length) {
1192
+ const codeSpan = readInlineCodeSpan(line, i);
1193
+ if (codeSpan) {
1194
+ result += codeSpan.text;
1195
+ i = codeSpan.end;
1196
+ continue;
1197
+ }
1198
+ const angleToken = readExistingSlackAngleToken(line, i);
1199
+ if (angleToken) {
1200
+ result += angleToken.text;
1201
+ i = angleToken.end;
1202
+ continue;
1203
+ }
1204
+ const mdLink = readMarkdownLink(line, i);
1205
+ if (mdLink) {
1206
+ result += mdLink.text;
1207
+ i = mdLink.end;
1208
+ continue;
1209
+ }
1210
+ if (line.startsWith("https://", i) || line.startsWith("http://", i)) {
1211
+ const parsed = readBareUrl(line, i);
1212
+ if (parsed) {
1213
+ result += `<${parsed.url}>${parsed.suffix}`;
1214
+ i = parsed.end;
1215
+ continue;
1216
+ }
1217
+ }
1218
+ result += line[i];
1219
+ i++;
1220
+ }
1221
+ return result;
1222
+ }
1223
+ function wrapBareUrls(text) {
1224
+ const lines = text.split("\n");
1225
+ const out = [];
1226
+ let inCodeBlock = false;
1227
+ for (const line of lines) {
1228
+ if (line.trimStart().startsWith("```")) {
1229
+ inCodeBlock = !inCodeBlock;
1230
+ out.push(line);
1231
+ continue;
1232
+ }
1233
+ out.push(inCodeBlock ? line : wrapBareUrlsOnLine(line));
1234
+ }
1235
+ return out.join("\n");
1236
+ }
1098
1237
  function ensureBlockSpacing(text) {
1099
1238
  const codeBlockPattern = /^```/;
1100
1239
  const listItemPattern = /^[-*•]\s|^\d+\.\s/;
@@ -1127,8 +1266,9 @@ function ensureBlockSpacing(text) {
1127
1266
  }
1128
1267
  return result.join("\n");
1129
1268
  }
1130
- function renderSlackMrkdwn(text) {
1269
+ function normalizeSlackReplyMarkdown(text) {
1131
1270
  let normalized = text.replace(/\r\n?/g, "\n").replace(/[ \t]+$/gm, "");
1271
+ normalized = wrapBareUrls(normalized);
1132
1272
  normalized = ensureBlockSpacing(normalized);
1133
1273
  return normalized.replace(/\n{3,}/g, "\n\n").trim();
1134
1274
  }
@@ -1302,7 +1442,7 @@ function takeSlackInlinePrefix(text, options) {
1302
1442
  };
1303
1443
  }
1304
1444
  function splitSlackReplyText(text, options) {
1305
- const normalized = renderSlackMrkdwn(text);
1445
+ const normalized = normalizeSlackReplyMarkdown(text);
1306
1446
  if (!normalized) {
1307
1447
  return [];
1308
1448
  }
@@ -1333,7 +1473,7 @@ function getSlackContinuationBudget() {
1333
1473
  return reserveInlineBudgetForSuffix(CONTINUED_MARKER);
1334
1474
  }
1335
1475
  function buildSlackOutputMessage(text, files) {
1336
- const normalized = renderSlackMrkdwn(text);
1476
+ const normalized = normalizeSlackReplyMarkdown(text);
1337
1477
  const fileCount = files?.length ?? 0;
1338
1478
  if (!normalized) {
1339
1479
  if (fileCount > 0) {
package/dist/reporting.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  listAgentTurnSessionSummaries,
10
10
  listAgentTurnSessionSummariesForConversation,
11
11
  resolveSlackConversationContextFromThreadId
12
- } from "./chunk-PLJTW7IB.js";
12
+ } from "./chunk-UQQSW7QB.js";
13
13
  import {
14
14
  discoverSkills
15
15
  } from "./chunk-V47RLIO2.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior",
3
- "version": "0.67.2",
3
+ "version": "0.67.3",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -65,7 +65,7 @@
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.67.2"
68
+ "@sentry/junior-plugin-api": "0.67.3"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/node": "^25.9.1",
@@ -77,7 +77,7 @@
77
77
  "typescript": "^6.0.3",
78
78
  "vercel": "^54.4.0",
79
79
  "vitest": "^4.1.7",
80
- "@sentry/junior-scheduler": "0.67.2"
80
+ "@sentry/junior-scheduler": "0.67.3"
81
81
  },
82
82
  "scripts": {
83
83
  "build": "tsup && tsc -p tsconfig.build.json --emitDeclarationOnly",