MCPcopy Index your code
hub / github.com/codeaashu/claude-code / extractFirstPromptFromChunk

Function extractFirstPromptFromChunk

src/utils/sessionStorage.ts:4818–4914  ·  view source on GitHub ↗

* Scans a chunk of text for the first meaningful user prompt.

(chunk: string)

Source from the content-addressed store, hash-verified

4816 * Scans a chunk of text for the first meaningful user prompt.
4817 */
4818function extractFirstPromptFromChunk(chunk: string): string {
4819 let start = 0
4820 let hasTickMessages = false
4821 let firstCommandFallback = ''
4822 while (start < chunk.length) {
4823 const newlineIdx = chunk.indexOf('\n', start)
4824 const line =
4825 newlineIdx >= 0 ? chunk.slice(start, newlineIdx) : chunk.slice(start)
4826 start = newlineIdx >= 0 ? newlineIdx + 1 : chunk.length
4827
4828 if (!line.includes('"type":"user"') && !line.includes('"type": "user"')) {
4829 continue
4830 }
4831 if (line.includes('"tool_result"')) continue
4832 if (line.includes('"isMeta":true') || line.includes('"isMeta": true'))
4833 continue
4834
4835 try {
4836 const entry = jsonParse(line) as Record<string, unknown>
4837 if (entry.type !== 'user') continue
4838
4839 const message = entry.message as Record<string, unknown> | undefined
4840 if (!message) continue
4841
4842 const content = message.content
4843 // Collect all text values from the message content. For array content
4844 // (common in VS Code where IDE metadata tags come before the user's
4845 // actual prompt), iterate all text blocks so we don't miss the real
4846 // prompt hidden behind <ide_selection>/<ide_opened_file> blocks.
4847 const texts: string[] = []
4848 if (typeof content === 'string') {
4849 texts.push(content)
4850 } else if (Array.isArray(content)) {
4851 for (const block of content) {
4852 const b = block as Record<string, unknown>
4853 if (b.type === 'text' && typeof b.text === 'string') {
4854 texts.push(b.text as string)
4855 }
4856 }
4857 }
4858
4859 for (const text of texts) {
4860 if (!text) continue
4861
4862 let result = text.replace(/\n/g, ' ').trim()
4863
4864 // Skip command messages (slash commands) but remember the first one
4865 // as a fallback title. Matches skip logic in
4866 // getFirstMeaningfulUserMessageTextContent, but instead of discarding
4867 // command messages entirely, we format them cleanly (e.g. "/clear")
4868 // so the session still appears in the resume picker.
4869 const commandNameTag = extractTag(result, COMMAND_NAME_TAG)
4870 if (commandNameTag) {
4871 const name = commandNameTag.replace(/^\//, '')
4872 const commandArgs = extractTag(result, 'command-args')?.trim() || ''
4873 if (builtInCommandNames().has(name) || !commandArgs) {
4874 if (!firstCommandFallback) {
4875 firstCommandFallback = commandNameTag

Callers 1

readLiteMetadataFunction · 0.85

Calls 5

jsonParseFunction · 0.85
extractTagFunction · 0.85
featureFunction · 0.85
pushMethod · 0.45
hasMethod · 0.45

Tested by

no test coverage detected