const { generateText } = require("ai");
const { google } = require('./llm')
const fs = require("fs");
const path = require("path");

const prompts = {
  system:
    "You are a JS and opensource-software specialist, going to explain some uglified JS code.",
  user: (
    code
  ) => `Here are some uglified codes. Read and answer the following questions

1. Is it part of several open source projects code you know? If it is likely, tell me the name of the open source project.
2. The purpose of the code snippet.

Response JSON Format:
{
  "ossProjects": ["$name_1", "$name_2"],
  "purpose": "$description"
}

\`\`\`
${code}
\`\`\``,
};

const chunksDir = path.resolve(__dirname, "../chunks");

(

)();

function parseMessageToJson(input) {
  // Regular expression to match JSON code blocks
  const jsonCodeBlockRegex = /```json\n([\s\S]*?)\n```/g;

  // Find all matches for JSON code blocks
  const matches = Array.from(input.matchAll(jsonCodeBlockRegex));

  if (matches.length > 1) {
    throw new Error("Multiple JSON code blocks found in the input string.");
  }

  let jsonString;

  if (matches.length === 1) {
    // Extract JSON content from the code block, trimming whitespace
    jsonString = matches[0][1].trim();
  } else {
    // No JSON code block found, use the entire input
    jsonString = input.trim();
  }

  try {
    // Parse the JSON string into an object
    return JSON.parse(jsonString);
  } catch (error) {
    throw new Error("Failed to parse JSON: " + error + "\n\n" + jsonString);
  }
}

module.exports = {
  google,
  parseMessageToJson,
  prompts
}

async () => {
  for (const chunk of fs.readdirSync(chunksDir)) {
    const mjsPath = path.resolve(chunksDir, chunk);
    if (!mjsPath.endsWith(".mjs") || chunk === 'cli.chunks.mjs') {
      continue;
    }
    const jsonPath = mjsPath.replace(".mjs", ".json");
    if (fs.existsSync(jsonPath)) {
      continue
    }
    const content = fs.readFileSync(mjsPath, "utf-8");
    const { text } = await generateText({
      model: google("gemini-2.0-flash"),
      messages: [
        {
          role: "system",
          content: prompts.system,
        },
        {
          role: "user",
          content: prompts.user(content),
        },
      ],
      maxRetries: 5
    });
    const struct = parseMessageToJson(text)
    fs.writeFileSync(jsonPath, JSON.stringify(struct, null, 2));
  }
}

const { generateText } = require("ai");
const { prompts } = require("./learn-chunks");
const { google } = require("./llm");
const fs = require("fs");
const path = require("path");
const marked = require("marked");
const { markedTerminal } = require("marked-terminal");
const readline = require("readline");

marked.use(markedTerminal());

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const mergedChunksDir = path.resolve(__dirname, "../merged-chunks");

(async () => {
  // Prompt the user for a question
  const QUESTION = await new Promise((resolve) => {
    rl.question("Enter your question about the code: ", (answer) => {
      resolve(answer);
    });
  });

  console.log(`Analyzing question: "${QUESTION}"\n`);

  let insight = "";
  let final = "";

  for (const chunk of fs.readdirSync(mergedChunksDir)) {
    if (!chunk.startsWith("improved-")) {
      continue;
    }

    console.log("Processing", chunk);

    prompts.user = (
      code
    ) => `I am analyzing a Node.JS CLI AI program called claude-code, which implements an AI coder by interacting with LLM, using tool calling, ModelContextProtocol and other functions.

The question I want to focus on now is:

<focus_question>
${QUESTION}
</focus_question>

The following is its source code fragment, which has been obfuscated by uglify. Please tell me the code logic that is directly or indirectly related to the problem I want to study.
Only answer me what you read from the code I provided.

The code logic I am more concerned about includes:

1. Its prompt design
2. Its LLM calling method
3. Other related logic

<insight_from_other_code_fragment>
${insight}
</insight_from_other_code_fragment>

<current_code_fragment>
${code}
</current_code_fragment>
\`\`\``;

    const { text } = await generateText({
      model: google("gemini-2.0-flash"),
      messages: [
        {
          role: "system",
          content: prompts.system,
        },
        {
          role: "user",
          content: prompts.user(
            fs.readFileSync(path.resolve(mergedChunksDir, chunk), "utf-8")
          ),
        },
      ],
      maxRetries: 5,
    });

    insight += `\n  <insight_from_${chunk}>
${text}
  </insight_from_${chunk}>\n`;
    final = text;
  }

  console.log(`=== Answer ===\n`);
  console.log(marked.parse(final));

  rl.close();
})();

