(text, extensions = new Set())
| 536 | * rejecting `res.send` and `mime.contentType`, which are the same token shape. |
| 537 | */ |
| 538 | export function answerCitations(text, extensions = new Set()) { |
| 539 | const src = String(text ?? ''); |
| 540 | const paths = new Set(); |
| 541 | // Dotted path with at least one directory: `lib/response.js:126-220`. |
| 542 | for (const m of src.matchAll(/(?:[\w@.+-]+\/)+[\w@.+-]+\.[A-Za-z]\w*/g)) paths.add(m[0]); |
| 543 | // Bare basename, only when its extension is one the envelope actually shipped. |
| 544 | for (const m of src.matchAll(/\b[\w@+-]+\.[A-Za-z]\w*/g)) { |
| 545 | const ext = m[0].slice(m[0].lastIndexOf('.') + 1).toLowerCase(); |
| 546 | if (extensions.has(ext)) paths.add(m[0]); |
| 547 | } |
| 548 | // Identifiers inside code spans. Prose mentions are excluded on purpose: a |
| 549 | // backtick is the agent marking the token as code, which is the whole signal. |
| 550 | const symbols = new Set(); |
| 551 | for (const span of src.matchAll(/`([^`\n]+)`/g)) { |
| 552 | for (const t of span[1].matchAll(/[A-Za-z_$][\w$]*/g)) { |
| 553 | const tok = t[0]; |
| 554 | if (tok.length >= MIN_SYMBOL_LEN && !SYMBOL_STOPWORDS.has(tok.toLowerCase())) symbols.add(tok); |
| 555 | } |
| 556 | } |
| 557 | return { paths: [...paths], symbols }; |
| 558 | } |
| 559 | |
| 560 | /** |
| 561 | * Allocation efficiency over one session's explore responses and its final |
no test coverage detected