Home / Function/ run() — dead-code-hunter Function Reference

run() — dead-code-hunter Function Reference

Architecture documentation for the run() function in index.ts from the dead-code-hunter codebase.

Entity Profile

Dependency Diagram

graph TD
  917645bc_a477_1891_eaae_c95a41b4031a["run()"]
  9f178763_0bb8_a0fb_e74f_8f045fcb3e5c["installCLI()"]
  917645bc_a477_1891_eaae_c95a41b4031a -->|calls| 9f178763_0bb8_a0fb_e74f_8f045fcb3e5c
  c840aa7b_dcc9_0fa9_89ea_de60634d0c88["runDeadCodeAnalysis()"]
  917645bc_a477_1891_eaae_c95a41b4031a -->|calls| c840aa7b_dcc9_0fa9_89ea_de60634d0c88
  b53a8fb0_a278_54c1_9544_2fcf2644a178["getChangedFiles()"]
  917645bc_a477_1891_eaae_c95a41b4031a -->|calls| b53a8fb0_a278_54c1_9544_2fcf2644a178
  4f161eb4_4651_9ff9_7813_a4e91911a4ca["filterByChangedFiles()"]
  917645bc_a477_1891_eaae_c95a41b4031a -->|calls| 4f161eb4_4651_9ff9_7813_a4e91911a4ca
  2e909b04_bb6e_a3ab_d740_ab5e4292de6d["formatPrComment()"]
  917645bc_a477_1891_eaae_c95a41b4031a -->|calls| 2e909b04_bb6e_a3ab_d740_ab5e4292de6d
  style 917645bc_a477_1891_eaae_c95a41b4031a fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

src/index.ts lines 84–203

async function run(): Promise<void> {
  try {
    const apiKey = core.getInput('supermodel-api-key', { required: true }).trim();

    if (!apiKey.startsWith('smsk_')) {
      core.warning('API key format looks incorrect. Get your key at https://dashboard.supermodeltools.com');
    }

    const commentOnPr = core.getBooleanInput('comment-on-pr');
    const failOnDeadCode = core.getBooleanInput('fail-on-dead-code');
    const ignorePatterns: string[] = JSON.parse(core.getInput('ignore-patterns') || '[]');
    const minConfidence = core.getInput('min-confidence') || '';
    const timeoutSeconds = parseInt(core.getInput('timeout-seconds') || '7200', 10);
    const cliVersion = core.getInput('cli-version') || 'latest';

    // Step 1: Install the Supermodel CLI
    await installCLI(cliVersion);

    // Step 2: Run dead code analysis via CLI
    core.info('Analyzing codebase with Supermodel...');
    const result = await runDeadCodeAnalysis({
      apiKey,
      minConfidence,
      ignorePatterns,
      timeoutSeconds,
    });

    let candidates = result.deadCodeCandidates;

    // Step 3: Scope to PR diff when running on a pull request
    const token = core.getInput('github-token') || process.env.GITHUB_TOKEN;
    let changedFiles: Set<string> | null = null;

    if (github.context.payload.pull_request && token) {
      changedFiles = await getChangedFiles(token);
      if (changedFiles) {
        const totalBeforeScoping = candidates.length;
        candidates = filterByChangedFiles(candidates, changedFiles);
        core.info(`Scoped to PR: ${candidates.length} findings in changed files (${totalBeforeScoping} total across repo, ${changedFiles.size} files in PR)`);
      }
    }

    core.info(`Found ${candidates.length} potentially unused code elements (${result.metadata.totalDeclarations} declarations analyzed)`);
    core.info(`Analysis method: ${result.metadata.analysisMethod}`);
    core.info(`Alive: ${result.metadata.aliveCode}, Entry points: ${result.entryPoints.length}`);
    for (const dc of candidates) {
      core.info(`  [${dc.confidence}] ${dc.type} ${dc.name} @ ${dc.file}:${dc.line} — ${dc.reason}`);
    }

    // Step 4: Set outputs
    core.setOutput('dead-code-count', candidates.length);
    core.setOutput('dead-code-json', JSON.stringify(candidates));

    // Step 5: Post PR comment if enabled
    if (commentOnPr && github.context.payload.pull_request) {
      if (token) {
        const octokit = github.getOctokit(token);
        const comment = formatPrComment(candidates, result.metadata);

        await octokit.rest.issues.createComment({
          owner: github.context.repo.owner,
          repo: github.context.repo.repo,
          issue_number: github.context.payload.pull_request.number,
          body: comment,
        });

        core.info('Posted findings to PR');
      } else {
        core.warning('GITHUB_TOKEN not available, skipping PR comment');
      }
    }

    // Step 6: Fail if configured and dead code found
    if (candidates.length > 0 && failOnDeadCode) {
      core.setFailed(`Found ${candidates.length} potentially unused code elements`);
    }

  } catch (error: unknown) {
    let message = 'An unknown error occurred';

    if (error instanceof SyntaxError) {
      message = 'Failed to parse CLI output as JSON. Make sure the Supermodel CLI installed correctly.';
      core.error(message);
      core.debug(`Parse error: ${error.message}`);
    } else if (error instanceof Error) {
      const msg = error.message;
      core.debug(`Error: ${msg}`);

      if (msg.includes('not authenticated') || msg.includes('SUPERMODEL_API_KEY')) {
        message = 'Invalid or missing API key';
        core.error(`${message}. Get your key at https://dashboard.supermodeltools.com`);
      } else if (msg.includes('timed out') || msg.includes('ETIMEDOUT')) {
        message = `Analysis timed out. Increase timeout-seconds (current: ${core.getInput('timeout-seconds')})`;
        core.error(message);
      } else if (msg.includes('API error 401')) {
        message = 'Invalid API key';
        core.error(`${message}. Get your key at https://dashboard.supermodeltools.com`);
      } else if (msg.includes('API error 413')) {
        message = 'Repository archive too large';
        core.error(`${message}. Exclude large files using .gitattributes with export-ignore.`);
      } else if (msg.includes('API error 429')) {
        message = 'Rate limit exceeded. Please wait before retrying.';
        core.error(message);
      } else if (msg.includes('Nested archives')) {
        message = 'Repository contains nested archive files';
        core.error(`${message}. Add them to .gitattributes with "export-ignore".`);
      } else if (msg.includes('exceeds maximum')) {
        message = 'Repository or file exceeds size limits';
        core.error(`${message}. Exclude large files using .gitattributes with export-ignore.`);
      } else {
        message = msg;
        core.error(message);
      }
    } else {
      core.error(String(error));
    }

    core.setFailed(message);
  }
}

Domain

Subdomains

Frequently Asked Questions

What does run() do?
run() is a function in the dead-code-hunter codebase.
What does run() call?
run() calls 5 function(s): filterByChangedFiles, formatPrComment, getChangedFiles, installCLI, runDeadCodeAnalysis.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free