const fs = require("fs");
const path = require("path");

const chunksDir = path.resolve(__dirname, "../chunks");
const mergedChunksDir = path.resolve(__dirname, "../merged-chunks");

const mergedIndex = {};

function manualFixNaming(project) {
  // fix LLM naming issue
  let lowerCaseProject = project.toLowerCase();

  return (
    {
      "sentry-javascript": "sentry",
      "react devtools": "react",
      "aws-sdk-js-v3": "aws-sdk",
      "@aws-sdk/signature-v4": "aws-sdk",
      "@smithy/smithy-client": "aws-sdk",
      "aws sdk for javascript": "aws-sdk",
      "statsig-js": "statsig",
      // 58
      "claude-code": "claude-code-1",
      // 59
      "langchain.js": 'claude-code-2',
      // 60
      zod: 'claude-code-3',
      // 61
      "claude code": "claude-code-4",
      // 62
      "continue code": "claude-code-5",
      tengu: "claude-code-5",
      // 64
      "@anthropic-ai/claude-code": "claude-code-6",
    }[lowerCaseProject] || lowerCaseProject
  );
}

for (const chunk of fs.readdirSync(chunksDir)) {
  const chunkPath = path.resolve(chunksDir, chunk);
  if (!chunkPath.endsWith(".json")) {
    continue;
  }

  const { ossProjects = [] } = JSON.parse(
    fs.readFileSync(chunkPath, "utf-8")
  );

  for (const prpject of ossProjects) {
    const projectName = manualFixNaming(prpject);
    mergedIndex[projectName] = mergedIndex[projectName] || [];
    mergedIndex[projectName].push(path.relative(chunksDir, chunkPath));
  }
}

for (const project in mergedIndex) {
  let content = "";
  for (const chunkPath of new Set(mergedIndex[project])) {
    content += fs.readFileSync(
      path.resolve(chunksDir, chunkPath.replace(".json", ".mjs")),
      "utf-8"
    );
  }

  fs.writeFileSync(
    path.resolve(mergedChunksDir, `${project.replaceAll("/", "__")}.mjs`),
    content
  );
}

fs.writeFileSync(
  path.resolve(mergedChunksDir, "chunks.index.json"),
  JSON.stringify(Object.keys(mergedIndex).reduce((prev, cur) => {
    for (const chunk of mergedIndex[cur]) {
      prev[chunk] = cur;
    }
    return prev;
  }, {}), null, 2)
);

const acorn = require("acorn");
const walk = require("acorn-walk");
const fs = require("fs");
const path = require("path");

const CHUNK_THRESHOLD = 100_000;
const currentChunk = {
  pathCount: 1,
  content: "",
};

const source = fs.readFileSync(
  path.resolve(__dirname, "../cli.beautify.mjs"),
  "utf-8"
);

const ast = acorn.parse(source, {
  allowHashBang: true,
  sourceType: "module",
  ecmaVersion: "latest",
});

const chunksDir = path.resolve(__dirname, "../chunks");

const chunksEntry = path.resolve(chunksDir, "cli.chunks.mjs");
fs.writeFileSync(chunksEntry, "");

// help Mac users
const namedSet = new Set();
function namer(value) {
  let count = 0;
  let newValue = `${value.toLowerCase()}_${count}`;
  while (namedSet.has(newValue)) {
    count++;
    newValue = `${value.toLowerCase()}_${count}`;
  }
  namedSet.add(newValue);
  return newValue;
}

const chunksIndex = {};

walk.fullAncestor(ast, (node, _state, ancestors) => {
  if (node.type === "Program") {
    return;
  }

  const lastAncestor = ancestors[ancestors.length - 2]; // exclude current
  if (lastAncestor.type !== "Program") {
    // only split top level
    return;
  }

  let splited = false;
  switch (node.type) {
    case "FunctionDeclaration":
      splited = writeWithCheck(getContent(node), node.id.name);
      return;
    case "ExportNamedDeclaration": {
      let exportName = node.specifiers.find((s) => s.type === "ExportSpecifier")
        .exported.name;
      splited = writeWithCheck(getContent(node), exportName);
      return;
    }
    case "VariableDeclaration":
      if (node.declarations.some((decl) => decl.id.type !== "Identifier")) {
        return;
      }
      node.declarations.forEach((decl) => {
        declSplited = writeWithCheck(getContent(decl), decl.id.name);
      });
      return;
    case "ClassDeclaration":
      splited = writeWithCheck(getContent(node), node.id.name);
      return;
    default:
  }

  if (!splited) {
    appendToEntry(node);
  }
});

