(text)
| 417 | 'namespace', 'route', 'component', |
| 418 | ]); |
| 419 | export function parseExploreCall(text) { |
| 420 | const src = String(text ?? ''); |
| 421 | const re = /^\*\*`([^`]+)`\*\*(.*)$/gm; |
| 422 | const marks = []; |
| 423 | let m; |
| 424 | while ((m = re.exec(src)) !== null) marks.push({ path: m[1], header: m[2] || '', at: m.index }); |
| 425 | if (!marks.length) return { envelope: 0, files: [] }; |
| 426 | // Sections run to the next header, or to the trailing guidance quote. |
| 427 | const tail = src.indexOf('\n> ', marks[marks.length - 1].at); |
| 428 | const end = tail === -1 ? src.length : tail; |
| 429 | const files = marks.map((mark, i) => ({ |
| 430 | path: mark.path, |
| 431 | chars: (i + 1 < marks.length ? marks[i + 1].at : end) - mark.at, |
| 432 | // `mutateElement(calls), onFinished(variable), +32 more` → the defined ones. |
| 433 | symbols: [...mark.header.matchAll(/([A-Za-z_$][\w$.]*)\(([a-z_]+)\)/g)] |
| 434 | .filter((s) => DEFINING_KINDS.has(s[2])) |
| 435 | .map((s) => ({ name: s[1], kind: s[2] })), |
| 436 | })); |
| 437 | return { envelope: files.reduce((s, f) => s + f.chars, 0), files }; |
| 438 | } |
| 439 | |
| 440 | /** |
| 441 | * How the codegraph_explore responses the agent received were DIVIDED across |
no test coverage detected