// flush last chunk
fs.writeFileSync(
  path.resolve(chunksDir, `chunks.${currentChunk.pathCount}.mjs`),
  currentChunk.content
);

fs.writeFileSync(
  path.resolve(chunksDir, `chunks.index.json`),
  JSON.stringify(chunksIndex, null, 2)
);

function getContent(node) {
  return `\n// @from(${getPositionInfo(node)})\n${source.slice(
    node.start,
    node.end
  )}`;
}

function writeWithCheck(content, name) {
  const chunkPath = path.resolve(chunksDir, `chunks.${currentChunk.pathCount}.mjs`);
  if (currentChunk.content.length + content.length > CHUNK_THRESHOLD) {
    // flush
    fs.writeFileSync(chunkPath, currentChunk.content);
    currentChunk.content = "";
    currentChunk.pathCount++;
  }

  // keep small chunks inline
  // if (content.length < 2000) {
  //   return false;
  // }

  if (chunksIndex[name]) {
    throw new Error("name conflict", { name });
  }
  chunksIndex[name] = path.relative(chunksDir, chunkPath);

  currentChunk.content += content;
  return true;
}

function appendToEntry(node) {
  fs.appendFileSync(
    chunksEntry,
    `\n// @from(${getPositionInfo(node)})\n` + getContent(node) + "\n"
  );
}

function getPositionInfo(node) {
  return node.loc
    ? `Ln ${node.loc.start.line}, Col ${node.loc.start.column}`
    : `Start ${node.start}, End ${node.end}`;
}

const fs = require("fs");
const path = require("path");
const acorn = require("acorn-loose");
const walk = require("acorn-walk");

const chunksDir = path.resolve(__dirname, "../chunks");
const mergedChunksDir = path.resolve(__dirname, "../merged-chunks");
const chunksIndex = JSON.parse(
  fs.readFileSync(path.resolve(chunksDir, "chunks.index.json"), "utf-8")
);
const mergedIndex = JSON.parse(
  fs.readFileSync(path.resolve(mergedChunksDir, "chunks.index.json"), "utf-8")
);

for (const chunk of fs.readdirSync(mergedChunksDir)) {
  if (chunk.startsWith("claude-code-")) {
    const content = fs.readFileSync(
      path.resolve(mergedChunksDir, chunk),
      "utf-8"
    );

    let depsSummary =
      "/* Some variables in the code import from the following projects\n";
    const deps = {};
    for (const v of roughFindUndefinedVariables(content)) {
      if (chunksIndex[v]) {
        const project = mergedIndex[chunksIndex[v].replace(".mjs", ".json")];
        if (project.startsWith("claude-code")) {
          continue;
        }
        deps[project] = deps[project] || [];
        deps[project].push(v);
      }
    }
    for (const project in deps) {
      depsSummary += `* ${deps[project].join(
        ", "
      )} import from OSS "${project}"\n`;
    }
    depsSummary += "*/";

    fs.writeFileSync(
      path.resolve(mergedChunksDir, `improved-${chunk}`),
      `${depsSummary}\n${content}`
    );
  }
}

function roughFindUndefinedVariables(code) {
  const ast = acorn.parse(code, {
    allowHashBang: true,
    sourceType: "module",
    ecmaVersion: "latest",
  });

  const defined = new Set();
  const used = new Set();

  walk.simple(ast, {
    VariableDeclarator(node) {
      if (node.id.type === "Identifier") {
        defined.add(node.id.name);
      }
    },
    FunctionDeclaration(node) {
      if (node.id && node.id.type === "Identifier") {
        defined.add(node.id.name);
      }
    },
    ClassExpression(node) {
      if (node.id && node.id.type === "Identifier") {
        defined.add(node.id.name);
      }
    },
    Identifier(node) {
      used.add(node.name);
    },
  });

  const undefinedVars = [...used].filter((name) => !defined.has(name));
  return undefinedVars;
}

const { createGoogleGenerativeAI } = require("@ai-sdk/google");
const { fetch, ProxyAgent } = require("undici");

const dispatcher = process.env.http_proxy ? new ProxyAgent(process.env.http_proxy) : undefined;

const google = createGoogleGenerativeAI({
  fetch: async (req, options) => {
    return fetch(req, {
      ...options,
      ...(dispatcher && { dispatcher }),
    });
  },
});

module.exports = {
  google,
};

const beautify = require('js-beautify/js').js
const fs = require('fs')
const path = require('path')

const original = fs.readFileSync(path.resolve(__dirname, '../cli.mjs'), 'utf-8')

fs.writeFileSync(path.resolve(__dirname, '../cli.beautify.mjs'), beautify(original, {
  indent_size: 2,
  space_in_empty_paren: true,
}))

This code segment functions to: Automatically process code files by generating descriptive metadata through an external language model and persist the structured results for subsequent analysis.

```javascript
[TASK_BEGIN]
async () => {
  const chunkFiles = await fs.promises.readdir(chunksDir);
  const results = [];

  for (const file of chunkFiles) {
    const code = await fs.promises.readFile(path.join(chunksDir, file), "utf-8");
    const { text } = await generateText({
      model: google,
      system: prompts.system,
      prompt: prompts.user(code),
    });

    results.push(parseMessageToJson(text));
  }

  const merged = results.reduce((acc, cur) => ({
    ossProjects: [...new Set([...acc.ossProjects, ...cur.ossProjects])].sort(),
    purpose: [...acc.purpose.split('\n'), cur.purpose].filter(Boolean).join('\n')
  }), { ossProjects: [], purpose: '' });

  console.log('Analysis Results:', merged);
  return merged;
}
[TASK_END]
```


const { generateText } = require("ai");
const { google } = require('./llm')
const fs = require("fs");
const path = require("path");

const prompts = {
  system:
    "You are a JS and opensource-software specialist, going to explain some uglified JS code.",
  user: (
    code
  ) => `Here are some uglified codes. Read and answer the following questions

1. Is it part of several open source projects code you know? If it is likely, tell me the name of the open source project.
2. The purpose of the code snippet.

Response JSON Format:
{
  "ossProjects": ["$name_1", "$name_2"],
  "purpose": "$description"
}

\`\`\`
${code}
\`\`\``,
};

const chunksDir = path.resolve(__dirname, "../chunks");

(async () => {
  for (const chunk of fs.readdirSync(chunksDir)) {
    const mjsPath = path.resolve(chunksDir, chunk);
    if (!mjsPath.endsWith(".mjs") || chunk === 'cli.chunks.mjs') {
      continue;
    }

    const jsonPath = mjsPath.replace(".mjs", ".json");
    if (fs.existsSync(jsonPath)) {
      continue
    }

    const content = fs.readFileSync(mjsPath, "utf-8");

    const { text } = await generateText({
      model: google("gemini-2.0-flash"),
      messages: [
        {
          role: "system",
          content: prompts.system,
        },
        {
          role: "user",
          content: prompts.user(content),
        },
      ],
      maxRetries: 5
    });

    const struct = parseMessageToJson(text)
    fs.writeFileSync(jsonPath, JSON.stringify(struct, null, 2));
  }
})();

module.exports = {
  google,
  parseMessageToJson,
  prompts
}

function parseMessageToJson(input) {
  const jsonCodeBlockRegex = /```json\n([\s\S]*?)\n```/g;
  const matches = Array.from(input.matchAll(jsonCodeBlockRegex));
  if (matches.length > 1) {
    throw new Error("Multiple JSON code blocks found in the input string.");
  }
  let jsonString;
  if (matches.length === 1) {
    jsonString = matches[0][1].trim();
  } else {
    jsonString = input.trim();
  }
  try {
    return JSON.parse(jsonString);
  } catch (error) {
    throw new Error("Failed to parse JSON: " + error + "\n\n" + jsonString);
  }
}

This code segment functions to: Extract and validate structured data formats from text responses by locating potential code blocks, enforcing single-result constraints, and converting formatted strings into standardized data objects while providing error handling for parsing failures.

```javascript
[TASK_BEGIN]
function parseMessageToJson(input) {
  const codeBlockRegex = /```(?:json)?\n([\s\S]+?)\n```/;
  const match = input.match(codeBlockRegex);
  let jsonStr = input;

  if (match) {
    jsonStr = match[1];
  } else {
    const firstBrace = jsonStr.indexOf('{');
    const lastBrace = jsonStr.lastIndexOf('}');
    if (firstBrace !== -1 && lastBrace !== -1 && lastBrace > firstBrace) {
      jsonStr = jsonStr.slice(firstBrace, lastBrace + 1);
    }
  }

  try {
    return JSON.parse(jsonStr);
  } catch (e) {
    throw new Error(`Failed to parse JSON: ${e.message}`);
  }
}
[TASK_END]
```


const fs = require("fs");
const path = require("path");
const acorn = require("acorn-loose");
const walk = require("acorn-walk");

const chunksDir = path.resolve(__dirname, "../chunks");
const mergedChunksDir = path.resolve(__dirname, "../merged-chunks");
const chunksIndex = JSON.parse(
  fs.readFileSync(path.resolve(chunksDir, "chunks.index.json"), "utf-8")
);
const mergedIndex = JSON.parse(
  fs.readFileSync(path.resolve(mergedChunksDir, "chunks.index.json"), "utf-8")
);

for (const chunk of fs.readdirSync(mergedChunksDir)) {
  if (chunk.startsWith("claude-code-")) {
    const content = fs.readFileSync(
      path.resolve(mergedChunksDir, chunk),
      "utf-8"
    );

    let depsSummary =
      "/* Some variables in the code import from the following projects\n";
    const deps = {};
    for (const v of roughFindUndefinedVariables(content)) {
      if (chunksIndex[v]) {
        const project = mergedIndex[chunksIndex[v].replace(".mjs", ".json")];
        if (project.startsWith("claude-code")) {
          continue;
        }
        deps[project] = deps[project] || [];
        deps[project].push(v);
      }
    }
    for (const project in deps) {
      depsSummary += `* ${deps[project].join(
        ", "
      )} import from OSS "${project}"\n`;
    }
    depsSummary += "*/";

    fs.writeFileSync(
      path.resolve(mergedChunksDir, `improved-${chunk}`),
      `${depsSummary}\n${content}`
    );
  }
}

function roughFindUndefinedVariables(code) {
  const ast = acorn.parse(code, {
    allowHashBang: true,
    sourceType: "module",
    ecmaVersion: "latest",
  });
  const defined = new Set();
  const used = new Set();
  walk.simple(ast, {
    VariableDeclarator(node) {
      if (node.id.type === "Identifier") {
        defined.add(node.id.name);
      }
    },
    FunctionDeclaration(node) {
      if (node.id && node.id.type === "Identifier") {
        defined.add(node.id.name);
      }
    },
    ClassExpression(node) {
      if (node.id && node.id.type === "Identifier") {
        defined.add(node.id.name);
      }
    },
    Identifier(node) {
      used.add(node.name);
    },
  });
  const undefinedVars = [...used].filter((name) => !defined.has(name));
  return undefinedVars;
}

const { generateText } = require("ai");
const { google } = require('./llm')
const fs = require("fs");
const path = require("path");

const prompts = {
  system:
    "You are a JS and opensource-software specialist, going to explain some uglified JS code.",
  user: (
    code
  ) => `Here are some uglified codes. Read and answer the following questions

1. Is it part of several open source projects code you know? If it is likely, tell me the name of the open source project.
2. The purpose of the code snippet.

Response JSON Format:
{
  "ossProjects": ["$name_1", "$name_2"],
  "purpose": "$description"
}

\`\`\`
${code}
\`\`\``,
};

const chunksDir = path.resolve(__dirname, "../chunks");

(async () => {
  for (const chunk of fs.readdirSync(chunksDir)) {
    const mjsPath = path.resolve(chunksDir, chunk);
    if (!mjsPath.endsWith(".mjs") || chunk === 'cli.chunks.mjs') {
      continue;
    }

    const jsonPath = mjsPath.replace(".mjs", ".json");
    if (fs.existsSync(jsonPath)) {
      continue
    }

    const content = fs.readFileSync(mjsPath, "utf-8");

    const { text } = await generateText({
      model: google("gemini-2.0-flash"),
      messages: [
        {
          role: "system",
          content: prompts.system,
        },
        {
          role: "user",
          content: prompts.user(content),
        },
      ],
      maxRetries: 5
    });

    const struct = parseMessageToJson(text)
    fs.writeFileSync(jsonPath, JSON.stringify(struct, null, 2));
  }
})();

function parseMessageToJson(input) {
  // Regular expression to match JSON code blocks
  const jsonCodeBlockRegex = /```json\n([\s\S]*?)\n```/g;

  // Find all matches for JSON code blocks
  const matches = Array.from(input.matchAll(jsonCodeBlockRegex));

  if (matches.length > 1) {
    throw new Error("Multiple JSON code blocks found in the input string.");
  }

  let jsonString;

  if (matches.length === 1) {
    // Extract JSON content from the code block, trimming whitespace
    jsonString = matches[0][1].trim();
  } else {
    // No JSON code block found, use the entire input
    jsonString = input.trim();
  }

  try {
    // Parse the JSON string into an object
    return JSON.parse(jsonString);
  } catch (error) {
    throw new Error("Failed to parse JSON: " + error + "\n\n" + jsonString);
  }
}

module.exports = {
  google,
  parseMessageToJson,
  prompts
}

function roughFindUndefinedVariables (code) {}

This code segment functions to: Analyze source code syntax to detect identifiers that are referenced but not declared within the codebase, enabling identification of external dependencies through static analysis.

```javascript
[TASK_BEGIN]
function roughFindUndefinedVariables(code) {
  const declared = new Set();
  const referenced = new Set();
  const ast = acorn.parse(code, { ecmaVersion: 'latest', sourceType: 'module' });

  // Collect declarations
  walk.simple(ast, {
    VariableDeclarator(node) {
      if (node.id.type === 'Identifier') {
        declared.add(node.id.name);
      } else if (node.id.type === 'ObjectPattern') {
        node.id.properties.forEach(prop => {
          if (prop.value.type === 'Identifier') declared.add(prop.value.name);
        });
      }
    },
    FunctionDeclaration(node) {
      if (node.id) declared.add(node.id.name);
    },
    ClassDeclaration(node) {
      if (node.id) declared.add(node.id.name);
    },
    ImportDefaultSpecifier(node) {
      declared.add(node.local.name);
    },
    ImportNamespaceSpecifier(node) {
      declared.add(node.local.name);
    },
    ImportSpecifier(node) {
      declared.add(node.local.name);
    },
    Function(node) {
      node.params.forEach(param => {
        if (param.type === 'Identifier') {
          declared.add(param.name);
        } else if (param.type === 'ObjectPattern') {
          param.properties.forEach(prop => {
            if (prop.value.type === 'Identifier') declared.add(prop.value.name);
          });
        }
      });
    }
  });

  // Collect references
  walk.simple(ast, {
    Identifier(node) {
      const parent = node.parent;
      if (!parent ||
          (parent.type !== 'VariableDeclarator' || parent.id !== node) &&
          (parent.type !== 'FunctionDeclaration' || parent.id !== node) &&
          (parent.type !== 'FunctionExpression' || parent.id !== node) &&
          parent.type !== 'ImportSpecifier' &&
          parent.type !== 'ImportDefaultSpecifier' &&
          parent.type !== 'ImportNamespaceSpecifier' &&
          parent.type !== 'ClassDeclaration') {
        referenced.add(node.name);
      }
    }
  });

  const globals = new Set(['console', 'process', 'module', 'exports', 'require', 'global']);
  return [...new Set([...referenced].filter(name =>
    !declared.has(name) &&
    !globals.has(name) &&
    !name.startsWith('_')
  ))];
}
[TASK_END]
```

function roughFindUndefinedVariables(code) {
  const declared = new Set();
  const referenced = new Set();
  const ast = acorn.parse(code, { ecmaVersion: 'latest', sourceType: 'module' });
  walk.simple(ast, {
    VariableDeclarator(node) {
      if (node.id.type === 'Identifier') {
        declared.add(node.id.name);
      } else if (node.id.type === 'ObjectPattern') {
        node.id.properties.forEach(prop => {
          if (prop.value.type === 'Identifier') declared.add(prop.value.name);
        });
      }
    },
    FunctionDeclaration(node) {
      if (node.id) declared.add(node.id.name);
    },
    ClassDeclaration(node) {
      if (node.id) declared.add(node.id.name);
    },
    ImportDefaultSpecifier(node) {
      declared.add(node.local.name);
    },
    ImportNamespaceSpecifier(node) {
      declared.add(node.local.name);
    },
    ImportSpecifier(node) {
      declared.add(node.local.name);
    },
    Function(node) {
      node.params.forEach(param => {
        if (param.type === 'Identifier') {
          declared.add(param.name);
        } else if (param.type === 'ObjectPattern') {
          param.properties.forEach(prop => {
            if (prop.value.type === 'Identifier') declared.add(prop.value.name);
          });
        }
      });
    }
  });
  walk.simple(ast, {
    Identifier(node) {
      const parent = node.parent;
      if (!parent ||
          (parent.type !== 'VariableDeclarator' || parent.id !== node) &&
          (parent.type !== 'FunctionDeclaration' || parent.id !== node) &&
          (parent.type !== 'FunctionExpression' || parent.id !== node) &&
          parent.type !== 'ImportSpecifier' &&
          parent.type !== 'ImportDefaultSpecifier' &&
          parent.type !== 'ImportNamespaceSpecifier' &&
          parent.type !== 'ClassDeclaration') {
        referenced.add(node.name);
      }
    }
  });
  const globals = new Set(['console', 'process', 'module', 'exports', 'require', 'global']);
  return [...new Set([...referenced].filter(name =>
    !declared.has(name) &&
    !globals.has(name) &&
    !name.startsWith('_')
  ))];
}


This code segment functions to: Analyze source code structure to detect unresolved variable references by comparing identifier usage against declarations and return missing dependencies requiring external resolution

```javascript
[TASK_BEGIN]
function roughFindUndefinedVariables(code) {
  const ast = acorn.loose.parse(code, { ecmaVersion: 'latest', sourceType: 'module' });
  const declared = new Set();
  const referenced = new Set();

  function collectDeclaredIds(node) {
    if (!node) return;
    if (node.type === 'Identifier') {
      declared.add(node.name);
    } else if (node.type === 'ObjectPattern') {
      node.properties.forEach(prop => {
        if (prop.type === 'Property') collectDeclaredIds(prop.value);
        else if (prop.type === 'RestElement') collectDeclaredIds(prop.argument);
      });
    } else if (node.type === 'ArrayPattern') {
      node.elements.forEach(element => element && collectDeclaredIds(element));
    } else if (node.type === 'RestElement') {
      collectDeclaredIds(node.argument);
    } else if (node.type === 'AssignmentPattern') {
      collectDeclaredIds(node.left);
    }
  }

  walk.simple(ast, {
    VariableDeclarator(node) { collectDeclaredIds(node.id) },
    FunctionDeclaration(node) {
      if (node.id) declared.add(node.id.name);
      node.params.forEach(collectDeclaredIds);
    },
    FunctionExpression(node) {
      if (node.id) declared.add(node.id.name);
      node.params.forEach(collectDeclaredIds);
    },
    ArrowFunctionExpression(node) { node.params.forEach(collectDeclaredIds) },
    ClassDeclaration(node) { node.id && declared.add(node.id.name) },
    CatchClause(node) { node.param && collectDeclaredIds(node.param) }
  });

  walk.simple(ast, {
    Identifier(node) {
      if (declared.has(node.name)) return;
      const parent = node.parent;
      const isPropertyKey = parent.type === 'Property' && parent.key === node && !parent.computed;
      const isMemberProp = parent.type === 'MemberExpression' && parent.property === node && !parent.computed;
      if (!isPropertyKey && !isMemberProp) referenced.add(node.name);
    }
  });

  return Array.from(referenced);
}
[TASK_END]
```


This code segment functions to: Analyze source code to detect undeclared variable references by comparing identifier usage against defined declarations, identifying external dependencies through unresolved symbols.

```javascript
[TASK_BEGIN]
function roughFindUndefinedVariables(code) {
  const ast = acorn.parse(code, { ecmaVersion: 'latest', sourceType: 'module' });
  const declared = new Set();
  const knownGlobals = new Set(['require', 'module', 'exports', 'console', 'process', 'global', '__dirname', '__filename']);

  // Collect declared identifiers from various patterns
  function collectFromPattern(pattern) {
    if (!pattern) return;
    switch (pattern.type) {
      case 'Identifier':
        declared.add(pattern.name);
        break;
      case 'ObjectPattern':
        pattern.properties.forEach(prop => {
          if (prop.type === 'Property') collectFromPattern(prop.value);
          else if (prop.type === 'RestElement') collectFromPattern(prop.argument);
        });
        break;
      case 'ArrayPattern':
        pattern.elements.forEach(el => el && collectFromPattern(el));
        break;
      case 'AssignmentPattern':
        collectFromPattern(pattern.left);
        break;
      case 'RestElement':
        collectFromPattern(pattern.argument);
        break;
    }
  }

  // First pass: collect all declared variables
  walk.ancestor(ast, {
    VariableDeclarator(node) { collectFromPattern(node.id) },
    FunctionDeclaration(node) {
      if (node.id) declared.add(node.id.name);
      node.params.forEach(p => collectFromPattern(p));
    },
    FunctionExpression(node) {
      if (node.id) declared.add(node.id.name);
      node.params.forEach(p => collectFromPattern(p));
    },
    ArrowFunctionExpression(node) {
      node.params.forEach(p => collectFromPattern(p));
    },
    ClassDeclaration(node) { node.id && declared.add(node.id.name) },
    CatchClause(node) { collectFromPattern(node.param) },
    ForInStatement(node) { node.left.type === 'VariableDeclaration' && node.left.declarations.forEach(d => collectFromPattern(d.id)) },
    ForOfStatement(node) { node.left.type === 'VariableDeclaration' && node.left.declarations.forEach(d => collectFromPattern(d.id)) }
  });

  // Second pass: find undefined references
  const undefinedVars = new Set();
  walk.simple(ast, {
    Identifier(node) {
      if (declared.has(node.name) || knownGlobals.has(node.name)) return;
      if (node.parent.type === 'MemberExpression' && node.parent.object === node) return;
      if (node.parent.type === 'Property' && node.parent.key === node) return;
      if (node.parent.type === 'MethodDefinition') return;

      undefinedVars.add(node.name);
    }
  });

  return Array.from(undefinedVars);
}
[TASK_END]
```

function roughFindUndefinedVariables(code) {
  const ast = acorn.parse(code, { ecmaVersion: 'latest', sourceType: 'module' });
  const declared = new Set();
  const knownGlobals = new Set(['require', 'module', 'exports', 'console', 'process', 'global', '__dirname', '__filename']);
  function collectFromPattern(pattern) {
    if (!pattern) return;
    switch (pattern.type) {
      case 'Identifier':
        declared.add(pattern.name);
        break;
      case 'ObjectPattern':
        pattern.properties.forEach(prop => {
          if (prop.type === 'Property') collectFromPattern(prop.value);
          else if (prop.type === 'RestElement') collectFromPattern(prop.argument);
        });
        break;
      case 'ArrayPattern':
        pattern.elements.forEach(el => el && collectFromPattern(el));
        break;
      case 'AssignmentPattern':
        collectFromPattern(pattern.left);
        break;
      case 'RestElement':
        collectFromPattern(pattern.argument);
        break;
    }
  }
  walk.ancestor(ast, {
    VariableDeclarator(node) { collectFromPattern(node.id) },
    FunctionDeclaration(node) {
      if (node.id) declared.add(node.id.name);
      node.params.forEach(p => collectFromPattern(p));
    },
    FunctionExpression(node) {
      if (node.id) declared.add(node.id.name);
      node.params.forEach(p => collectFromPattern(p));
    },
    ArrowFunctionExpression(node) {
      node.params.forEach(p => collectFromPattern(p));
    },
    ClassDeclaration(node) { node.id && declared.add(node.id.name) },
    CatchClause(node) { collectFromPattern(node.param) },
    ForInStatement(node) { node.left.type === 'VariableDeclaration' && node.left.declarations.forEach(d => collectFromPattern(d.id)) },
    ForOfStatement(node) { node.left.type === 'VariableDeclaration' && node.left.declarations.forEach(d => collectFromPattern(d.id)) }
  });
  const undefinedVars = new Set();
  walk.simple(ast, {
    Identifier(node) {
      if (declared.has(node.name) || knownGlobals.has(node.name)) return;
      if (node.parent.type === 'MemberExpression' && node.parent.object === node) return;
      if (node.parent.type === 'Property' && node.parent.key === node) return;
      if (node.parent.type === 'MethodDefinition') return;
      undefinedVars.add(node.name);
    }
  });
  return Array.from(undefinedVars);
}