hiregraph 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +147 -0
- package/dist/data/companies.json +65 -0
- package/dist/index.js +3282 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -0
- package/src/data/companies.json +65 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/storage/store.ts","../src/resume/parser.ts","../src/llm/client.ts","../src/graph/schema.ts","../src/graph/skill-graph.ts","../src/utils/logger.ts","../src/utils/spinner.ts","../src/commands/scan.ts","../src/layers/file-discovery.ts","../src/utils/gitignore.ts","../src/utils/language-map.ts","../src/layers/dependency-extraction.ts","../src/layers/ast-analysis.ts","../src/layers/git-forensics.ts","../src/layers/quality-signals.ts","../src/layers/architecture-patterns.ts","../src/layers/llm-classification.ts","../src/commands/status.ts","../src/commands/jobs.ts","../src/ats/registry.ts","../src/ats/greenhouse.ts","../src/ats/lever.ts","../src/ats/ashby.ts","../src/ats/normalizer.ts","../src/ats/fetcher.ts","../src/commands/matches.ts","../src/matching/job-parser.ts","../src/matching/vectorizer.ts","../src/matching/similarity.ts","../src/matching/filters.ts","../src/matching/evaluator.ts","../src/matching/matcher.ts","../src/commands/apply.ts","../src/history/tracker.ts","../src/resume/tailorer.ts","../src/resume/pdf-builder.ts","../src/ats/submitter.ts","../src/commands/history.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { initCommand } from './commands/init.js';\nimport { scanCommand } from './commands/scan.js';\nimport { statusCommand } from './commands/status.js';\nimport { jobsCommand } from './commands/jobs.js';\nimport { matchesCommand } from './commands/matches.js';\nimport { applyCommand } from './commands/apply.js';\nimport { historyCommand } from './commands/history.js';\n\nconst program = new Command();\n\nprogram\n .name('hiregraph')\n .description('Turn your code into job applications. Local-first CLI that scans codebases and builds skill graphs.')\n .version('0.1.0');\n\nprogram\n .command('init')\n .description('Set up your builder profile (resume upload + preferences)')\n .action(initCommand);\n\nprogram\n .command('scan')\n .description('Scan a project and update your skill graph')\n .argument('[path]', 'Path to the project directory', '.')\n .action(scanCommand);\n\nprogram\n .command('status')\n .description('Show your current skill graph summary')\n .action(statusCommand);\n\nprogram\n .command('jobs')\n .description('Fetch job listings from Greenhouse, Lever, and Ashby boards')\n .option('--refresh', 'Force refresh cached jobs')\n .option('--ats <type>', 'Filter by ATS type (greenhouse, lever, ashby)')\n .option('--limit <n>', 'Show sample of N job titles', parseInt)\n .action(jobsCommand);\n\nprogram\n .command('matches')\n .description('Match your skill graph against fetched jobs')\n .option('--refresh', 'Re-fetch jobs before matching')\n .option('--top <n>', 'Number of candidates for LLM evaluation (default 50)', parseInt)\n .option('--verbose', 'Show detailed reasoning for all matches')\n .action(matchesCommand);\n\nprogram\n .command('apply')\n .description('Generate a tailored resume and submit to ATS')\n .argument('[job-id]', 'Job ID to apply to')\n .option('--all-above <score>', 'Apply to all matches above this score', parseFloat)\n .option('--review', 'Review each resume before submitting')\n .option('--dry-run', 'Generate resume PDF without submitting')\n .action(applyCommand);\n\nprogram\n .command('history')\n .description('View and manage your application history')\n .argument('[action]', 'Action: \"update\"')\n .argument('[id]', 'Application ID')\n .option('--status <status>', 'New status (applied, screening, interview, offer, rejected, withdrawn, no-response)')\n .option('--notes <notes>', 'Optional notes')\n .action(historyCommand);\n\nprogram.parse();\n","import inquirer from 'inquirer';\nimport { existsSync } from 'fs';\nimport { resolve } from 'path';\nimport { saveJson, loadJson } from '../storage/store.js';\nimport { parseResume, resumeToIdentity } from '../resume/parser.js';\nimport { createEmptySkillGraph } from '../graph/schema.js';\nimport { saveGraph } from '../graph/skill-graph.js';\nimport { isApiKeyConfigured } from '../llm/client.js';\nimport * as log from '../utils/logger.js';\nimport * as spinner from '../utils/spinner.js';\nimport type { BuilderIdentity, IdentityConfig } from '../graph/schema.js';\n\nconst ROLE_CHOICES = [\n { name: 'Engineer', value: 'engineer' },\n { name: 'PM', value: 'pm' },\n { name: 'Designer', value: 'designer' },\n { name: 'Founder', value: 'founder' },\n { name: 'Builder', value: 'builder' },\n];\n\nexport async function initCommand(): Promise<void> {\n log.header('\\n HireGraph Init\\n');\n\n // Check if already initialized\n const existing = await loadJson<IdentityConfig>('identity.json');\n if (existing) {\n const { overwrite } = await inquirer.prompt([{\n type: 'confirm',\n name: 'overwrite',\n message: 'Profile already exists. Overwrite?',\n default: false,\n }]);\n if (!overwrite) {\n log.info('Keeping existing profile.');\n return;\n }\n }\n\n // Basic info\n const { name, email } = await inquirer.prompt([\n { type: 'input', name: 'name', message: 'Name:' },\n { type: 'input', name: 'email', message: 'Email:' },\n ]);\n\n // Resume upload\n let resumeData: Awaited<ReturnType<typeof parseResume>> | null = null;\n\n const { hasResume } = await inquirer.prompt([{\n type: 'confirm',\n name: 'hasResume',\n message: 'Do you have an existing resume? (PDF/TXT)',\n default: true,\n }]);\n\n if (hasResume) {\n if (!isApiKeyConfigured()) {\n log.warn('No API key detected. Run inside Claude Code for resume parsing. Using manual flow.');\n } else {\n const { resumePath } = await inquirer.prompt([{\n type: 'input',\n name: 'resumePath',\n message: 'Path to resume:',\n }]);\n\n const resolved = resolve(resumePath.trim().replace(/^[\"']|[\"']$/g, ''));\n if (existsSync(resolved)) {\n spinner.start('Parsing resume...');\n try {\n resumeData = await parseResume(resolved);\n spinner.succeed('Resume parsed');\n log.info(` Name: ${resumeData.name}`);\n log.info(` Email: ${resumeData.email}`);\n if (resumeData.work_history.length > 0) {\n log.info(' Work History:');\n for (const w of resumeData.work_history) {\n log.info(` ${w.role} @ ${w.company} (${w.start_year}-${w.end_year || 'present'})`);\n }\n }\n if (resumeData.skills.length > 0) {\n log.info(` Skills: ${resumeData.skills.join(', ')}`);\n }\n\n const { looksRight } = await inquirer.prompt([{\n type: 'confirm',\n name: 'looksRight',\n message: 'Look right?',\n default: true,\n }]);\n if (!looksRight) {\n log.info('Resume data discarded. Using manual input.');\n resumeData = null;\n }\n } catch (err: any) {\n spinner.fail('Failed to parse resume');\n log.error(err.message);\n resumeData = null;\n }\n } else {\n log.warn('File not found. Continuing without resume.');\n }\n }\n }\n\n // Role and preferences\n const { role } = await inquirer.prompt([{\n type: 'list',\n name: 'role',\n message: 'What describes you best?',\n choices: ROLE_CHOICES,\n }]);\n\n const { targetRoles } = await inquirer.prompt([{\n type: 'input',\n name: 'targetRoles',\n message: 'Target roles (comma separated):',\n default: 'Founding Engineer, Full-Stack Engineer',\n }]);\n\n const { remotePref } = await inquirer.prompt([{\n type: 'list',\n name: 'remotePref',\n message: 'Remote preference?',\n choices: ['Remote', 'Hybrid', 'Onsite', 'No preference'],\n }]);\n\n const { minComp } = await inquirer.prompt([{\n type: 'input',\n name: 'minComp',\n message: 'Min compensation (optional):',\n default: '',\n }]);\n\n // Build identity\n const targets = targetRoles.split(',').map((r: string) => r.trim()).filter(Boolean);\n\n const identity: BuilderIdentity = resumeData\n ? resumeToIdentity(resumeData, role, targets, remotePref, minComp)\n : {\n name,\n email,\n primary_role: role,\n target_roles: targets,\n remote_preference: remotePref,\n min_compensation: minComp,\n previous_companies: [],\n education: [],\n links: {},\n source: 'manual',\n };\n\n // Override name/email if provided manually and resume had different\n if (name) identity.name = name;\n if (email) identity.email = email;\n\n // Save\n await saveJson('identity.json', identity);\n await saveJson('config.json', { excluded_companies: [], auto_apply_threshold: 8 });\n\n // Create empty skill graph\n const graph = createEmptySkillGraph(identity);\n await saveGraph(graph);\n\n log.success('\\nProfile saved to ~/.hiregraph/identity.json');\n log.info('Run `hiregraph scan <path>` to analyze your first project.');\n}\n","import { homedir } from 'os';\nimport { join } from 'path';\nimport { mkdir, readFile, writeFile } from 'fs/promises';\nimport { existsSync } from 'fs';\n\nconst HIREGRAPH_DIR = join(homedir(), '.hiregraph');\n\nexport async function ensureDir(): Promise<void> {\n if (!existsSync(HIREGRAPH_DIR)) {\n await mkdir(HIREGRAPH_DIR, { recursive: true });\n }\n}\n\nexport function getPath(filename: string): string {\n return join(HIREGRAPH_DIR, filename);\n}\n\nexport async function loadJson<T>(filename: string): Promise<T | null> {\n const filepath = getPath(filename);\n if (!existsSync(filepath)) return null;\n const raw = await readFile(filepath, 'utf-8');\n return JSON.parse(raw) as T;\n}\n\nexport async function saveJson(filename: string, data: unknown): Promise<void> {\n await ensureDir();\n const filepath = getPath(filename);\n await writeFile(filepath, JSON.stringify(data, null, 2), 'utf-8');\n}\n\nexport async function ensureSubDir(subdir: string): Promise<void> {\n const dirPath = join(HIREGRAPH_DIR, subdir);\n if (!existsSync(dirPath)) {\n await mkdir(dirPath, { recursive: true });\n }\n}\n\nexport async function loadSubJson<T>(subdir: string, filename: string): Promise<T | null> {\n await ensureSubDir(subdir);\n const filepath = join(HIREGRAPH_DIR, subdir, filename);\n if (!existsSync(filepath)) return null;\n const raw = await readFile(filepath, 'utf-8');\n return JSON.parse(raw) as T;\n}\n\nexport async function saveSubJson(subdir: string, filename: string, data: unknown): Promise<void> {\n await ensureSubDir(subdir);\n const filepath = join(HIREGRAPH_DIR, subdir, filename);\n await writeFile(filepath, JSON.stringify(data, null, 2), 'utf-8');\n}\n","import { readFile } from 'fs/promises';\nimport { extname } from 'path';\nimport { callHaiku, isApiKeyConfigured } from '../llm/client.js';\nimport type { BuilderIdentity, WorkHistory, Education } from '../graph/schema.js';\n\nconst SYSTEM_PROMPT = `You extract structured data from resume text.\nReturn JSON only, no markdown fences. Schema:\n{\n \"name\": \"string\",\n \"email\": \"string\",\n \"phone\": \"string or null\",\n \"links\": { \"github\": \"url\", \"linkedin\": \"url\", \"portfolio\": \"url\" },\n \"work_history\": [{ \"company\": \"string\", \"role\": \"string\", \"start_year\": number, \"end_year\": number|null }],\n \"skills\": [\"string array\"],\n \"education\": [{ \"institution\": \"string\", \"degree\": \"string\", \"field\": \"string\", \"year\": number }]\n}`;\n\nexport interface ParsedResume {\n name: string;\n email: string;\n phone?: string;\n links: Record<string, string>;\n work_history: WorkHistory[];\n skills: string[];\n education: Education[];\n}\n\nexport async function parseResume(filePath: string): Promise<ParsedResume> {\n const ext = extname(filePath).toLowerCase();\n let text: string;\n\n if (ext === '.pdf') {\n // Dynamic import for pdf-parse\n const pdfParse = (await import('pdf-parse')).default;\n const buffer = await readFile(filePath);\n const data = await pdfParse(buffer);\n text = data.text;\n } else if (ext === '.txt' || ext === '.md') {\n text = await readFile(filePath, 'utf-8');\n } else {\n throw new Error(`Unsupported resume format: ${ext}. Supported: .pdf, .txt, .md`);\n }\n\n if (!isApiKeyConfigured()) {\n throw new Error('No API key detected. Run hiregraph inside Claude Code or Cursor for resume parsing.');\n }\n\n const response = await callHaiku(SYSTEM_PROMPT, `Extract structured data from this resume:\\n\\n${text}`);\n const cleaned = response.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n const parsed = JSON.parse(cleaned);\n\n return {\n name: parsed.name || '',\n email: parsed.email || '',\n phone: parsed.phone || undefined,\n links: parsed.links || {},\n work_history: (parsed.work_history || []).map((w: any) => ({\n company: w.company || '',\n role: w.role || '',\n start_year: w.start_year || 0,\n end_year: w.end_year || undefined,\n })),\n skills: parsed.skills || [],\n education: (parsed.education || []).map((e: any) => ({\n institution: e.institution || '',\n degree: e.degree || '',\n field: e.field || '',\n year: e.year || 0,\n })),\n };\n}\n\nexport function resumeToIdentity(parsed: ParsedResume, role: string, targetRoles: string[], remotePref: string, minComp: string): BuilderIdentity {\n return {\n name: parsed.name,\n email: parsed.email,\n phone: parsed.phone,\n primary_role: role,\n target_roles: targetRoles,\n remote_preference: remotePref,\n min_compensation: minComp,\n previous_companies: parsed.work_history,\n education: parsed.education,\n links: parsed.links,\n source: 'resume-upload',\n };\n}\n","import Anthropic from '@anthropic-ai/sdk';\n\nlet client: Anthropic | null = null;\n\nexport function isApiKeyConfigured(): boolean {\n return !!process.env.ANTHROPIC_API_KEY;\n}\n\nfunction getClient(): Anthropic {\n if (!client) {\n // ANTHROPIC_API_KEY is auto-detected by the SDK from process.env.\n // Claude Code / Cursor users already have this set — zero config needed.\n client = new Anthropic();\n }\n return client;\n}\n\nexport async function callHaiku(\n systemPrompt: string,\n userPrompt: string\n): Promise<string> {\n const anthropic = getClient();\n\n const message = await anthropic.messages.create({\n model: 'claude-haiku-4-5-20251001',\n max_tokens: 1024,\n system: systemPrompt,\n messages: [{ role: 'user', content: userPrompt }],\n });\n\n const block = message.content[0];\n if (block.type === 'text') {\n return block.text;\n }\n throw new Error('Unexpected response format from Haiku');\n}\n\nexport async function callHaikuJson<T>(\n systemPrompt: string,\n userPrompt: string,\n maxTokens = 1024,\n): Promise<T> {\n const anthropic = getClient();\n\n const message = await anthropic.messages.create({\n model: 'claude-haiku-4-5-20251001',\n max_tokens: maxTokens,\n system: systemPrompt,\n messages: [{ role: 'user', content: userPrompt }],\n });\n\n const block = message.content[0];\n if (block.type !== 'text') throw new Error('Unexpected response format from Haiku');\n\n const cleaned = block.text.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n return JSON.parse(cleaned) as T;\n}\n","// === Skill Graph (persisted to ~/.hiregraph/skill-graph.json) ===\n\nexport interface SkillGraph {\n builder_identity: BuilderIdentity;\n tech_stack: Record<string, TechSkill>;\n architecture: Record<string, { confidence: number }>;\n quality: QualityMetrics;\n projects: ProjectEntry[];\n builder_profile: BuilderProfile;\n last_updated: string;\n}\n\nexport interface BuilderIdentity {\n name: string;\n email: string;\n phone?: string;\n primary_role: string;\n target_roles: string[];\n remote_preference?: string;\n min_compensation?: string;\n years_in_role?: number;\n previous_companies: WorkHistory[];\n education: Education[];\n links: Record<string, string>;\n source: 'resume-upload' | 'manual';\n}\n\nexport interface WorkHistory {\n company: string;\n role: string;\n start_year: number;\n end_year?: number;\n bullets?: string[];\n}\n\nexport interface Education {\n institution: string;\n degree: string;\n field: string;\n year: number;\n}\n\nexport interface TechSkill {\n proficiency: number;\n source: 'code-verified' | 'self-reported';\n loc: number;\n projects: number;\n advanced_features: string[];\n last_seen: string;\n}\n\nexport interface QualityMetrics {\n test_ratio: number;\n complexity_avg: number;\n type_safety: boolean;\n secrets_clean: boolean;\n}\n\nexport interface BuilderProfile {\n is_end_to_end: boolean;\n role_signals: string[];\n}\n\nexport interface ProjectEntry {\n name: string;\n path: string;\n domain: string;\n stack: string[];\n languages: Record<string, { files: number; loc: number }>;\n commits: number;\n active_days: number;\n contributors: number;\n test_ratio: number;\n complexity_avg: number;\n patterns: Record<string, number>;\n description: string;\n scanned_at: string;\n}\n\n// === Per-Layer Result Types ===\n\nexport interface FileDiscoveryResult {\n total_files: number;\n total_loc: number;\n languages: Record<string, { files: number; loc: number }>;\n config_files: string[];\n primary_language: string;\n}\n\nexport interface DependencyResult {\n ecosystem: string;\n dependencies: string[];\n dev_dependencies: string[];\n frameworks: string[];\n has_lockfile: boolean;\n}\n\nexport interface AstAnalysisResult {\n functions: number;\n classes: number;\n interfaces: number;\n components: number;\n hooks: number;\n services: number;\n max_nesting_depth: number;\n avg_params_per_function: number;\n imports_used: string[];\n advanced_features: string[];\n}\n\nexport interface GitForensicsResult {\n is_git_repo: boolean;\n commits: number;\n active_days: number;\n contributors: number;\n commits_per_active_day: number;\n active_days_per_week: number;\n first_commit: string;\n last_commit: string;\n conventional_commit_ratio: number;\n branches: number;\n primary_author: string;\n}\n\nexport interface QualitySignalsResult {\n test_ratio: number;\n complexity_avg: number;\n type_safety: boolean;\n type_safety_details: string;\n secrets_clean: boolean;\n secrets_found: number;\n lint_tools: string[];\n}\n\nexport interface ArchitecturePatternsResult {\n patterns: Record<string, number>;\n primary_pattern: string | null;\n}\n\nexport interface LlmClassificationResult {\n domain: string;\n builder_profile: string;\n role_signals: string[];\n is_end_to_end: boolean;\n description: string;\n}\n\n// === Aggregated Scan Result ===\n\nexport interface ScanResult {\n project_name: string;\n project_path: string;\n file_discovery: FileDiscoveryResult;\n dependencies: DependencyResult;\n ast_analysis: AstAnalysisResult;\n git_forensics: GitForensicsResult;\n quality_signals: QualitySignalsResult;\n architecture_patterns: ArchitecturePatternsResult;\n llm_classification: LlmClassificationResult | null;\n}\n\n// === Identity (persisted to ~/.hiregraph/identity.json) ===\n\nexport interface IdentityConfig {\n name: string;\n email: string;\n phone?: string;\n primary_role: string;\n target_roles: string[];\n remote_preference: string;\n min_compensation: string;\n previous_companies: WorkHistory[];\n education: Education[];\n links: Record<string, string>;\n skills: string[];\n source: 'resume-upload' | 'manual';\n}\n\n// === Phase 1B: Job Fetching + Matching ===\n\nexport interface CompanyRegistryEntry {\n name: string;\n slug: string;\n ats: 'greenhouse' | 'lever' | 'ashby';\n board_token: string;\n domain?: string;\n size?: 'startup' | 'growth' | 'enterprise';\n hq_location?: string;\n tags?: string[];\n}\n\nexport interface JobListing {\n id: string;\n source: 'greenhouse' | 'lever' | 'ashby';\n company: string;\n company_slug: string;\n title: string;\n url: string;\n location: string;\n department?: string;\n description_raw: string;\n posted_at?: string;\n updated_at?: string;\n fetched_at: string;\n}\n\nexport interface ParsedJobRequirements {\n job_id: string;\n must_have_skills: string[];\n nice_to_have_skills: string[];\n seniority_level: string;\n tech_stack: string[];\n domain: string;\n remote_policy: 'remote' | 'hybrid' | 'onsite' | 'unknown';\n compensation_range?: { min?: number; max?: number; currency?: string };\n parsed_at: string;\n}\n\nexport interface MatchResult {\n job_id: string;\n job_title: string;\n company: string;\n company_slug: string;\n url: string;\n score: number;\n confidence: number;\n tier: 'strong' | 'suggested' | 'filtered';\n reasoning: string;\n strengths: string[];\n gaps: string[];\n matched_at: string;\n}\n\nexport interface MatchRun {\n date: string;\n total_jobs_fetched: number;\n total_jobs_parsed: number;\n total_candidates_evaluated: number;\n strong_matches: MatchResult[];\n suggested_matches: MatchResult[];\n run_at: string;\n cost_estimate: { jobs_parsed: number; pairs_evaluated: number; estimated_usd: number };\n}\n\nexport interface JobsCache {\n source: 'greenhouse' | 'lever' | 'ashby';\n fetched_at: string;\n companies_fetched: number;\n total_jobs: number;\n jobs: JobListing[];\n}\n\nexport interface ParsedJobsCache {\n parsed_at: string;\n requirements: Record<string, ParsedJobRequirements>;\n}\n\n// === Phase 1C: Resume Generation + Application Tracking ===\n\nexport interface ResumeTailoring {\n job_id: string;\n professional_summary: string;\n project_order: string[];\n bullet_emphasis: Record<string, string[]>;\n skills_order: string[];\n generated_at: string;\n}\n\nexport type ApplicationStatus =\n | 'applied'\n | 'screening'\n | 'interview'\n | 'offer'\n | 'rejected'\n | 'withdrawn'\n | 'no-response';\n\nexport interface ApplicationRecord {\n id: string;\n job_id: string;\n job_title: string;\n company: string;\n company_slug: string;\n url: string;\n ats_source: 'greenhouse' | 'lever' | 'ashby';\n match_score: number;\n resume_path: string;\n status: ApplicationStatus;\n applied_at: string;\n updated_at: string;\n notes?: string;\n}\n\nexport interface ApplicationHistory {\n applications: ApplicationRecord[];\n last_updated: string;\n}\n\nexport function createEmptySkillGraph(identity: BuilderIdentity): SkillGraph {\n return {\n builder_identity: identity,\n tech_stack: {},\n architecture: {},\n quality: {\n test_ratio: 0,\n complexity_avg: 0,\n type_safety: false,\n secrets_clean: true,\n },\n projects: [],\n builder_profile: {\n is_end_to_end: false,\n role_signals: [],\n },\n last_updated: new Date().toISOString(),\n };\n}\n","import { loadJson, saveJson } from '../storage/store.js';\nimport type {\n SkillGraph, BuilderIdentity, TechSkill, ProjectEntry, ScanResult,\n LlmClassificationResult, QualityMetrics,\n} from './schema.js';\nimport { createEmptySkillGraph } from './schema.js';\n\nconst GRAPH_FILE = 'skill-graph.json';\n\nexport async function loadGraph(): Promise<SkillGraph | null> {\n return loadJson<SkillGraph>(GRAPH_FILE);\n}\n\nexport async function saveGraph(graph: SkillGraph): Promise<void> {\n graph.last_updated = new Date().toISOString();\n await saveJson(GRAPH_FILE, graph);\n}\n\nexport function buildProjectEntry(scan: ScanResult): ProjectEntry {\n return {\n name: scan.project_name,\n path: scan.project_path,\n domain: scan.llm_classification?.domain || 'unknown',\n stack: [\n ...scan.dependencies.frameworks,\n ...Object.keys(scan.file_discovery.languages),\n ],\n languages: scan.file_discovery.languages,\n commits: scan.git_forensics.commits,\n active_days: scan.git_forensics.active_days,\n contributors: scan.git_forensics.contributors,\n test_ratio: scan.quality_signals.test_ratio,\n complexity_avg: scan.quality_signals.complexity_avg,\n patterns: scan.architecture_patterns.patterns,\n description: scan.llm_classification?.description || '',\n scanned_at: new Date().toISOString(),\n };\n}\n\nexport function mergeIntoGraph(\n graph: SkillGraph,\n project: ProjectEntry,\n classification: LlmClassificationResult | null,\n): SkillGraph {\n // Update or add project\n const existingIdx = graph.projects.findIndex(p => p.path === project.path);\n if (existingIdx >= 0) {\n graph.projects[existingIdx] = project;\n } else {\n graph.projects.push(project);\n }\n\n // Merge tech stack from all projects\n graph.tech_stack = {};\n for (const proj of graph.projects) {\n for (const [lang, stats] of Object.entries(proj.languages)) {\n if (!graph.tech_stack[lang]) {\n graph.tech_stack[lang] = {\n proficiency: 0,\n source: 'code-verified',\n loc: 0,\n projects: 0,\n advanced_features: [],\n last_seen: proj.scanned_at,\n };\n }\n const skill = graph.tech_stack[lang];\n skill.loc += stats.loc;\n skill.projects += 1;\n if (proj.scanned_at > skill.last_seen) {\n skill.last_seen = proj.scanned_at;\n }\n }\n\n // Add frameworks to tech stack\n for (const fw of proj.stack) {\n if (!graph.tech_stack[fw]) {\n graph.tech_stack[fw] = {\n proficiency: 0,\n source: 'code-verified',\n loc: 0,\n projects: 0,\n advanced_features: [],\n last_seen: proj.scanned_at,\n };\n }\n // Only increment projects count for frameworks (not languages already counted)\n if (!proj.languages[fw]) {\n graph.tech_stack[fw].projects += 1;\n }\n }\n }\n\n // Calculate proficiency scores\n for (const skill of Object.values(graph.tech_stack)) {\n skill.proficiency = calculateProficiency(skill);\n }\n\n // Merge architecture patterns (take max confidence across projects)\n graph.architecture = {};\n for (const proj of graph.projects) {\n for (const [pattern, confidence] of Object.entries(proj.patterns)) {\n if (!graph.architecture[pattern] || confidence > graph.architecture[pattern].confidence) {\n graph.architecture[pattern] = { confidence };\n }\n }\n }\n\n // Average quality metrics across projects\n graph.quality = averageQuality(graph.projects);\n\n // Update builder profile from classification\n if (classification) {\n graph.builder_profile = {\n is_end_to_end: classification.is_end_to_end || graph.builder_profile.is_end_to_end,\n role_signals: [...new Set([\n ...graph.builder_profile.role_signals,\n ...classification.role_signals,\n ])],\n };\n }\n\n return graph;\n}\n\nfunction calculateProficiency(skill: TechSkill): number {\n const locScore = Math.min(1, skill.loc / 50000) * 0.4;\n const projectScore = Math.min(1, skill.projects / 10) * 0.3;\n const featureScore = Math.min(1, skill.advanced_features.length / 5) * 0.3;\n return Math.round(Math.min(1, locScore + projectScore + featureScore) * 100) / 100;\n}\n\nfunction averageQuality(projects: ProjectEntry[]): QualityMetrics {\n if (projects.length === 0) {\n return { test_ratio: 0, complexity_avg: 0, type_safety: false, secrets_clean: true };\n }\n\n const testRatio = projects.reduce((sum, p) => sum + p.test_ratio, 0) / projects.length;\n const complexity = projects.reduce((sum, p) => sum + p.complexity_avg, 0) / projects.length;\n\n return {\n test_ratio: Math.round(testRatio * 100) / 100,\n complexity_avg: Math.round(complexity * 10) / 10,\n type_safety: false, // Will be updated per-project\n secrets_clean: true,\n };\n}\n","import chalk from 'chalk';\n\nexport function info(msg: string): void {\n console.log(chalk.cyan(msg));\n}\n\nexport function success(msg: string): void {\n console.log(chalk.green(msg));\n}\n\nexport function warn(msg: string): void {\n console.log(chalk.yellow(msg));\n}\n\nexport function error(msg: string): void {\n console.log(chalk.red(msg));\n}\n\nexport function header(msg: string): void {\n console.log(chalk.bold.white(msg));\n}\n\nexport function dim(msg: string): void {\n console.log(chalk.dim(msg));\n}\n\nexport function layerOutput(label: string, detail: string): void {\n console.log(` ${chalk.cyan(label.padEnd(28))} ${detail}`);\n}\n","import ora, { type Ora } from 'ora';\n\nlet current: Ora | null = null;\n\nexport function start(text: string): Ora {\n if (current) current.stop();\n current = ora(text).start();\n return current;\n}\n\nexport function succeed(text: string): void {\n if (current) {\n current.succeed(text);\n current = null;\n }\n}\n\nexport function fail(text: string): void {\n if (current) {\n current.fail(text);\n current = null;\n }\n}\n\nexport function stop(): void {\n if (current) {\n current.stop();\n current = null;\n }\n}\n","import { resolve, basename } from 'path';\nimport { existsSync } from 'fs';\nimport { analyzeFileDiscovery } from '../layers/file-discovery.js';\nimport { analyzeDependencies } from '../layers/dependency-extraction.js';\nimport { analyzeAst } from '../layers/ast-analysis.js';\nimport { analyzeGitForensics } from '../layers/git-forensics.js';\nimport { analyzeQualitySignals } from '../layers/quality-signals.js';\nimport { analyzeArchitecturePatterns } from '../layers/architecture-patterns.js';\nimport { classifyWithLlm } from '../layers/llm-classification.js';\nimport { loadGraph, saveGraph, buildProjectEntry, mergeIntoGraph } from '../graph/skill-graph.js';\nimport { isApiKeyConfigured } from '../llm/client.js';\nimport { createEmptySkillGraph } from '../graph/schema.js';\nimport type { ScanResult } from '../graph/schema.js';\nimport * as log from '../utils/logger.js';\nimport * as spinner from '../utils/spinner.js';\n\nexport async function scanCommand(path: string): Promise<void> {\n const projectPath = resolve(path);\n const projectName = basename(projectPath);\n\n if (!existsSync(projectPath)) {\n log.error(`Directory not found: ${projectPath}`);\n process.exit(1);\n }\n\n log.header(`\\n Scanning ${projectName}...\\n`);\n\n // Layer 1: File Discovery\n spinner.start('Layer 1: File discovery...');\n const fileDiscovery = await analyzeFileDiscovery(projectPath);\n spinner.succeed('Layer 1: File discovery');\n log.layerOutput('Layer 1: File discovery',\n `${fileDiscovery.total_files} files, ${fileDiscovery.total_loc.toLocaleString()} LOC`);\n\n // Layer 2: Dependencies\n spinner.start('Layer 2: Dependencies...');\n const dependencies = await analyzeDependencies(projectPath);\n spinner.succeed('Layer 2: Dependencies');\n log.layerOutput('Layer 2: Dependencies',\n dependencies.frameworks.length > 0\n ? dependencies.frameworks.join(', ')\n : dependencies.dependencies.slice(0, 5).join(', ') || 'none detected');\n\n // Layer 3: AST Analysis\n spinner.start('Layer 3: AST analysis...');\n const astAnalysis = await analyzeAst(projectPath, fileDiscovery.languages);\n spinner.succeed('Layer 3: AST analysis');\n log.layerOutput('Layer 3: AST analysis',\n `${astAnalysis.functions} functions, ${astAnalysis.classes} classes, ${astAnalysis.components} components, ${astAnalysis.hooks} hooks`);\n\n // Layer 4: Git Forensics\n spinner.start('Layer 4: Git forensics...');\n const gitForensics = await analyzeGitForensics(projectPath);\n spinner.succeed('Layer 4: Git forensics');\n if (gitForensics.is_git_repo) {\n log.layerOutput('Layer 4: Git forensics',\n `${gitForensics.commits} commits, ${gitForensics.active_days} active days, ${gitForensics.contributors} contributors`);\n } else {\n log.layerOutput('Layer 4: Git forensics', 'Not a git repo');\n }\n\n // Layer 5: Quality Signals\n spinner.start('Layer 5: Quality signals...');\n const qualitySignals = await analyzeQualitySignals(projectPath, fileDiscovery);\n spinner.succeed('Layer 5: Quality signals');\n log.layerOutput('Layer 5: Quality signals',\n `test ratio ${qualitySignals.test_ratio}, complexity ${qualitySignals.complexity_avg}, ${qualitySignals.type_safety ? 'strict TS' : 'no strict types'}`);\n\n // Layer 6: Architecture Patterns\n spinner.start('Layer 6: Architecture patterns...');\n const architecturePatterns = await analyzeArchitecturePatterns(projectPath, fileDiscovery, astAnalysis);\n spinner.succeed('Layer 6: Architecture patterns');\n const patternStr = Object.entries(architecturePatterns.patterns)\n .map(([name, conf]) => `${name} (${conf})`)\n .join(', ') || 'none detected';\n log.layerOutput('Layer 6: Architecture patterns', patternStr);\n\n // Layer 7: LLM Classification\n let llmClassification = null;\n if (isApiKeyConfigured()) {\n spinner.start('Layer 7: LLM classification (API call)...');\n llmClassification = await classifyWithLlm(\n fileDiscovery, dependencies, astAnalysis, gitForensics, qualitySignals, architecturePatterns,\n );\n if (llmClassification) {\n spinner.succeed('Layer 7: LLM classification');\n log.layerOutput('Layer 7: LLM classification',\n `${llmClassification.domain}, ${llmClassification.builder_profile}`);\n } else {\n spinner.fail('Layer 7: LLM classification failed');\n }\n } else {\n log.dim(' Layer 7: Skipped (no API key — run inside Claude Code for full analysis)');\n }\n\n // Build scan result\n const scanResult: ScanResult = {\n project_name: projectName,\n project_path: projectPath,\n file_discovery: fileDiscovery,\n dependencies,\n ast_analysis: astAnalysis,\n git_forensics: gitForensics,\n quality_signals: qualitySignals,\n architecture_patterns: architecturePatterns,\n llm_classification: llmClassification,\n };\n\n // Merge into skill graph\n spinner.start('Updating skill graph...');\n let graph = await loadGraph();\n if (!graph) {\n graph = createEmptySkillGraph({\n name: '', email: '', primary_role: 'engineer', target_roles: [],\n previous_companies: [], education: [], links: {}, source: 'manual',\n });\n }\n\n const projectEntry = buildProjectEntry(scanResult);\n graph = mergeIntoGraph(graph, projectEntry, llmClassification);\n await saveGraph(graph);\n spinner.succeed('Skill graph updated');\n\n log.success(`\\nScan complete. ${graph.projects.length} project(s) in skill graph.`);\n log.info('Run `hiregraph status` to see your full profile.');\n}\n","import { readdir, readFile } from 'fs/promises';\nimport { join, extname, relative } from 'path';\nimport type { Ignore } from 'ignore';\nimport { createFilter } from '../utils/gitignore.js';\nimport { getLanguage, shouldSkip } from '../utils/language-map.js';\nimport type { FileDiscoveryResult } from '../graph/schema.js';\n\nconst CONFIG_PATTERNS = [\n 'Dockerfile', 'docker-compose.yml', 'docker-compose.yaml',\n '.github', '.gitlab-ci.yml', '.circleci',\n 'tsconfig.json', 'jest.config', 'vitest.config', 'vite.config',\n '.eslintrc', '.prettierrc', 'prettier.config',\n 'biome.json', 'ruff.toml', '.flake8',\n 'Makefile', 'Procfile', 'vercel.json', 'netlify.toml',\n 'turbo.json', 'lerna.json',\n];\n\ninterface FileInfo {\n relativePath: string;\n language: string;\n loc: number;\n}\n\nexport async function analyzeFileDiscovery(projectPath: string): Promise<FileDiscoveryResult> {\n const ig = await createFilter(projectPath);\n const files: FileInfo[] = [];\n const configFiles: string[] = [];\n\n await walkDir(projectPath, projectPath, ig, files, configFiles);\n\n const languages: Record<string, { files: number; loc: number }> = {};\n let totalLoc = 0;\n\n for (const file of files) {\n if (!languages[file.language]) {\n languages[file.language] = { files: 0, loc: 0 };\n }\n languages[file.language].files++;\n languages[file.language].loc += file.loc;\n totalLoc += file.loc;\n }\n\n let primaryLanguage = '';\n let maxLoc = 0;\n for (const [lang, stats] of Object.entries(languages)) {\n if (stats.loc > maxLoc) {\n maxLoc = stats.loc;\n primaryLanguage = lang;\n }\n }\n\n return {\n total_files: files.length,\n total_loc: totalLoc,\n languages,\n config_files: configFiles,\n primary_language: primaryLanguage,\n };\n}\n\nasync function walkDir(\n basePath: string,\n currentPath: string,\n ig: Ignore,\n files: FileInfo[],\n configFiles: string[],\n): Promise<void> {\n const entries = await readdir(currentPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(currentPath, entry.name);\n const relPath = relative(basePath, fullPath).replace(/\\\\/g, '/');\n\n if (ig.ignores(relPath)) continue;\n\n if (entry.isDirectory()) {\n // Check for config directories\n if (CONFIG_PATTERNS.some(p => entry.name === p || entry.name.startsWith(p))) {\n configFiles.push(entry.name);\n }\n await walkDir(basePath, fullPath, ig, files, configFiles);\n } else if (entry.isFile()) {\n const ext = extname(entry.name).toLowerCase();\n\n // Check for config files\n if (CONFIG_PATTERNS.some(p => entry.name === p || entry.name.startsWith(p))) {\n configFiles.push(entry.name);\n }\n\n if (shouldSkip(ext)) continue;\n\n const language = getLanguage(ext);\n if (!language) continue;\n\n try {\n const content = await readFile(fullPath, 'utf-8');\n const loc = countLines(content);\n files.push({ relativePath: relPath, language, loc });\n } catch {\n // Skip files that can't be read\n }\n }\n }\n}\n\nfunction countLines(content: string): number {\n const lines = content.split('\\n');\n let count = 0;\n for (const line of lines) {\n if (line.trim().length > 0) count++;\n }\n return count;\n}\n","import ignore, { type Ignore } from 'ignore';\nimport { readFile } from 'fs/promises';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\n\nconst DEFAULT_IGNORES = [\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n 'out',\n '.next',\n '.nuxt',\n '__pycache__',\n '.pytest_cache',\n 'target',\n 'vendor',\n '.venv',\n 'venv',\n 'env',\n '.tox',\n '.mypy_cache',\n 'coverage',\n '.nyc_output',\n '.turbo',\n '.vercel',\n '.expo',\n '.cache',\n];\n\nexport async function createFilter(projectPath: string): Promise<Ignore> {\n const ig = ignore();\n ig.add(DEFAULT_IGNORES);\n\n const gitignorePath = join(projectPath, '.gitignore');\n if (existsSync(gitignorePath)) {\n const content = await readFile(gitignorePath, 'utf-8');\n ig.add(content);\n }\n\n return ig;\n}\n","const LANGUAGE_MAP: Record<string, string> = {\n '.ts': 'TypeScript',\n '.tsx': 'TypeScript',\n '.js': 'JavaScript',\n '.jsx': 'JavaScript',\n '.mjs': 'JavaScript',\n '.cjs': 'JavaScript',\n '.py': 'Python',\n '.rs': 'Rust',\n '.go': 'Go',\n '.java': 'Java',\n '.kt': 'Kotlin',\n '.kts': 'Kotlin',\n '.swift': 'Swift',\n '.rb': 'Ruby',\n '.php': 'PHP',\n '.c': 'C',\n '.h': 'C',\n '.cpp': 'C++',\n '.cc': 'C++',\n '.cxx': 'C++',\n '.hpp': 'C++',\n '.cs': 'C#',\n '.dart': 'Dart',\n '.lua': 'Lua',\n '.r': 'R',\n '.R': 'R',\n '.scala': 'Scala',\n '.ex': 'Elixir',\n '.exs': 'Elixir',\n '.erl': 'Erlang',\n '.hs': 'Haskell',\n '.clj': 'Clojure',\n '.vue': 'Vue',\n '.svelte': 'Svelte',\n '.sol': 'Solidity',\n '.zig': 'Zig',\n '.nim': 'Nim',\n '.ml': 'OCaml',\n '.sh': 'Shell',\n '.bash': 'Shell',\n '.zsh': 'Shell',\n '.sql': 'SQL',\n};\n\nconst SKIP_EXTENSIONS = new Set([\n '.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico', '.webp', '.bmp',\n '.woff', '.woff2', '.ttf', '.eot', '.otf',\n '.mp3', '.mp4', '.avi', '.mov', '.wav', '.ogg',\n '.zip', '.tar', '.gz', '.rar', '.7z',\n '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.pptx',\n '.exe', '.dll', '.so', '.dylib', '.bin',\n '.lock', '.map',\n]);\n\nexport function getLanguage(ext: string): string | null {\n return LANGUAGE_MAP[ext] ?? null;\n}\n\nexport function shouldSkip(ext: string): boolean {\n return SKIP_EXTENSIONS.has(ext);\n}\n\nexport function getSupportedExtensions(): string[] {\n return Object.keys(LANGUAGE_MAP);\n}\n","import { readFile } from 'fs/promises';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport type { DependencyResult } from '../graph/schema.js';\n\nconst FRAMEWORK_MAP: Record<string, string> = {\n // Frontend\n 'react': 'React', 'react-dom': 'React', 'next': 'Next.js', 'vue': 'Vue',\n 'nuxt': 'Nuxt', 'svelte': 'Svelte', '@sveltejs/kit': 'SvelteKit',\n 'angular': 'Angular', '@angular/core': 'Angular', 'solid-js': 'Solid',\n 'astro': 'Astro', 'gatsby': 'Gatsby', 'remix': 'Remix',\n // Mobile\n 'react-native': 'React Native', 'expo': 'Expo', 'flutter': 'Flutter',\n // Backend\n 'express': 'Express', 'fastify': 'Fastify', 'koa': 'Koa', 'hono': 'Hono',\n 'nestjs': 'NestJS', '@nestjs/core': 'NestJS',\n // Database\n 'prisma': 'Prisma', '@prisma/client': 'Prisma', 'drizzle-orm': 'Drizzle',\n 'typeorm': 'TypeORM', 'sequelize': 'Sequelize', 'mongoose': 'Mongoose',\n '@supabase/supabase-js': 'Supabase', 'firebase': 'Firebase',\n // Python frameworks (from requirements.txt)\n 'django': 'Django', 'flask': 'Flask', 'fastapi': 'FastAPI',\n 'tornado': 'Tornado', 'starlette': 'Starlette',\n 'sqlalchemy': 'SQLAlchemy', 'pandas': 'Pandas', 'numpy': 'NumPy',\n 'tensorflow': 'TensorFlow', 'torch': 'PyTorch', 'pytorch': 'PyTorch',\n // Rust frameworks\n 'actix-web': 'Actix', 'axum': 'Axum', 'rocket': 'Rocket', 'warp': 'Warp',\n 'tokio': 'Tokio', 'serde': 'Serde',\n // Go frameworks\n 'github.com/gin-gonic/gin': 'Gin', 'github.com/gofiber/fiber': 'Fiber',\n 'github.com/labstack/echo': 'Echo',\n // AI/ML\n '@anthropic-ai/sdk': 'Anthropic SDK', 'openai': 'OpenAI',\n 'langchain': 'LangChain', '@langchain/core': 'LangChain',\n};\n\nexport async function analyzeDependencies(projectPath: string): Promise<DependencyResult> {\n const deps: string[] = [];\n const devDeps: string[] = [];\n const frameworks: Set<string> = new Set();\n let ecosystem = 'unknown';\n let hasLockfile = false;\n\n // Node.js\n const pkgPath = join(projectPath, 'package.json');\n if (existsSync(pkgPath)) {\n ecosystem = 'node';\n hasLockfile = existsSync(join(projectPath, 'package-lock.json')) ||\n existsSync(join(projectPath, 'yarn.lock')) ||\n existsSync(join(projectPath, 'pnpm-lock.yaml')) ||\n existsSync(join(projectPath, 'bun.lockb'));\n try {\n const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));\n if (pkg.dependencies) {\n for (const dep of Object.keys(pkg.dependencies)) {\n deps.push(dep);\n const fw = FRAMEWORK_MAP[dep];\n if (fw) frameworks.add(fw);\n }\n }\n if (pkg.devDependencies) {\n for (const dep of Object.keys(pkg.devDependencies)) {\n devDeps.push(dep);\n const fw = FRAMEWORK_MAP[dep];\n if (fw) frameworks.add(fw);\n }\n }\n } catch { /* skip malformed package.json */ }\n }\n\n // Python\n const reqPath = join(projectPath, 'requirements.txt');\n if (existsSync(reqPath)) {\n ecosystem = ecosystem === 'node' ? 'multi' : 'python';\n hasLockfile = hasLockfile || existsSync(join(projectPath, 'Pipfile.lock')) ||\n existsSync(join(projectPath, 'poetry.lock'));\n try {\n const content = await readFile(reqPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('-')) continue;\n const name = trimmed.split(/[=<>!~]/)[0].trim().toLowerCase();\n if (name) {\n deps.push(name);\n const fw = FRAMEWORK_MAP[name];\n if (fw) frameworks.add(fw);\n }\n }\n } catch { /* skip */ }\n }\n\n // pyproject.toml (basic parsing)\n const pyprojectPath = join(projectPath, 'pyproject.toml');\n if (existsSync(pyprojectPath)) {\n ecosystem = ecosystem === 'unknown' ? 'python' : ecosystem === 'python' ? 'python' : 'multi';\n try {\n const content = await readFile(pyprojectPath, 'utf-8');\n const depMatches = content.match(/dependencies\\s*=\\s*\\[([\\s\\S]*?)\\]/);\n if (depMatches) {\n const items = depMatches[1].match(/\"([^\"]+)\"/g);\n if (items) {\n for (const item of items) {\n const name = item.replace(/\"/g, '').split(/[=<>!~]/)[0].trim().toLowerCase();\n if (name && !deps.includes(name)) {\n deps.push(name);\n const fw = FRAMEWORK_MAP[name];\n if (fw) frameworks.add(fw);\n }\n }\n }\n }\n } catch { /* skip */ }\n }\n\n // Rust\n const cargoPath = join(projectPath, 'Cargo.toml');\n if (existsSync(cargoPath)) {\n ecosystem = ecosystem === 'unknown' ? 'rust' : 'multi';\n hasLockfile = hasLockfile || existsSync(join(projectPath, 'Cargo.lock'));\n try {\n const content = await readFile(cargoPath, 'utf-8');\n const depSection = content.match(/\\[dependencies\\]([\\s\\S]*?)(?=\\[|$)/);\n if (depSection) {\n for (const line of depSection[1].split('\\n')) {\n const match = line.match(/^(\\S+)\\s*=/);\n if (match) {\n const name = match[1].trim();\n deps.push(name);\n const fw = FRAMEWORK_MAP[name];\n if (fw) frameworks.add(fw);\n }\n }\n }\n const devSection = content.match(/\\[dev-dependencies\\]([\\s\\S]*?)(?=\\[|$)/);\n if (devSection) {\n for (const line of devSection[1].split('\\n')) {\n const match = line.match(/^(\\S+)\\s*=/);\n if (match) devDeps.push(match[1].trim());\n }\n }\n } catch { /* skip */ }\n }\n\n // Go\n const goModPath = join(projectPath, 'go.mod');\n if (existsSync(goModPath)) {\n ecosystem = ecosystem === 'unknown' ? 'go' : 'multi';\n hasLockfile = hasLockfile || existsSync(join(projectPath, 'go.sum'));\n try {\n const content = await readFile(goModPath, 'utf-8');\n const requireBlock = content.match(/require\\s*\\(([\\s\\S]*?)\\)/);\n if (requireBlock) {\n for (const line of requireBlock[1].split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('//')) continue;\n const parts = trimmed.split(/\\s+/);\n if (parts[0]) {\n deps.push(parts[0]);\n const fw = FRAMEWORK_MAP[parts[0]];\n if (fw) frameworks.add(fw);\n }\n }\n }\n } catch { /* skip */ }\n }\n\n return {\n ecosystem,\n dependencies: deps,\n dev_dependencies: devDeps,\n frameworks: [...frameworks],\n has_lockfile: hasLockfile,\n };\n}\n","import { readFile, readdir } from 'fs/promises';\nimport { join, extname, relative } from 'path';\nimport type { Ignore } from 'ignore';\nimport { createFilter } from '../utils/gitignore.js';\nimport type { AstAnalysisResult } from '../graph/schema.js';\n\n// Regex-based AST analysis (no tree-sitter dependency for now — keeps install simple)\n// Covers TypeScript, JavaScript, Python, Rust, Go via pattern matching on source text.\n// A tree-sitter upgrade path exists if deeper analysis is needed later.\n\nconst MAX_FILES = 100;\n\nconst EMPTY_RESULT: AstAnalysisResult = {\n functions: 0,\n classes: 0,\n interfaces: 0,\n components: 0,\n hooks: 0,\n services: 0,\n max_nesting_depth: 0,\n avg_params_per_function: 0,\n imports_used: [],\n advanced_features: [],\n};\n\ninterface FileAnalysis {\n functions: number;\n classes: number;\n interfaces: number;\n components: number;\n hooks: number;\n services: number;\n nestingDepth: number;\n paramCounts: number[];\n imports: string[];\n features: string[];\n}\n\nexport async function analyzeAst(\n projectPath: string,\n languages: Record<string, { files: number; loc: number }>,\n): Promise<AstAnalysisResult> {\n const ig = await createFilter(projectPath);\n const files = await collectSourceFiles(projectPath, projectPath, ig);\n\n // Sample if too many files\n const sampled = files.length > MAX_FILES\n ? files.sort(() => Math.random() - 0.5).slice(0, MAX_FILES)\n : files;\n\n const totals: FileAnalysis = {\n functions: 0, classes: 0, interfaces: 0, components: 0,\n hooks: 0, services: 0, nestingDepth: 0, paramCounts: [],\n imports: [], features: [],\n };\n\n for (const filePath of sampled) {\n try {\n const content = await readFile(filePath, 'utf-8');\n const ext = extname(filePath).toLowerCase();\n const analysis = analyzeFile(content, ext);\n totals.functions += analysis.functions;\n totals.classes += analysis.classes;\n totals.interfaces += analysis.interfaces;\n totals.components += analysis.components;\n totals.hooks += analysis.hooks;\n totals.services += analysis.services;\n totals.nestingDepth = Math.max(totals.nestingDepth, analysis.nestingDepth);\n totals.paramCounts.push(...analysis.paramCounts);\n totals.imports.push(...analysis.imports);\n totals.features.push(...analysis.features);\n } catch { /* skip unreadable files */ }\n }\n\n const uniqueImports = [...new Set(totals.imports)];\n const uniqueFeatures = [...new Set(totals.features)];\n const avgParams = totals.paramCounts.length > 0\n ? Math.round((totals.paramCounts.reduce((a, b) => a + b, 0) / totals.paramCounts.length) * 100) / 100\n : 0;\n\n return {\n functions: totals.functions,\n classes: totals.classes,\n interfaces: totals.interfaces,\n components: totals.components,\n hooks: totals.hooks,\n services: totals.services,\n max_nesting_depth: totals.nestingDepth,\n avg_params_per_function: avgParams,\n imports_used: uniqueImports,\n advanced_features: uniqueFeatures,\n };\n}\n\nfunction analyzeFile(content: string, ext: string): FileAnalysis {\n const result: FileAnalysis = {\n functions: 0, classes: 0, interfaces: 0, components: 0,\n hooks: 0, services: 0, nestingDepth: 0, paramCounts: [],\n imports: [], features: [],\n };\n\n if (['.ts', '.tsx', '.js', '.jsx', '.mjs'].includes(ext)) {\n analyzeTypeScript(content, ext, result);\n } else if (ext === '.py') {\n analyzePython(content, result);\n } else if (ext === '.rs') {\n analyzeRust(content, result);\n } else if (ext === '.go') {\n analyzeGo(content, result);\n }\n\n return result;\n}\n\nfunction analyzeTypeScript(content: string, ext: string, result: FileAnalysis): void {\n // Functions\n const funcMatches = content.match(/(?:function\\s+\\w+|(?:const|let|var)\\s+\\w+\\s*=\\s*(?:async\\s*)?\\(|(?:async\\s+)?(?:export\\s+)?(?:default\\s+)?function)/g);\n if (funcMatches) {\n result.functions += funcMatches.length;\n for (const m of funcMatches) {\n const params = m.match(/\\(([^)]*)\\)/);\n if (params && params[1]) {\n result.paramCounts.push(params[1].split(',').filter(p => p.trim()).length);\n }\n }\n }\n\n // Arrow functions in methods\n const arrowFuncs = content.match(/=>\\s*{/g);\n if (arrowFuncs) result.functions += arrowFuncs.length;\n\n // Classes\n const classMatches = content.match(/\\bclass\\s+\\w+/g);\n if (classMatches) result.classes += classMatches.length;\n\n // Interfaces and types\n const ifaceMatches = content.match(/\\b(?:interface|type)\\s+\\w+/g);\n if (ifaceMatches) result.interfaces += ifaceMatches.length;\n\n // React components (function returning JSX in .tsx/.jsx)\n if (['.tsx', '.jsx'].includes(ext)) {\n const componentMatches = content.match(/(?:export\\s+)?(?:default\\s+)?function\\s+[A-Z]\\w*/g);\n if (componentMatches) result.components += componentMatches.length;\n const arrowComponents = content.match(/(?:const|export\\s+const)\\s+[A-Z]\\w+\\s*[=:]/g);\n if (arrowComponents) result.components += arrowComponents.length;\n }\n\n // Custom hooks\n const hookMatches = content.match(/(?:function|const)\\s+use[A-Z]\\w*/g);\n if (hookMatches) result.hooks += hookMatches.length;\n\n // Services\n const serviceMatches = content.match(/class\\s+\\w*(?:Service|Repository|Controller)\\b/g);\n if (serviceMatches) result.services += serviceMatches.length;\n\n // Imports\n const importMatches = content.matchAll(/import\\s+.*?from\\s+['\"]([^'\"]+)['\"]/g);\n for (const m of importMatches) {\n const pkg = m[1];\n if (!pkg.startsWith('.') && !pkg.startsWith('/')) {\n result.imports.push(pkg.split('/').slice(0, pkg.startsWith('@') ? 2 : 1).join('/'));\n }\n }\n\n // Advanced features\n if (content.match(/<\\w+(?:\\s+extends|\\s*,)/)) result.features.push('generics');\n if (content.match(/\\bkeyof\\b|\\bin\\s+keyof\\b/)) result.features.push('mapped-types');\n if (content.match(/\\binfer\\b/)) result.features.push('conditional-types');\n if (content.match(/@\\w+/)) result.features.push('decorators');\n if (content.match(/\\basync\\s+/)) result.features.push('async-await');\n\n // Nesting depth\n result.nestingDepth = estimateNesting(content);\n}\n\nfunction analyzePython(content: string, result: FileAnalysis): void {\n const funcMatches = content.match(/\\bdef\\s+\\w+/g);\n if (funcMatches) result.functions += funcMatches.length;\n\n const classMatches = content.match(/\\bclass\\s+\\w+/g);\n if (classMatches) result.classes += classMatches.length;\n\n // Imports\n const importMatches = content.matchAll(/(?:from\\s+(\\S+)\\s+import|import\\s+(\\S+))/g);\n for (const m of importMatches) {\n const pkg = (m[1] || m[2]).split('.')[0];\n if (pkg && !pkg.startsWith('.')) result.imports.push(pkg);\n }\n\n // Advanced features\n if (content.match(/@\\w+/)) result.features.push('decorators');\n if (content.match(/@dataclass/)) result.features.push('dataclasses');\n if (content.match(/->\\s*\\w+|:\\s*\\w+\\s*[=,)]/)) result.features.push('type-hints');\n if (content.match(/\\basync\\s+def\\b/)) result.features.push('async-await');\n\n // Services\n const serviceMatches = content.match(/class\\s+\\w*(?:Service|Repository|Controller)\\b/g);\n if (serviceMatches) result.services += serviceMatches.length;\n\n result.nestingDepth = estimateIndentNesting(content);\n}\n\nfunction analyzeRust(content: string, result: FileAnalysis): void {\n const fnMatches = content.match(/\\bfn\\s+\\w+/g);\n if (fnMatches) result.functions += fnMatches.length;\n\n const structMatches = content.match(/\\bstruct\\s+\\w+/g);\n if (structMatches) result.classes += structMatches.length;\n\n const traitMatches = content.match(/\\btrait\\s+\\w+/g);\n if (traitMatches) result.interfaces += traitMatches.length;\n\n const implMatches = content.match(/\\bimpl\\b/g);\n if (implMatches) result.features.push('impl-blocks');\n\n // Imports\n const useMatches = content.matchAll(/use\\s+(\\w+)/g);\n for (const m of useMatches) {\n if (m[1] !== 'std' && m[1] !== 'self' && m[1] !== 'super' && m[1] !== 'crate') {\n result.imports.push(m[1]);\n }\n }\n\n if (content.match(/\\basync\\s+fn\\b/)) result.features.push('async-await');\n if (content.match(/macro_rules!/)) result.features.push('macros');\n if (content.match(/<[^>]+>/)) result.features.push('generics');\n if (content.match(/\\bunsafe\\b/)) result.features.push('unsafe');\n\n result.nestingDepth = estimateNesting(content);\n}\n\nfunction analyzeGo(content: string, result: FileAnalysis): void {\n const funcMatches = content.match(/\\bfunc\\s+(?:\\([^)]*\\)\\s*)?\\w+/g);\n if (funcMatches) result.functions += funcMatches.length;\n\n const structMatches = content.match(/\\btype\\s+\\w+\\s+struct\\b/g);\n if (structMatches) result.classes += structMatches.length;\n\n const ifaceMatches = content.match(/\\btype\\s+\\w+\\s+interface\\b/g);\n if (ifaceMatches) result.interfaces += ifaceMatches.length;\n\n // Imports\n const importBlock = content.match(/import\\s*\\(([\\s\\S]*?)\\)/);\n if (importBlock) {\n const imports = importBlock[1].matchAll(/\"([^\"]+)\"/g);\n for (const m of imports) {\n const parts = m[1].split('/');\n result.imports.push(parts[parts.length - 1]);\n }\n }\n\n if (content.match(/\\bgo\\s+\\w+/)) result.features.push('goroutines');\n if (content.match(/\\bchan\\b/)) result.features.push('channels');\n if (content.match(/\\binterface\\s*\\{/)) result.features.push('interfaces');\n\n result.nestingDepth = estimateNesting(content);\n}\n\nfunction estimateNesting(content: string): number {\n let max = 0;\n let current = 0;\n for (const char of content) {\n if (char === '{') { current++; max = Math.max(max, current); }\n else if (char === '}') { current = Math.max(0, current - 1); }\n }\n return max;\n}\n\nfunction estimateIndentNesting(content: string): number {\n let max = 0;\n for (const line of content.split('\\n')) {\n if (line.trim().length === 0) continue;\n const indent = line.match(/^(\\s*)/);\n if (indent) {\n const level = Math.floor(indent[1].length / 4);\n max = Math.max(max, level);\n }\n }\n return max;\n}\n\nasync function collectSourceFiles(\n basePath: string,\n currentPath: string,\n ig: Ignore,\n): Promise<string[]> {\n const files: string[] = [];\n const codeExts = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.py', '.rs', '.go']);\n\n const entries = await readdir(currentPath, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = join(currentPath, entry.name);\n const relPath = relative(basePath, fullPath).replace(/\\\\/g, '/');\n\n if (ig.ignores(relPath)) continue;\n\n if (entry.isDirectory()) {\n files.push(...await collectSourceFiles(basePath, fullPath, ig));\n } else if (entry.isFile()) {\n const ext = extname(entry.name).toLowerCase();\n if (codeExts.has(ext)) files.push(fullPath);\n }\n }\n\n return files;\n}\n","import { execFile } from 'child_process';\nimport { promisify } from 'util';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport type { GitForensicsResult } from '../graph/schema.js';\n\nconst execFileAsync = promisify(execFile);\n\nconst EMPTY_RESULT: GitForensicsResult = {\n is_git_repo: false,\n commits: 0,\n active_days: 0,\n contributors: 0,\n commits_per_active_day: 0,\n active_days_per_week: 0,\n first_commit: '',\n last_commit: '',\n conventional_commit_ratio: 0,\n branches: 0,\n primary_author: '',\n};\n\nconst CONVENTIONAL_PREFIXES = [\n 'feat:', 'fix:', 'refactor:', 'docs:', 'test:', 'chore:',\n 'style:', 'perf:', 'ci:', 'build:', 'revert:',\n 'feat(', 'fix(', 'refactor(', 'docs(', 'test(', 'chore(',\n];\n\nexport async function analyzeGitForensics(projectPath: string): Promise<GitForensicsResult> {\n if (!existsSync(join(projectPath, '.git'))) {\n return { ...EMPTY_RESULT };\n }\n\n try {\n const opts = { cwd: projectPath, maxBuffer: 10 * 1024 * 1024 };\n\n const [logResult, branchResult] = await Promise.all([\n execFileAsync('git', ['log', '--format=%an|%aI|%s', '--all'], opts),\n execFileAsync('git', ['branch', '-a', '--format=%(refname:short)'], opts),\n ]);\n\n const lines = logResult.stdout.trim().split('\\n').filter(Boolean);\n if (lines.length === 0) return { ...EMPTY_RESULT, is_git_repo: true };\n\n const authors: Record<string, number> = {};\n const dates = new Set<string>();\n let conventionalCount = 0;\n let firstDate = '';\n let lastDate = '';\n\n for (const line of lines) {\n const parts = line.split('|');\n if (parts.length < 3) continue;\n\n const author = parts[0];\n const date = parts[1];\n const subject = parts.slice(2).join('|');\n\n authors[author] = (authors[author] || 0) + 1;\n\n const day = date.slice(0, 10);\n dates.add(day);\n\n if (!lastDate) lastDate = date;\n firstDate = date;\n\n const lowerSubject = subject.toLowerCase().trim();\n if (CONVENTIONAL_PREFIXES.some(p => lowerSubject.startsWith(p))) {\n conventionalCount++;\n }\n }\n\n const activeDays = dates.size;\n const commits = lines.length;\n const firstDateObj = new Date(firstDate);\n const lastDateObj = new Date(lastDate);\n const weeksSpan = Math.max(1, (lastDateObj.getTime() - firstDateObj.getTime()) / (7 * 24 * 60 * 60 * 1000));\n\n let primaryAuthor = '';\n let maxCommits = 0;\n for (const [author, count] of Object.entries(authors)) {\n if (count > maxCommits) {\n maxCommits = count;\n primaryAuthor = author;\n }\n }\n\n const branches = branchResult.stdout.trim().split('\\n').filter(Boolean).length;\n\n return {\n is_git_repo: true,\n commits,\n active_days: activeDays,\n contributors: Object.keys(authors).length,\n commits_per_active_day: Math.round((commits / activeDays) * 100) / 100,\n active_days_per_week: Math.round((activeDays / weeksSpan) * 100) / 100,\n first_commit: firstDate,\n last_commit: lastDate,\n conventional_commit_ratio: Math.round((conventionalCount / commits) * 100) / 100,\n branches,\n primary_author: primaryAuthor,\n };\n } catch {\n return { ...EMPTY_RESULT, is_git_repo: true };\n }\n}\n","import { readFile } from 'fs/promises';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport type { FileDiscoveryResult, QualitySignalsResult } from '../graph/schema.js';\n\nconst TEST_PATTERNS = [\n /\\.test\\.\\w+$/, /\\.spec\\.\\w+$/, /_test\\.\\w+$/,\n /\\/__tests__\\//, /\\/tests?\\//, /\\/spec\\//,\n];\n\nconst SECRET_PATTERNS = [\n /(?:api[_-]?key|apikey)\\s*[:=]\\s*[\"'][^\"']{8,}[\"']/i,\n /AKIA[0-9A-Z]{16}/,\n /(?:secret|password|credential|token)\\s*[:=]\\s*[\"'][^\"']{8,}[\"']/i,\n /ghp_[a-zA-Z0-9]{36}/,\n /sk-[a-zA-Z0-9]{20,}/,\n];\n\nconst LINT_CONFIGS = [\n '.eslintrc', '.eslintrc.js', '.eslintrc.json', '.eslintrc.yml', '.eslintrc.yaml',\n 'eslint.config.js', 'eslint.config.mjs', 'eslint.config.ts',\n '.prettierrc', '.prettierrc.js', '.prettierrc.json', 'prettier.config.js',\n 'biome.json', 'biome.jsonc',\n 'ruff.toml', '.flake8', 'mypy.ini',\n 'clippy.toml', '.clippy.toml',\n '.golangci.yml', '.golangci.yaml',\n];\n\nexport async function analyzeQualitySignals(\n projectPath: string,\n fileDiscovery: FileDiscoveryResult,\n): Promise<QualitySignalsResult> {\n // Test ratio\n let testLoc = 0;\n let sourceLoc = 0;\n for (const [, stats] of Object.entries(fileDiscovery.languages)) {\n sourceLoc += stats.loc;\n }\n // Estimate test LOC from file discovery data — we'll use a heuristic based on the project\n // A more accurate version would track test files separately in file discovery\n testLoc = await estimateTestLoc(projectPath, fileDiscovery);\n const testRatio = sourceLoc > 0 ? Math.round((testLoc / sourceLoc) * 100) / 100 : 0;\n\n // Type safety\n const { typeSafety, typeSafetyDetails } = await checkTypeSafety(projectPath);\n\n // Secrets scan\n const { secretsClean, secretsFound } = await scanSecrets(projectPath);\n\n // Lint tools\n const lintTools: string[] = [];\n for (const config of LINT_CONFIGS) {\n if (existsSync(join(projectPath, config))) {\n const tool = config.includes('eslint') ? 'ESLint'\n : config.includes('prettier') ? 'Prettier'\n : config.includes('biome') ? 'Biome'\n : config.includes('ruff') ? 'Ruff'\n : config.includes('flake8') ? 'Flake8'\n : config.includes('mypy') ? 'mypy'\n : config.includes('clippy') ? 'Clippy'\n : config.includes('golangci') ? 'golangci-lint'\n : config;\n if (!lintTools.includes(tool)) lintTools.push(tool);\n }\n }\n\n // Complexity (simplified: count branching keywords per function)\n const complexityAvg = await estimateComplexity(projectPath, fileDiscovery);\n\n return {\n test_ratio: testRatio,\n complexity_avg: complexityAvg,\n type_safety: typeSafety,\n type_safety_details: typeSafetyDetails,\n secrets_clean: secretsClean,\n secrets_found: secretsFound,\n lint_tools: lintTools,\n };\n}\n\nasync function estimateTestLoc(\n projectPath: string,\n fileDiscovery: FileDiscoveryResult,\n): Promise<number> {\n // Rough estimate: count test files' LOC as a fraction of total\n // We'd need the full file list for precision, but we can estimate\n // by checking common test directories\n let testLoc = 0;\n const testDirs = ['__tests__', 'tests', 'test', 'spec'];\n\n for (const dir of testDirs) {\n if (existsSync(join(projectPath, dir))) {\n // Estimate ~20% of total LOC per test directory found\n testLoc += Math.round(fileDiscovery.total_loc * 0.05);\n }\n }\n\n // Also check for colocated test files\n if (fileDiscovery.config_files.some(f => f.includes('jest') || f.includes('vitest'))) {\n testLoc += Math.round(fileDiscovery.total_loc * 0.1);\n }\n\n return Math.min(testLoc, Math.round(fileDiscovery.total_loc * 0.5));\n}\n\nasync function checkTypeSafety(projectPath: string): Promise<{ typeSafety: boolean; typeSafetyDetails: string }> {\n // TypeScript strict mode\n const tsconfigPath = join(projectPath, 'tsconfig.json');\n if (existsSync(tsconfigPath)) {\n try {\n const content = await readFile(tsconfigPath, 'utf-8');\n const tsconfig = JSON.parse(content);\n if (tsconfig.compilerOptions?.strict === true) {\n return { typeSafety: true, typeSafetyDetails: 'TypeScript strict mode' };\n }\n return { typeSafety: false, typeSafetyDetails: 'TypeScript without strict mode' };\n } catch { /* skip */ }\n }\n\n // Python type checking\n if (existsSync(join(projectPath, 'mypy.ini')) ||\n existsSync(join(projectPath, 'pyrightconfig.json'))) {\n return { typeSafety: true, typeSafetyDetails: 'Python type checker configured' };\n }\n\n const pyprojectPath = join(projectPath, 'pyproject.toml');\n if (existsSync(pyprojectPath)) {\n try {\n const content = await readFile(pyprojectPath, 'utf-8');\n if (content.includes('[tool.mypy]') || content.includes('[tool.pyright]')) {\n return { typeSafety: true, typeSafetyDetails: 'Python type checker configured' };\n }\n } catch { /* skip */ }\n }\n\n return { typeSafety: false, typeSafetyDetails: 'No type checking configured' };\n}\n\nasync function scanSecrets(projectPath: string): Promise<{ secretsClean: boolean; secretsFound: number }> {\n let found = 0;\n // Check common files that might have secrets\n const filesToCheck = ['.env', '.env.local', '.env.production'];\n for (const file of filesToCheck) {\n const filePath = join(projectPath, file);\n if (existsSync(filePath)) {\n try {\n const content = await readFile(filePath, 'utf-8');\n for (const pattern of SECRET_PATTERNS) {\n const matches = content.match(pattern);\n if (matches) found += matches.length;\n }\n } catch { /* skip */ }\n }\n }\n\n return { secretsClean: found === 0, secretsFound: found };\n}\n\nasync function estimateComplexity(\n projectPath: string,\n fileDiscovery: FileDiscoveryResult,\n): Promise<number> {\n // Simplified cyclomatic complexity estimate\n // Count branching keywords relative to function count\n const branchKeywords = /\\b(if|else|elif|switch|case|for|while|catch|except|&&|\\|\\||\\?)\\b/g;\n\n // Read a sample of source files\n const tsconfigExists = existsSync(join(projectPath, 'tsconfig.json'));\n const mainFile = tsconfigExists\n ? join(projectPath, 'src', 'index.ts')\n : join(projectPath, 'src', 'index.js');\n\n if (!existsSync(mainFile)) {\n // Default moderate complexity\n return 3.5;\n }\n\n try {\n const content = await readFile(mainFile, 'utf-8');\n const branches = (content.match(branchKeywords) || []).length;\n const functions = (content.match(/\\b(function|def|fn|func)\\b/g) || []).length || 1;\n return Math.round((branches / functions) * 10) / 10;\n } catch {\n return 3.5;\n }\n}\n","import { existsSync } from 'fs';\nimport { join } from 'path';\nimport type { FileDiscoveryResult, AstAnalysisResult, ArchitecturePatternsResult } from '../graph/schema.js';\n\ninterface PatternSignals {\n name: string;\n score: number;\n maxSignals: number;\n}\n\nexport async function analyzeArchitecturePatterns(\n projectPath: string,\n fileDiscovery: FileDiscoveryResult,\n astAnalysis: AstAnalysisResult,\n): Promise<ArchitecturePatternsResult> {\n const patterns: PatternSignals[] = [\n detectServiceLayer(projectPath, astAnalysis),\n detectMvc(projectPath),\n detectEventDriven(astAnalysis),\n detectRepositoryPattern(astAnalysis),\n detectMicroservices(projectPath),\n detectMonorepo(projectPath),\n detectApiFirst(projectPath, fileDiscovery),\n ];\n\n const result: Record<string, number> = {};\n let primaryPattern: string | null = null;\n let highestScore = 0;\n\n for (const p of patterns) {\n const confidence = p.maxSignals > 0\n ? Math.round((p.score / p.maxSignals) * 100) / 100\n : 0;\n if (confidence >= 0.2) {\n result[p.name] = confidence;\n if (confidence > highestScore) {\n highestScore = confidence;\n primaryPattern = p.name;\n }\n }\n }\n\n return { patterns: result, primary_pattern: primaryPattern };\n}\n\nfunction detectServiceLayer(projectPath: string, ast: AstAnalysisResult): PatternSignals {\n let score = 0;\n const max = 5;\n\n if (ast.services > 0) score += 2;\n if (ast.services >= 3) score += 1;\n if (existsSync(join(projectPath, 'src', 'services')) || existsSync(join(projectPath, 'services'))) score += 1;\n if (existsSync(join(projectPath, 'src', 'controllers')) || existsSync(join(projectPath, 'controllers'))) score += 1;\n\n return { name: 'Service Layer', score, maxSignals: max };\n}\n\nfunction detectMvc(projectPath: string): PatternSignals {\n let score = 0;\n const max = 4;\n\n const mvcDirs = ['models', 'views', 'controllers', 'routes', 'handlers'];\n for (const dir of mvcDirs) {\n if (existsSync(join(projectPath, 'src', dir)) || existsSync(join(projectPath, dir))) {\n score += 1;\n }\n }\n\n return { name: 'MVC', score: Math.min(score, max), maxSignals: max };\n}\n\nfunction detectEventDriven(ast: AstAnalysisResult): PatternSignals {\n let score = 0;\n const max = 4;\n\n const eventPackages = ['events', 'eventemitter', 'amqplib', 'kafkajs', 'bullmq', 'ioredis', 'socket.io'];\n for (const pkg of eventPackages) {\n if (ast.imports_used.some(i => i.includes(pkg))) score += 1;\n }\n\n if (ast.advanced_features.includes('async-await')) score += 0.5;\n\n return { name: 'Event-Driven', score: Math.min(score, max), maxSignals: max };\n}\n\nfunction detectRepositoryPattern(ast: AstAnalysisResult): PatternSignals {\n let score = 0;\n const max = 4;\n\n // Check for repository/store classes\n if (ast.services > 0) score += 1; // Services often indicate repository pattern too\n if (ast.imports_used.some(i => ['prisma', '@prisma/client', 'typeorm', 'sequelize', 'drizzle-orm', 'mongoose'].includes(i))) {\n score += 2;\n }\n if (ast.imports_used.some(i => ['@supabase/supabase-js', 'firebase'].includes(i))) {\n score += 1;\n }\n\n return { name: 'Repository', score, maxSignals: max };\n}\n\nfunction detectMicroservices(projectPath: string): PatternSignals {\n let score = 0;\n const max = 4;\n\n if (existsSync(join(projectPath, 'docker-compose.yml')) || existsSync(join(projectPath, 'docker-compose.yaml'))) {\n score += 2;\n }\n if (existsSync(join(projectPath, 'Dockerfile'))) score += 1;\n if (existsSync(join(projectPath, 'k8s')) || existsSync(join(projectPath, 'kubernetes'))) score += 1;\n\n return { name: 'Microservices', score, maxSignals: max };\n}\n\nfunction detectMonorepo(projectPath: string): PatternSignals {\n let score = 0;\n const max = 4;\n\n if (existsSync(join(projectPath, 'turbo.json'))) score += 2;\n if (existsSync(join(projectPath, 'lerna.json'))) score += 2;\n if (existsSync(join(projectPath, 'pnpm-workspace.yaml'))) score += 2;\n if (existsSync(join(projectPath, 'packages'))) score += 1;\n if (existsSync(join(projectPath, 'apps'))) score += 1;\n\n return { name: 'Monorepo', score: Math.min(score, max), maxSignals: max };\n}\n\nfunction detectApiFirst(projectPath: string, fileDiscovery: FileDiscoveryResult): PatternSignals {\n let score = 0;\n const max = 4;\n\n const apiFiles = ['openapi.yml', 'openapi.yaml', 'openapi.json', 'swagger.yml', 'swagger.yaml', 'swagger.json'];\n for (const file of apiFiles) {\n if (existsSync(join(projectPath, file))) {\n score += 2;\n break;\n }\n }\n\n if (existsSync(join(projectPath, 'src', 'routes')) || existsSync(join(projectPath, 'routes'))) score += 1;\n if (existsSync(join(projectPath, 'src', 'api')) || existsSync(join(projectPath, 'api'))) score += 1;\n\n return { name: 'API-First', score, maxSignals: max };\n}\n","import { callHaiku, isApiKeyConfigured } from '../llm/client.js';\nimport type {\n FileDiscoveryResult,\n DependencyResult,\n AstAnalysisResult,\n GitForensicsResult,\n QualitySignalsResult,\n ArchitecturePatternsResult,\n LlmClassificationResult,\n} from '../graph/schema.js';\n\nconst SYSTEM_PROMPT = `You classify software projects based on analysis data.\nReturn JSON only, no markdown fences. Schema:\n{\n \"domain\": \"string (e.g., travel-tech, fintech, e-commerce, dev-tools)\",\n \"builder_profile\": \"string (e.g., engineer, PM-who-codes, builder, designer-who-ships)\",\n \"role_signals\": [\"string array of matching roles\"],\n \"is_end_to_end\": boolean,\n \"description\": \"1-2 sentence project description\"\n}`;\n\nexport async function classifyWithLlm(\n fileDiscovery: FileDiscoveryResult,\n dependencies: DependencyResult,\n astAnalysis: AstAnalysisResult,\n gitForensics: GitForensicsResult,\n qualitySignals: QualitySignalsResult,\n architecturePatterns: ArchitecturePatternsResult,\n): Promise<LlmClassificationResult | null> {\n if (!isApiKeyConfigured()) return null;\n\n const topLanguages = Object.entries(fileDiscovery.languages)\n .sort((a, b) => b[1].loc - a[1].loc)\n .slice(0, 5)\n .map(([lang, stats]) => `${lang} (${stats.loc.toLocaleString()} LOC)`)\n .join(', ');\n\n const patternStr = Object.entries(architecturePatterns.patterns)\n .map(([name, conf]) => `${name} (${conf})`)\n .join(', ') || 'none detected';\n\n const prompt = `Given this project analysis summary:\n Languages: ${topLanguages}\n Frameworks: ${dependencies.frameworks.join(', ') || 'none'}\n Structure: ${astAnalysis.functions} functions, ${astAnalysis.classes} classes, ${astAnalysis.components} components, ${astAnalysis.hooks} custom hooks\n Git: ${gitForensics.commits} commits, ${gitForensics.active_days} active days, ${gitForensics.contributors} contributors\n Quality: test ratio ${qualitySignals.test_ratio}, complexity ${qualitySignals.complexity_avg}, type safety: ${qualitySignals.type_safety}\n Patterns: ${patternStr}\n Imports: ${astAnalysis.imports_used.slice(0, 20).join(', ')}\n\nClassify this project:\n 1. Project domain\n 2. Builder profile\n 3. Role signals (what roles does this work suggest?)\n 4. End-to-end ownership? (single person across frontend+backend+infra?)\n 5. Brief project description (1-2 sentences)`;\n\n try {\n const response = await callHaiku(SYSTEM_PROMPT, prompt);\n const cleaned = response.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n const parsed = JSON.parse(cleaned);\n\n return {\n domain: parsed.domain || 'general',\n builder_profile: parsed.builder_profile || 'engineer',\n role_signals: parsed.role_signals || [],\n is_end_to_end: parsed.is_end_to_end || false,\n description: parsed.description || '',\n };\n } catch {\n return null;\n }\n}\n","import chalk from 'chalk';\nimport { loadGraph } from '../graph/skill-graph.js';\nimport { loadJson } from '../storage/store.js';\nimport type { BuilderIdentity } from '../graph/schema.js';\nimport * as log from '../utils/logger.js';\n\nexport async function statusCommand(): Promise<void> {\n const graph = await loadGraph();\n\n if (!graph || graph.projects.length === 0) {\n log.warn('No skill graph found.');\n log.info('Run `hiregraph init` to set up your profile.');\n log.info('Run `hiregraph scan <path>` to analyze a project.');\n return;\n }\n\n const identity = graph.builder_identity;\n\n log.header('\\n HireGraph Status\\n');\n\n // Builder info\n if (identity.name) {\n console.log(` ${chalk.bold('Builder:')} ${identity.name} (${identity.primary_role})`);\n }\n console.log(` ${chalk.bold('Projects scanned:')} ${graph.projects.length}`);\n console.log();\n\n // Tech Stack\n const skills = Object.entries(graph.tech_stack)\n .sort((a, b) => b[1].proficiency - a[1].proficiency)\n .slice(0, 10);\n\n if (skills.length > 0) {\n console.log(` ${chalk.bold('Tech Stack:')}`);\n const maxNameLen = Math.max(...skills.map(([name]) => name.length));\n\n for (const [name, skill] of skills) {\n const bar = renderBar(skill.proficiency, 20);\n const locStr = skill.loc > 0 ? `${skill.loc.toLocaleString()} LOC` : '';\n const projStr = skill.projects > 0 ? `${skill.projects} projects` : '';\n const details = [locStr, projStr].filter(Boolean).join(', ');\n console.log(` ${name.padEnd(maxNameLen + 2)} ${bar} ${skill.proficiency.toFixed(2)}${details ? ` (${details})` : ''}`);\n }\n console.log();\n }\n\n // Architecture\n const patterns = Object.entries(graph.architecture)\n .sort((a, b) => b[1].confidence - a[1].confidence);\n if (patterns.length > 0) {\n const patternStr = patterns\n .map(([name, { confidence }]) => `${name} (${confidence})`)\n .join(', ');\n console.log(` ${chalk.bold('Architecture:')} ${patternStr}`);\n }\n\n // Quality\n console.log(` ${chalk.bold('Quality:')} test ratio ${graph.quality.test_ratio}, complexity ${graph.quality.complexity_avg}${graph.quality.type_safety ? ', strict types' : ''}`);\n\n // Builder Profile\n if (graph.builder_profile.role_signals.length > 0) {\n console.log(` ${chalk.bold('Role Signals:')} ${graph.builder_profile.role_signals.join(', ')}`);\n }\n if (graph.builder_profile.is_end_to_end) {\n console.log(` ${chalk.bold('Builder Profile:')} End-to-end ownership detected`);\n }\n\n // Projects\n console.log();\n console.log(` ${chalk.bold('Projects:')}`);\n for (const project of graph.projects) {\n const age = getTimeAgo(project.scanned_at);\n console.log(` ${chalk.cyan(project.name)} — ${project.domain || 'unknown domain'} (scanned ${age})`);\n const stackStr = project.stack.slice(0, 5).join(', ');\n if (stackStr) console.log(` ${chalk.dim(stackStr)}`);\n }\n\n console.log();\n log.dim(` Last updated: ${getTimeAgo(graph.last_updated)}`);\n console.log();\n}\n\nfunction renderBar(value: number, width: number): string {\n const filled = Math.round(value * width);\n const empty = width - filled;\n return chalk.green('█'.repeat(filled)) + chalk.dim('░'.repeat(empty));\n}\n\nfunction getTimeAgo(isoDate: string): string {\n const diff = Date.now() - new Date(isoDate).getTime();\n const minutes = Math.floor(diff / 60000);\n if (minutes < 1) return 'just now';\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n","import chalk from 'chalk';\nimport { fetchAllJobs } from '../ats/fetcher.js';\nimport { loadRegistry } from '../ats/registry.js';\nimport * as log from '../utils/logger.js';\n\nexport async function jobsCommand(options: { refresh?: boolean; ats?: string; limit?: number }): Promise<void> {\n log.header('\\n HireGraph Jobs\\n');\n\n const companies = await loadRegistry();\n const ghCount = companies.filter(c => c.ats === 'greenhouse').length;\n const lvCount = companies.filter(c => c.ats === 'lever').length;\n const abCount = companies.filter(c => c.ats === 'ashby').length;\n log.info(` Registry: ${companies.length} companies (${ghCount} Greenhouse, ${lvCount} Lever, ${abCount} Ashby)\\n`);\n\n const result = await fetchAllJobs({ refresh: options.refresh, ats: options.ats });\n\n console.log();\n console.log(` ${chalk.bold('Jobs Fetched:')}`);\n if (result.stats.greenhouse > 0) {\n console.log(` Greenhouse ${result.stats.greenhouse.toLocaleString().padStart(6)} jobs`);\n }\n if (result.stats.lever > 0) {\n console.log(` Lever ${result.stats.lever.toLocaleString().padStart(6)} jobs`);\n }\n if (result.stats.ashby > 0) {\n console.log(` Ashby ${result.stats.ashby.toLocaleString().padStart(6)} jobs`);\n }\n console.log(` ${chalk.bold('Total')} ${chalk.bold(result.stats.total.toLocaleString().padStart(6))} jobs`);\n\n if (result.stats.failed > 0) {\n console.log();\n log.warn(` ${result.stats.failed} companies unreachable:`);\n for (const err of result.errors.slice(0, 10)) {\n log.dim(` ${err.company}: ${err.error}`);\n }\n if (result.errors.length > 10) {\n log.dim(` ... and ${result.errors.length - 10} more`);\n }\n }\n\n if (options.limit && options.limit > 0) {\n console.log();\n console.log(` ${chalk.bold('Sample jobs:')}`);\n const sample = result.jobs.slice(0, options.limit);\n for (const job of sample) {\n console.log(` ${chalk.cyan(job.title)} @ ${job.company} (${job.location})`);\n }\n }\n\n console.log();\n log.info(' Cached to ~/.hiregraph/jobs/');\n log.info(' Run `hiregraph matches` to find your best matches.');\n console.log();\n}\n","import { readFile } from 'fs/promises';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { existsSync } from 'fs';\nimport { loadJson } from '../storage/store.js';\nimport type { CompanyRegistryEntry } from '../graph/schema.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport async function loadRegistry(): Promise<CompanyRegistryEntry[]> {\n // Load bundled seed data — try multiple paths (dev vs built)\n const candidates = [\n join(__dirname, '..', 'data', 'companies.json'),\n join(__dirname, '..', '..', 'src', 'data', 'companies.json'),\n join(__dirname, 'data', 'companies.json'),\n ];\n\n let companies: CompanyRegistryEntry[] = [];\n for (const seedPath of candidates) {\n if (existsSync(seedPath)) {\n const raw = await readFile(seedPath, 'utf-8');\n companies = JSON.parse(raw);\n break;\n }\n }\n\n // Merge user overrides from ~/.hiregraph/companies.json\n const userCompanies = await loadJson<CompanyRegistryEntry[]>('companies.json');\n if (userCompanies) {\n const bySlug = new Map(companies.map(c => [c.slug, c]));\n for (const uc of userCompanies) {\n bySlug.set(uc.slug, uc);\n }\n companies = [...bySlug.values()];\n }\n\n return companies;\n}\n\nexport function filterByAts(companies: CompanyRegistryEntry[], ats: string): CompanyRegistryEntry[] {\n return companies.filter(c => c.ats === ats);\n}\n\nexport function excludeCompanies(companies: CompanyRegistryEntry[], slugs: string[]): CompanyRegistryEntry[] {\n const excluded = new Set(slugs);\n return companies.filter(c => !excluded.has(c.slug));\n}\n","export interface RawGreenhouseJob {\n id: number;\n title: string;\n absolute_url: string;\n location: { name: string };\n departments: Array<{ name: string }>;\n content: string;\n updated_at: string;\n}\n\nexport async function fetchGreenhouseJobs(boardToken: string): Promise<RawGreenhouseJob[]> {\n const url = `https://boards-api.greenhouse.io/v1/boards/${boardToken}/jobs?content=true`;\n\n const response = await fetch(url, {\n headers: { 'Accept': 'application/json' },\n signal: AbortSignal.timeout(15000),\n });\n\n if (!response.ok) {\n if (response.status === 429) throw new Error('Rate limited');\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data = await response.json() as { jobs: RawGreenhouseJob[] };\n return data.jobs || [];\n}\n","export interface RawLeverPosting {\n id: string;\n text: string;\n hostedUrl: string;\n categories: { location?: string; department?: string; team?: string };\n description: string;\n descriptionPlain: string;\n lists: Array<{ text: string; content: string }>;\n createdAt: number;\n}\n\nexport async function fetchLeverPostings(company: string): Promise<RawLeverPosting[]> {\n const url = `https://api.lever.co/v0/postings/${company}`;\n\n const response = await fetch(url, {\n headers: { 'Accept': 'application/json' },\n signal: AbortSignal.timeout(15000),\n });\n\n if (!response.ok) {\n if (response.status === 429) throw new Error('Rate limited');\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data = await response.json() as RawLeverPosting[];\n return Array.isArray(data) ? data : [];\n}\n","export interface RawAshbyJob {\n id: string;\n title: string;\n location: string;\n department: string;\n publishedAt: string;\n descriptionHtml: string;\n jobUrl: string;\n}\n\nexport async function fetchAshbyJobs(boardId: string): Promise<RawAshbyJob[]> {\n const url = `https://api.ashbyhq.com/posting-api/job-board/${boardId}`;\n\n const response = await fetch(url, {\n headers: { 'Accept': 'application/json' },\n signal: AbortSignal.timeout(15000),\n });\n\n if (!response.ok) {\n if (response.status === 429) throw new Error('Rate limited');\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data = await response.json() as { jobs: RawAshbyJob[] };\n return data.jobs || [];\n}\n","import type { CompanyRegistryEntry, JobListing } from '../graph/schema.js';\nimport type { RawGreenhouseJob } from './greenhouse.js';\nimport type { RawLeverPosting } from './lever.js';\nimport type { RawAshbyJob } from './ashby.js';\n\nfunction stripHtml(html: string): string {\n return html\n .replace(/<br\\s*\\/?>/gi, '\\n')\n .replace(/<\\/p>/gi, '\\n')\n .replace(/<\\/li>/gi, '\\n')\n .replace(/<[^>]+>/g, '')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/ /g, ' ')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim();\n}\n\nexport function normalizeGreenhouseJob(raw: RawGreenhouseJob, company: CompanyRegistryEntry): JobListing {\n return {\n id: `gh_${raw.id}`,\n source: 'greenhouse',\n company: company.name,\n company_slug: company.slug,\n title: raw.title,\n url: raw.absolute_url,\n location: raw.location?.name || 'Unknown',\n department: raw.departments?.[0]?.name,\n description_raw: stripHtml(raw.content || ''),\n updated_at: raw.updated_at,\n fetched_at: new Date().toISOString(),\n };\n}\n\nexport function normalizeLeverPosting(raw: RawLeverPosting, company: CompanyRegistryEntry): JobListing {\n const descParts = [raw.descriptionPlain || stripHtml(raw.description || '')];\n if (raw.lists) {\n for (const list of raw.lists) {\n descParts.push(`${list.text}\\n${stripHtml(list.content)}`);\n }\n }\n\n return {\n id: `lv_${raw.id}`,\n source: 'lever',\n company: company.name,\n company_slug: company.slug,\n title: raw.text,\n url: raw.hostedUrl,\n location: raw.categories?.location || 'Unknown',\n department: raw.categories?.department || raw.categories?.team,\n description_raw: descParts.join('\\n\\n'),\n posted_at: raw.createdAt ? new Date(raw.createdAt).toISOString() : undefined,\n fetched_at: new Date().toISOString(),\n };\n}\n\nexport function normalizeAshbyJob(raw: RawAshbyJob, company: CompanyRegistryEntry): JobListing {\n return {\n id: `ab_${raw.id}`,\n source: 'ashby',\n company: company.name,\n company_slug: company.slug,\n title: raw.title,\n url: raw.jobUrl || `https://jobs.ashbyhq.com/${company.board_token}/${raw.id}`,\n location: raw.location || 'Unknown',\n department: raw.department,\n description_raw: stripHtml(raw.descriptionHtml || ''),\n posted_at: raw.publishedAt,\n fetched_at: new Date().toISOString(),\n };\n}\n","import { loadRegistry, excludeCompanies, filterByAts } from './registry.js';\nimport { fetchGreenhouseJobs } from './greenhouse.js';\nimport { fetchLeverPostings } from './lever.js';\nimport { fetchAshbyJobs } from './ashby.js';\nimport { normalizeGreenhouseJob, normalizeLeverPosting, normalizeAshbyJob } from './normalizer.js';\nimport { loadSubJson, saveSubJson } from '../storage/store.js';\nimport { loadJson } from '../storage/store.js';\nimport type { CompanyRegistryEntry, JobListing, JobsCache } from '../graph/schema.js';\nimport * as spinner from '../utils/spinner.js';\nimport * as log from '../utils/logger.js';\n\nconst CACHE_MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24 hours\nconst BATCH_SIZE = 5;\nconst BATCH_DELAY_MS = 500;\n\nexport interface FetchResult {\n jobs: JobListing[];\n errors: Array<{ company: string; error: string }>;\n stats: { greenhouse: number; lever: number; ashby: number; total: number; failed: number };\n}\n\nfunction isCacheStale(fetchedAt: string): boolean {\n return Date.now() - new Date(fetchedAt).getTime() > CACHE_MAX_AGE_MS;\n}\n\nasync function delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nasync function fetchInBatches<T>(\n items: T[],\n fn: (item: T) => Promise<JobListing[]>,\n getName: (item: T) => string,\n errors: Array<{ company: string; error: string }>,\n): Promise<JobListing[]> {\n const allJobs: JobListing[] = [];\n\n for (let i = 0; i < items.length; i += BATCH_SIZE) {\n const batch = items.slice(i, i + BATCH_SIZE);\n const results = await Promise.allSettled(batch.map(item => fn(item)));\n\n for (let j = 0; j < results.length; j++) {\n const result = results[j];\n if (result.status === 'fulfilled') {\n allJobs.push(...result.value);\n } else {\n errors.push({ company: getName(batch[j]), error: result.reason?.message || 'Unknown error' });\n }\n }\n\n if (i + BATCH_SIZE < items.length) {\n await delay(BATCH_DELAY_MS);\n }\n }\n\n return allJobs;\n}\n\nexport async function fetchAllJobs(options?: { refresh?: boolean; ats?: string }): Promise<FetchResult> {\n const config = await loadJson<{ excluded_companies?: string[] }>('config.json');\n let companies = await loadRegistry();\n companies = excludeCompanies(companies, config?.excluded_companies || []);\n\n if (options?.ats) {\n companies = filterByAts(companies, options.ats);\n }\n\n const errors: Array<{ company: string; error: string }> = [];\n const allJobs: JobListing[] = [];\n const stats = { greenhouse: 0, lever: 0, ashby: 0, total: 0, failed: 0 };\n\n // Greenhouse\n const ghCompanies = companies.filter(c => c.ats === 'greenhouse');\n if (ghCompanies.length > 0) {\n const cached = await loadSubJson<JobsCache>('jobs', 'greenhouse.json');\n if (cached && !isCacheStale(cached.fetched_at) && !options?.refresh) {\n allJobs.push(...cached.jobs);\n stats.greenhouse = cached.total_jobs;\n } else {\n spinner.start(`Fetching from Greenhouse (${ghCompanies.length} companies)...`);\n const ghJobs = await fetchInBatches(\n ghCompanies,\n async (c) => {\n const raw = await fetchGreenhouseJobs(c.board_token);\n return raw.map(j => normalizeGreenhouseJob(j, c));\n },\n c => c.name,\n errors,\n );\n allJobs.push(...ghJobs);\n stats.greenhouse = ghJobs.length;\n spinner.succeed(`Greenhouse: ${ghJobs.length} jobs from ${ghCompanies.length} companies`);\n await saveSubJson('jobs', 'greenhouse.json', {\n source: 'greenhouse', fetched_at: new Date().toISOString(),\n companies_fetched: ghCompanies.length, total_jobs: ghJobs.length, jobs: ghJobs,\n } satisfies JobsCache);\n }\n }\n\n // Lever\n const lvCompanies = companies.filter(c => c.ats === 'lever');\n if (lvCompanies.length > 0) {\n const cached = await loadSubJson<JobsCache>('jobs', 'lever.json');\n if (cached && !isCacheStale(cached.fetched_at) && !options?.refresh) {\n allJobs.push(...cached.jobs);\n stats.lever = cached.total_jobs;\n } else {\n spinner.start(`Fetching from Lever (${lvCompanies.length} companies)...`);\n const lvJobs = await fetchInBatches(\n lvCompanies,\n async (c) => {\n const raw = await fetchLeverPostings(c.board_token);\n return raw.map(j => normalizeLeverPosting(j, c));\n },\n c => c.name,\n errors,\n );\n allJobs.push(...lvJobs);\n stats.lever = lvJobs.length;\n spinner.succeed(`Lever: ${lvJobs.length} jobs from ${lvCompanies.length} companies`);\n await saveSubJson('jobs', 'lever.json', {\n source: 'lever', fetched_at: new Date().toISOString(),\n companies_fetched: lvCompanies.length, total_jobs: lvJobs.length, jobs: lvJobs,\n } satisfies JobsCache);\n }\n }\n\n // Ashby\n const abCompanies = companies.filter(c => c.ats === 'ashby');\n if (abCompanies.length > 0) {\n const cached = await loadSubJson<JobsCache>('jobs', 'ashby.json');\n if (cached && !isCacheStale(cached.fetched_at) && !options?.refresh) {\n allJobs.push(...cached.jobs);\n stats.ashby = cached.total_jobs;\n } else {\n spinner.start(`Fetching from Ashby (${abCompanies.length} companies)...`);\n const abJobs = await fetchInBatches(\n abCompanies,\n async (c) => {\n const raw = await fetchAshbyJobs(c.board_token);\n return raw.map(j => normalizeAshbyJob(j, c));\n },\n c => c.name,\n errors,\n );\n allJobs.push(...abJobs);\n stats.ashby = abJobs.length;\n spinner.succeed(`Ashby: ${abJobs.length} jobs from ${abCompanies.length} companies`);\n await saveSubJson('jobs', 'ashby.json', {\n source: 'ashby', fetched_at: new Date().toISOString(),\n companies_fetched: abCompanies.length, total_jobs: abJobs.length, jobs: abJobs,\n } satisfies JobsCache);\n }\n }\n\n stats.total = allJobs.length;\n stats.failed = errors.length;\n\n return { jobs: allJobs, errors, stats };\n}\n","import chalk from 'chalk';\nimport { runMatchPipeline } from '../matching/matcher.js';\nimport { isApiKeyConfigured } from '../llm/client.js';\nimport type { MatchResult } from '../graph/schema.js';\nimport * as log from '../utils/logger.js';\n\nexport async function matchesCommand(options: { refresh?: boolean; top?: number; verbose?: boolean }): Promise<void> {\n log.header('\\n HireGraph Matches\\n');\n\n if (!isApiKeyConfigured()) {\n log.warn('No API key detected. Run hiregraph inside Claude Code or Cursor for automatic access.');\n return;\n }\n\n try {\n const result = await runMatchPipeline({\n topK: options.top || 50,\n refresh: options.refresh,\n });\n\n console.log();\n\n // Strong matches\n if (result.strong_matches.length > 0) {\n console.log(` ${chalk.bold.green('Strong Matches (score 8-10):')}`);\n for (let i = 0; i < result.strong_matches.length; i++) {\n printMatch(result.strong_matches[i], i + 1, true);\n }\n console.log();\n }\n\n // Suggested matches\n if (result.suggested_matches.length > 0) {\n console.log(` ${chalk.bold.yellow('Suggested Matches (score 6-7):')}`);\n for (let i = 0; i < result.suggested_matches.length; i++) {\n const idx = result.strong_matches.length + i + 1;\n printMatch(result.suggested_matches[i], idx, !!options.verbose);\n }\n console.log();\n }\n\n if (result.strong_matches.length === 0 && result.suggested_matches.length === 0) {\n log.warn(' No matches above threshold. Try scanning more projects or adjusting preferences.');\n console.log();\n }\n\n // Summary\n console.log(` ${chalk.bold('Summary:')}`);\n console.log(` Jobs analyzed: ${result.total_jobs_fetched.toLocaleString()}`);\n console.log(` Jobs parsed: ${result.total_jobs_parsed.toLocaleString()}`);\n console.log(` LLM evaluated: ${result.total_candidates_evaluated}`);\n console.log(` Strong matches: ${chalk.green(String(result.strong_matches.length))}`);\n console.log(` Suggested: ${chalk.yellow(String(result.suggested_matches.length))}`);\n console.log(` Cost estimate: ~$${result.cost_estimate.estimated_usd.toFixed(2)}`);\n console.log();\n log.info(` Results saved to ~/.hiregraph/matches/${result.date}.json`);\n console.log();\n } catch (err: any) {\n log.error(err.message);\n process.exit(1);\n }\n}\n\nfunction printMatch(match: MatchResult, rank: number, showDetails: boolean): void {\n const scoreColor = match.score >= 8 ? chalk.green : chalk.yellow;\n console.log(` ${chalk.dim(`#${rank}`)} ${scoreColor(match.score.toFixed(1))} ${chalk.bold(match.job_title)} @ ${match.company}`);\n\n if (showDetails) {\n if (match.strengths.length > 0) {\n console.log(` ${chalk.green('+')} ${match.strengths.join(', ')}`);\n }\n if (match.gaps.length > 0) {\n console.log(` ${chalk.red('-')} ${match.gaps.join(', ')}`);\n }\n console.log(` ${chalk.dim(match.url)}`);\n }\n}\n","import { callHaikuJson, isApiKeyConfigured } from '../llm/client.js';\nimport { loadSubJson, saveSubJson } from '../storage/store.js';\nimport type { JobListing, ParsedJobRequirements, ParsedJobsCache } from '../graph/schema.js';\nimport * as spinner from '../utils/spinner.js';\n\nconst SYSTEM_PROMPT = `You extract structured job requirements from job descriptions.\nReturn JSON only, no markdown fences. Schema:\n{\n \"must_have_skills\": [\"string array\"],\n \"nice_to_have_skills\": [\"string array\"],\n \"seniority_level\": \"junior|mid|senior|staff|principal|lead|manager\",\n \"tech_stack\": [\"specific technologies mentioned\"],\n \"domain\": \"string (e.g., fintech, dev-tools, e-commerce)\",\n \"remote_policy\": \"remote|hybrid|onsite|unknown\",\n \"compensation_range\": { \"min\": number|null, \"max\": number|null, \"currency\": \"USD\" } | null\n}`;\n\nconst BATCH_SIZE = 10;\nconst BATCH_DELAY_MS = 1000;\n\nexport async function parseJobsBatch(\n jobs: JobListing[],\n): Promise<Record<string, ParsedJobRequirements>> {\n if (!isApiKeyConfigured()) {\n throw new Error('No API key detected. Run hiregraph inside Claude Code or Cursor.');\n }\n\n // Load existing cache\n const cached = await loadSubJson<ParsedJobsCache>('jobs', 'parsed.json');\n const requirements: Record<string, ParsedJobRequirements> = cached?.requirements || {};\n\n // Find unparsed jobs\n const unparsed = jobs.filter(j => !requirements[j.id]);\n if (unparsed.length === 0) return requirements;\n\n spinner.start(`Parsing ${unparsed.length} new job descriptions...`);\n let parsed = 0;\n\n for (let i = 0; i < unparsed.length; i += BATCH_SIZE) {\n const batch = unparsed.slice(i, i + BATCH_SIZE);\n\n const results = await Promise.allSettled(\n batch.map(job => parseOneJob(job)),\n );\n\n for (let j = 0; j < results.length; j++) {\n if (results[j].status === 'fulfilled') {\n const req = (results[j] as PromiseFulfilledResult<ParsedJobRequirements>).value;\n requirements[batch[j].id] = req;\n parsed++;\n }\n }\n\n if (i + BATCH_SIZE < unparsed.length) {\n await new Promise(r => setTimeout(r, BATCH_DELAY_MS));\n }\n }\n\n spinner.succeed(`Parsed ${parsed} job descriptions (${Object.keys(requirements).length} total cached)`);\n\n // Save updated cache\n await saveSubJson('jobs', 'parsed.json', {\n parsed_at: new Date().toISOString(),\n requirements,\n } satisfies ParsedJobsCache);\n\n return requirements;\n}\n\nasync function parseOneJob(job: JobListing): Promise<ParsedJobRequirements> {\n const description = job.description_raw.slice(0, 4000); // Limit to ~4K chars\n\n const result = await callHaikuJson<Omit<ParsedJobRequirements, 'job_id' | 'parsed_at'>>(\n SYSTEM_PROMPT,\n `Job: ${job.title} at ${job.company}\\nLocation: ${job.location}\\n\\n${description}`,\n );\n\n return {\n job_id: job.id,\n must_have_skills: result.must_have_skills || [],\n nice_to_have_skills: result.nice_to_have_skills || [],\n seniority_level: result.seniority_level || 'mid',\n tech_stack: result.tech_stack || [],\n domain: result.domain || 'unknown',\n remote_policy: result.remote_policy || 'unknown',\n compensation_range: result.compensation_range || undefined,\n parsed_at: new Date().toISOString(),\n };\n}\n","import type { SkillGraph, ParsedJobRequirements } from '../graph/schema.js';\n\nconst STOP_WORDS = new Set([\n 'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',\n 'of', 'with', 'by', 'from', 'is', 'are', 'was', 'were', 'be', 'been',\n 'being', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would',\n 'could', 'should', 'may', 'might', 'can', 'shall', 'not', 'no', 'nor',\n 'so', 'if', 'then', 'than', 'that', 'this', 'these', 'those', 'it',\n 'its', 'we', 'you', 'he', 'she', 'they', 'our', 'your', 'their',\n 'who', 'which', 'what', 'where', 'when', 'how', 'all', 'each', 'every',\n 'both', 'few', 'more', 'most', 'other', 'some', 'such', 'only', 'very',\n 'also', 'just', 'about', 'up', 'out', 'as', 'into', 'through', 'over',\n 'after', 'before', 'between', 'under', 'above', 'while', 'during',\n 'experience', 'work', 'working', 'ability', 'strong', 'team', 'role',\n 'position', 'company', 'using', 'used', 'use', 'years', 'year',\n]);\n\nexport interface TermVector {\n terms: Map<number, number>; // term index -> weight\n magnitude: number;\n}\n\nexport interface Vocabulary {\n termToIndex: Map<string, number>;\n idf: Float32Array;\n size: number;\n}\n\nfunction tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9.#+\\-_/]/g, ' ')\n .split(/\\s+/)\n .filter(t => t.length > 1 && !STOP_WORDS.has(t));\n}\n\nexport function buildVocabulary(documents: string[][]): Vocabulary {\n // Count document frequency for each term\n const docFreq = new Map<string, number>();\n const allTerms = new Set<string>();\n\n for (const doc of documents) {\n const seen = new Set<string>();\n for (const term of doc) {\n allTerms.add(term);\n if (!seen.has(term)) {\n seen.add(term);\n docFreq.set(term, (docFreq.get(term) || 0) + 1);\n }\n }\n }\n\n // Filter to top 2000 terms by document frequency, excluding very rare terms\n const sorted = [...allTerms]\n .filter(t => (docFreq.get(t) || 0) >= 2)\n .sort((a, b) => (docFreq.get(b) || 0) - (docFreq.get(a) || 0))\n .slice(0, 2000);\n\n const termToIndex = new Map<string, number>();\n const idf = new Float32Array(sorted.length);\n const N = documents.length;\n\n for (let i = 0; i < sorted.length; i++) {\n termToIndex.set(sorted[i], i);\n const df = docFreq.get(sorted[i]) || 1;\n idf[i] = Math.log(N / df) + 1; // smoothed IDF\n }\n\n return { termToIndex, idf, size: sorted.length };\n}\n\nfunction vectorize(tokens: string[], vocab: Vocabulary): TermVector {\n const tf = new Map<number, number>();\n\n for (const token of tokens) {\n const idx = vocab.termToIndex.get(token);\n if (idx !== undefined) {\n tf.set(idx, (tf.get(idx) || 0) + 1);\n }\n }\n\n // TF-IDF weighting\n const terms = new Map<number, number>();\n let magnitude = 0;\n\n for (const [idx, count] of tf) {\n const weight = count * vocab.idf[idx];\n terms.set(idx, weight);\n magnitude += weight * weight;\n }\n\n magnitude = Math.sqrt(magnitude);\n return { terms, magnitude };\n}\n\nexport function buildSkillVector(graph: SkillGraph, vocab: Vocabulary): TermVector {\n const tokens: string[] = [];\n\n // Tech stack with proficiency weighting\n for (const [skill, data] of Object.entries(graph.tech_stack)) {\n const name = skill.toLowerCase();\n const repeat = data.proficiency > 0.5 ? 3 : data.proficiency > 0.3 ? 2 : 1;\n for (let i = 0; i < repeat; i++) {\n tokens.push(...tokenize(name));\n }\n }\n\n // Architecture patterns\n for (const [pattern] of Object.entries(graph.architecture)) {\n tokens.push(...tokenize(pattern));\n }\n\n // Role signals\n for (const signal of graph.builder_profile.role_signals) {\n tokens.push(...tokenize(signal));\n }\n\n // Project domains and stacks\n for (const proj of graph.projects) {\n if (proj.domain) tokens.push(...tokenize(proj.domain));\n for (const s of proj.stack) tokens.push(...tokenize(s));\n }\n\n return vectorize(tokens, vocab);\n}\n\nexport function buildJobVector(req: ParsedJobRequirements, vocab: Vocabulary): TermVector {\n const tokens: string[] = [];\n\n // Must-have skills get 2x weight\n for (const skill of req.must_have_skills) {\n const t = tokenize(skill);\n tokens.push(...t, ...t); // 2x\n }\n\n // Nice-to-have skills 1x\n for (const skill of req.nice_to_have_skills) {\n tokens.push(...tokenize(skill));\n }\n\n // Tech stack\n for (const tech of req.tech_stack) {\n tokens.push(...tokenize(tech));\n }\n\n // Domain\n if (req.domain) tokens.push(...tokenize(req.domain));\n\n return vectorize(tokens, vocab);\n}\n\nexport function cosineSimilarity(a: TermVector, b: TermVector): number {\n if (a.magnitude === 0 || b.magnitude === 0) return 0;\n\n let dotProduct = 0;\n // Iterate over the smaller vector\n const [smaller, larger] = a.terms.size <= b.terms.size ? [a, b] : [b, a];\n\n for (const [idx, weight] of smaller.terms) {\n const otherWeight = larger.terms.get(idx);\n if (otherWeight !== undefined) {\n dotProduct += weight * otherWeight;\n }\n }\n\n return dotProduct / (a.magnitude * b.magnitude);\n}\n\nexport function buildAllDocuments(\n graph: SkillGraph,\n requirements: Record<string, ParsedJobRequirements>,\n): string[][] {\n const docs: string[][] = [];\n\n // Skill graph as a document\n const skillTokens: string[] = [];\n for (const skill of Object.keys(graph.tech_stack)) {\n skillTokens.push(...tokenize(skill));\n }\n for (const proj of graph.projects) {\n for (const s of proj.stack) skillTokens.push(...tokenize(s));\n if (proj.domain) skillTokens.push(...tokenize(proj.domain));\n }\n docs.push(skillTokens);\n\n // Each job as a document\n for (const req of Object.values(requirements)) {\n const tokens: string[] = [];\n for (const s of req.must_have_skills) tokens.push(...tokenize(s));\n for (const s of req.nice_to_have_skills) tokens.push(...tokenize(s));\n for (const s of req.tech_stack) tokens.push(...tokenize(s));\n if (req.domain) tokens.push(...tokenize(req.domain));\n docs.push(tokens);\n }\n\n return docs;\n}\n","import type { TermVector } from './vectorizer.js';\nimport { cosineSimilarity } from './vectorizer.js';\n\nexport interface CandidateMatch {\n jobId: string;\n similarity: number;\n}\n\nexport function findTopCandidates(\n skillVector: TermVector,\n jobVectors: Map<string, TermVector>,\n k: number,\n): CandidateMatch[] {\n // Brute-force cosine similarity — fast enough for <10K jobs\n const scored: CandidateMatch[] = [];\n\n for (const [jobId, jobVector] of jobVectors) {\n const sim = cosineSimilarity(skillVector, jobVector);\n if (sim > 0) {\n scored.push({ jobId, similarity: sim });\n }\n }\n\n // Sort descending by similarity, return top K\n scored.sort((a, b) => b.similarity - a.similarity);\n return scored.slice(0, k);\n}\n","import type { JobListing, ParsedJobRequirements } from '../graph/schema.js';\n\nexport interface FilterConfig {\n excluded_companies: string[];\n remote_preference?: string;\n min_compensation?: string;\n}\n\nexport interface FilterableJob {\n job: JobListing;\n requirements: ParsedJobRequirements;\n}\n\nexport function applyHardFilters(\n jobs: FilterableJob[],\n config: FilterConfig,\n): FilterableJob[] {\n const excluded = new Set(config.excluded_companies.map(s => s.toLowerCase()));\n\n return jobs.filter(({ job, requirements }) => {\n // Excluded companies\n if (excluded.has(job.company_slug.toLowerCase())) return false;\n\n // Remote preference\n if (config.remote_preference === 'Remote' && requirements.remote_policy === 'onsite') {\n return false;\n }\n\n // Min compensation\n if (config.min_compensation && requirements.compensation_range?.max) {\n const min = parseCompensation(config.min_compensation);\n if (min > 0 && requirements.compensation_range.max < min) {\n return false;\n }\n }\n\n return true;\n });\n}\n\nfunction parseCompensation(value: string): number {\n // Handle various formats: \"150000\", \"150,000\", \"150k\", \"$150,000\", \"35,00,000\" (Indian)\n const cleaned = value.replace(/[$,]/g, '').trim();\n if (cleaned.toLowerCase().endsWith('k')) {\n return parseFloat(cleaned) * 1000;\n }\n return parseFloat(cleaned) || 0;\n}\n","import { callHaikuJson, isApiKeyConfigured } from '../llm/client.js';\nimport type { SkillGraph, MatchResult, JobListing, ParsedJobRequirements } from '../graph/schema.js';\nimport * as spinner from '../utils/spinner.js';\n\nconst SYSTEM_PROMPT = `You evaluate job-candidate match quality. Given a candidate's verified skill profile and a job's requirements, score the match.\n\nRules:\n- code-verified skills are confirmed facts. Weight heavily.\n- self-reported skills are unverified claims. Weight lower.\n- Proficiency scores: 0.8+ is strong, 0.5+ is moderate, below 0.3 is beginner.\n- For 'builder' profiles, value end-to-end ownership over single-area depth.\n- Be strict. 7/10 = genuinely strong match. 8+ = exceptional fit.\n\nReturn JSON only, no markdown fences. Schema:\n{\n \"score\": number (1-10),\n \"confidence\": number (0.0-1.0),\n \"reasoning\": \"2-3 sentences explaining the match\",\n \"strengths\": [\"key matching strengths\"],\n \"gaps\": [\"notable gaps or missing skills\"]\n}`;\n\nconst BATCH_SIZE = 5;\nconst BATCH_DELAY_MS = 1500;\n\ninterface EvalInput {\n job: JobListing;\n requirements: ParsedJobRequirements;\n}\n\nexport async function evaluateMatchesBatch(\n candidates: EvalInput[],\n graph: SkillGraph,\n): Promise<MatchResult[]> {\n if (!isApiKeyConfigured()) {\n throw new Error('No API key detected. Run hiregraph inside Claude Code or Cursor.');\n }\n\n const skillSummary = buildSkillSummary(graph);\n const results: MatchResult[] = [];\n\n spinner.start(`Evaluating ${candidates.length} matches with LLM...`);\n\n for (let i = 0; i < candidates.length; i += BATCH_SIZE) {\n const batch = candidates.slice(i, i + BATCH_SIZE);\n\n const batchResults = await Promise.allSettled(\n batch.map(({ job, requirements }) => evaluateOne(skillSummary, job, requirements)),\n );\n\n for (let j = 0; j < batchResults.length; j++) {\n if (batchResults[j].status === 'fulfilled') {\n results.push((batchResults[j] as PromiseFulfilledResult<MatchResult>).value);\n }\n }\n\n if (i + BATCH_SIZE < candidates.length) {\n await new Promise(r => setTimeout(r, BATCH_DELAY_MS));\n }\n }\n\n spinner.succeed(`Evaluated ${results.length} matches`);\n return results;\n}\n\nasync function evaluateOne(\n skillSummary: string,\n job: JobListing,\n requirements: ParsedJobRequirements,\n): Promise<MatchResult> {\n const jobSummary = buildJobSummary(job, requirements);\n\n const prompt = `CANDIDATE PROFILE:\\n${skillSummary}\\n\\nJOB:\\n${jobSummary}`;\n\n const result = await callHaikuJson<{\n score: number;\n confidence: number;\n reasoning: string;\n strengths: string[];\n gaps: string[];\n }>(SYSTEM_PROMPT, prompt, 2048);\n\n const score = Math.min(10, Math.max(1, result.score || 1));\n const tier = score >= 8 ? 'strong' : score >= 6 ? 'suggested' : 'filtered';\n\n return {\n job_id: job.id,\n job_title: job.title,\n company: job.company,\n company_slug: job.company_slug,\n url: job.url,\n score,\n confidence: result.confidence || 0.5,\n tier,\n reasoning: result.reasoning || '',\n strengths: result.strengths || [],\n gaps: result.gaps || [],\n matched_at: new Date().toISOString(),\n };\n}\n\nfunction buildSkillSummary(graph: SkillGraph): string {\n const lines: string[] = [];\n\n if (graph.builder_identity.name) {\n lines.push(`Name: ${graph.builder_identity.name} (${graph.builder_identity.primary_role})`);\n }\n\n // Tech stack\n const skills = Object.entries(graph.tech_stack)\n .sort((a, b) => b[1].proficiency - a[1].proficiency)\n .slice(0, 15);\n\n if (skills.length > 0) {\n lines.push('Tech Stack (code-verified):');\n for (const [name, data] of skills) {\n lines.push(` ${name}: proficiency ${data.proficiency}, ${data.loc.toLocaleString()} LOC, ${data.projects} projects`);\n }\n }\n\n // Architecture\n const patterns = Object.entries(graph.architecture)\n .sort((a, b) => b[1].confidence - a[1].confidence);\n if (patterns.length > 0) {\n lines.push(`Architecture: ${patterns.map(([n, { confidence }]) => `${n} (${confidence})`).join(', ')}`);\n }\n\n // Quality\n lines.push(`Quality: test ratio ${graph.quality.test_ratio}, complexity ${graph.quality.complexity_avg}`);\n\n // Projects\n if (graph.projects.length > 0) {\n lines.push(`Projects (${graph.projects.length}):`);\n for (const proj of graph.projects.slice(0, 5)) {\n lines.push(` ${proj.name}: ${proj.domain || 'unknown'} — ${proj.stack.slice(0, 5).join(', ')}`);\n }\n }\n\n // Builder profile\n if (graph.builder_profile.role_signals.length > 0) {\n lines.push(`Role signals: ${graph.builder_profile.role_signals.join(', ')}`);\n }\n if (graph.builder_profile.is_end_to_end) {\n lines.push('End-to-end builder: yes');\n }\n\n // Work history\n if (graph.builder_identity.previous_companies.length > 0) {\n lines.push('Work history:');\n for (const w of graph.builder_identity.previous_companies) {\n lines.push(` ${w.role} @ ${w.company} (${w.start_year}-${w.end_year || 'present'})`);\n }\n }\n\n return lines.join('\\n');\n}\n\nfunction buildJobSummary(job: JobListing, req: ParsedJobRequirements): string {\n const lines = [\n `Title: ${job.title}`,\n `Company: ${job.company}`,\n `Location: ${job.location}`,\n `Seniority: ${req.seniority_level}`,\n `Domain: ${req.domain}`,\n `Remote: ${req.remote_policy}`,\n ];\n\n if (req.must_have_skills.length > 0) {\n lines.push(`Must have: ${req.must_have_skills.join(', ')}`);\n }\n if (req.nice_to_have_skills.length > 0) {\n lines.push(`Nice to have: ${req.nice_to_have_skills.join(', ')}`);\n }\n if (req.tech_stack.length > 0) {\n lines.push(`Tech stack: ${req.tech_stack.join(', ')}`);\n }\n\n return lines.join('\\n');\n}\n","import { loadGraph } from '../graph/skill-graph.js';\nimport { loadJson } from '../storage/store.js';\nimport { fetchAllJobs } from '../ats/fetcher.js';\nimport { parseJobsBatch } from './job-parser.js';\nimport { buildVocabulary, buildSkillVector, buildJobVector, buildAllDocuments } from './vectorizer.js';\nimport { findTopCandidates } from './similarity.js';\nimport { applyHardFilters, type FilterConfig, type FilterableJob } from './filters.js';\nimport { evaluateMatchesBatch } from './evaluator.js';\nimport { saveSubJson } from '../storage/store.js';\nimport type { SkillGraph, JobListing, ParsedJobRequirements, MatchResult, MatchRun } from '../graph/schema.js';\nimport * as spinner from '../utils/spinner.js';\nimport * as log from '../utils/logger.js';\n\nexport interface MatchPipelineOptions {\n topK?: number;\n refresh?: boolean;\n maxEval?: number;\n}\n\nexport async function runMatchPipeline(options?: MatchPipelineOptions): Promise<MatchRun> {\n const topK = options?.topK || 50;\n const maxEval = options?.maxEval || 50;\n\n // 1. Load skill graph\n const graph = await loadGraph();\n if (!graph || graph.projects.length === 0) {\n throw new Error('No skill graph found. Run `hiregraph scan <path>` first.');\n }\n\n // 2. Load identity and config for filters\n const identity = graph.builder_identity;\n const config = await loadJson<{ excluded_companies?: string[] }>('config.json');\n const filterConfig: FilterConfig = {\n excluded_companies: config?.excluded_companies || [],\n remote_preference: identity.remote_preference,\n min_compensation: identity.min_compensation,\n };\n\n // 3. Fetch jobs (from cache or fresh)\n const fetchResult = await fetchAllJobs({ refresh: options?.refresh });\n const allJobs = fetchResult.jobs;\n\n if (allJobs.length === 0) {\n throw new Error('No jobs found. Run `hiregraph jobs` first.');\n }\n\n // 4. Parse job descriptions (incremental, cached)\n const requirements = await parseJobsBatch(allJobs);\n\n // 5. Build filterable job pairs\n const jobMap = new Map<string, JobListing>();\n for (const job of allJobs) jobMap.set(job.id, job);\n\n const filterableJobs: FilterableJob[] = [];\n for (const [jobId, req] of Object.entries(requirements)) {\n const job = jobMap.get(jobId);\n if (job) filterableJobs.push({ job, requirements: req });\n }\n\n // 6. Apply hard filters\n spinner.start('Applying filters...');\n const filtered = applyHardFilters(filterableJobs, filterConfig);\n spinner.succeed(`After filtering: ${filtered.length} jobs (from ${filterableJobs.length})`);\n\n if (filtered.length === 0) {\n throw new Error('All jobs filtered out. Try adjusting your preferences.');\n }\n\n // 7. Build TF-IDF vocabulary and vectors\n spinner.start('Building vectors for matching...');\n const filteredReqs: Record<string, ParsedJobRequirements> = {};\n for (const f of filtered) filteredReqs[f.job.id] = f.requirements;\n\n const documents = buildAllDocuments(graph, filteredReqs);\n const vocab = buildVocabulary(documents);\n\n const skillVector = buildSkillVector(graph, vocab);\n const jobVectors = new Map<string, ReturnType<typeof buildJobVector>>();\n for (const f of filtered) {\n jobVectors.set(f.job.id, buildJobVector(f.requirements, vocab));\n }\n spinner.succeed(`Vectorized ${filtered.length} jobs`);\n\n // 8. Pre-filter: find top K by vector similarity\n spinner.start(`Pre-filtering top ${topK} candidates...`);\n const candidates = findTopCandidates(skillVector, jobVectors, topK);\n spinner.succeed(`Top ${candidates.length} candidates selected`);\n\n // 9. LLM evaluation\n const evalInputs = candidates.slice(0, maxEval).map(c => {\n const job = jobMap.get(c.jobId)!;\n const req = requirements[c.jobId];\n return { job, requirements: req };\n });\n\n const matchResults = await evaluateMatchesBatch(evalInputs, graph);\n\n // 10. Categorize\n matchResults.sort((a, b) => b.score - a.score);\n const strong = matchResults.filter(m => m.tier === 'strong');\n const suggested = matchResults.filter(m => m.tier === 'suggested');\n\n // 11. Save match run\n const today = new Date().toISOString().slice(0, 10);\n const matchRun: MatchRun = {\n date: today,\n total_jobs_fetched: allJobs.length,\n total_jobs_parsed: Object.keys(requirements).length,\n total_candidates_evaluated: matchResults.length,\n strong_matches: strong,\n suggested_matches: suggested,\n run_at: new Date().toISOString(),\n cost_estimate: {\n jobs_parsed: Object.keys(requirements).length,\n pairs_evaluated: matchResults.length,\n estimated_usd: Math.round((Object.keys(requirements).length * 0.0003 + matchResults.length * 0.003) * 100) / 100,\n },\n };\n\n await saveSubJson('matches', `${today}.json`, matchRun);\n\n return matchRun;\n}\n","import chalk from 'chalk';\nimport inquirer from 'inquirer';\nimport { loadGraph } from '../graph/skill-graph.js';\nimport { loadSubJson } from '../storage/store.js';\nimport { loadHistory, addApplication, findByJobId, generateAppId } from '../history/tracker.js';\nimport { tailorResume } from '../resume/tailorer.js';\nimport { generateResumePdf, saveResumePdf } from '../resume/pdf-builder.js';\nimport { submitApplication } from '../ats/submitter.js';\nimport { isApiKeyConfigured } from '../llm/client.js';\nimport type { MatchRun, MatchResult, JobListing, ParsedJobRequirements, JobsCache, ParsedJobsCache } from '../graph/schema.js';\nimport * as log from '../utils/logger.js';\nimport * as spinner from '../utils/spinner.js';\n\nexport async function applyCommand(\n jobId?: string,\n options?: { allAbove?: number; review?: boolean; dryRun?: boolean },\n): Promise<void> {\n log.header('\\n HireGraph Apply\\n');\n\n if (!isApiKeyConfigured()) {\n log.warn('No API key detected. Run hiregraph inside Claude Code or Cursor.');\n return;\n }\n\n const graph = await loadGraph();\n if (!graph || graph.projects.length === 0) {\n log.error('No skill graph found. Run `hiregraph scan <path>` first.');\n return;\n }\n\n if (!graph.builder_identity.name || !graph.builder_identity.email) {\n log.error('Name and email required. Run `hiregraph init` first.');\n return;\n }\n\n // Load latest matches\n const matchRun = await loadLatestMatches();\n if (!matchRun) {\n log.error('No match results found. Run `hiregraph matches` first.');\n return;\n }\n\n // Load jobs and requirements caches\n const jobsMap = await loadJobsMap();\n const requirementsMap = await loadRequirementsMap();\n\n const history = await loadHistory();\n\n // Determine which matches to apply to\n let targets: MatchResult[];\n\n if (options?.allAbove !== undefined) {\n const threshold = options.allAbove;\n const allMatches = [...matchRun.strong_matches, ...matchRun.suggested_matches];\n targets = allMatches.filter(m => m.score >= threshold);\n log.info(` Found ${targets.length} matches with score >= ${threshold}\\n`);\n } else if (jobId) {\n const allMatches = [...matchRun.strong_matches, ...matchRun.suggested_matches];\n const match = allMatches.find(m => m.job_id === jobId);\n if (!match) {\n log.error(`Match not found for job ID: ${jobId}`);\n log.info('Available matches:');\n for (const m of allMatches.slice(0, 10)) {\n console.log(` ${chalk.dim(m.job_id)} ${m.job_title} @ ${m.company} (${m.score})`);\n }\n return;\n }\n targets = [match];\n } else {\n log.error('Provide a job-id or use --all-above <score>');\n log.info('Usage: hiregraph apply <job-id> [--review] [--dry-run]');\n log.info(' hiregraph apply --all-above 8');\n return;\n }\n\n let applied = 0;\n let skipped = 0;\n let failed = 0;\n\n for (const match of targets) {\n // Check if already applied\n if (findByJobId(history, match.job_id)) {\n log.dim(` Skipped (already applied): ${match.job_title} @ ${match.company}`);\n skipped++;\n continue;\n }\n\n const job = jobsMap.get(match.job_id);\n const requirements = requirementsMap[match.job_id];\n\n if (!job || !requirements) {\n log.warn(` Skipped (missing data): ${match.job_title} @ ${match.company}`);\n failed++;\n continue;\n }\n\n console.log(`\\n ${chalk.bold(match.job_title)} @ ${match.company} (score: ${chalk.green(String(match.score))})`);\n\n // Tailor resume\n spinner.start('Tailoring resume...');\n let tailoring;\n try {\n tailoring = await tailorResume(graph, job, requirements, match);\n spinner.succeed('Resume tailored');\n } catch (err: any) {\n spinner.fail(`Tailoring failed: ${err.message}`);\n failed++;\n continue;\n }\n\n // Review mode\n if (options?.review) {\n console.log();\n console.log(` ${chalk.bold('Summary:')} ${tailoring.professional_summary}`);\n console.log(` ${chalk.bold('Projects:')} ${tailoring.project_order.join(' > ')}`);\n console.log(` ${chalk.bold('Skills:')} ${tailoring.skills_order.slice(0, 8).join(', ')}`);\n console.log(` ${chalk.bold('Strengths:')} ${match.strengths.join(', ')}`);\n console.log(` ${chalk.bold('Gaps:')} ${match.gaps.join(', ')}`);\n console.log();\n\n const { proceed } = await inquirer.prompt([{\n type: 'confirm',\n name: 'proceed',\n message: 'Apply to this job?',\n default: true,\n }]);\n\n if (!proceed) {\n log.dim(' Skipped by user');\n skipped++;\n continue;\n }\n }\n\n // Generate PDF\n spinner.start('Generating resume PDF...');\n let pdfBuffer: Buffer;\n let resumePath: string;\n try {\n pdfBuffer = await generateResumePdf(graph, tailoring);\n resumePath = await saveResumePdf(pdfBuffer, match.job_id);\n spinner.succeed(`Resume saved: ${resumePath}`);\n } catch (err: any) {\n spinner.fail(`PDF generation failed: ${err.message}`);\n failed++;\n continue;\n }\n\n // Dry run — stop here\n if (options?.dryRun) {\n log.success(` [dry-run] Resume generated but not submitted`);\n applied++;\n continue;\n }\n\n // Submit\n spinner.start('Submitting application...');\n const result = await submitApplication(job, pdfBuffer, graph.builder_identity);\n if (result.success) {\n spinner.succeed(result.message);\n\n // Record in history\n const appId = generateAppId();\n await addApplication({\n id: appId,\n job_id: match.job_id,\n job_title: match.job_title,\n company: match.company,\n company_slug: match.company_slug,\n url: match.url,\n ats_source: job.source,\n match_score: match.score,\n resume_path: resumePath,\n status: 'applied',\n applied_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n });\n\n log.success(` Applied! (${appId})`);\n applied++;\n } else {\n spinner.fail(result.message);\n failed++;\n }\n\n // Delay between batch submissions\n if (targets.length > 1) {\n await new Promise(r => setTimeout(r, 2000));\n }\n }\n\n // Summary\n console.log();\n console.log(` ${chalk.bold('Summary:')}`);\n console.log(` Applied: ${chalk.green(String(applied))}`);\n if (skipped > 0) console.log(` Skipped: ${chalk.yellow(String(skipped))}`);\n if (failed > 0) console.log(` Failed: ${chalk.red(String(failed))}`);\n console.log();\n}\n\nasync function loadLatestMatches(): Promise<MatchRun | null> {\n // Try today first, then yesterday\n const today = new Date().toISOString().slice(0, 10);\n let run = await loadSubJson<MatchRun>('matches', `${today}.json`);\n if (run) return run;\n\n const yesterday = new Date(Date.now() - 86400000).toISOString().slice(0, 10);\n run = await loadSubJson<MatchRun>('matches', `${yesterday}.json`);\n return run;\n}\n\nasync function loadJobsMap(): Promise<Map<string, JobListing>> {\n const map = new Map<string, JobListing>();\n for (const source of ['greenhouse', 'lever', 'ashby'] as const) {\n const cache = await loadSubJson<JobsCache>('jobs', `${source}.json`);\n if (cache) {\n for (const job of cache.jobs) {\n map.set(job.id, job);\n }\n }\n }\n return map;\n}\n\nasync function loadRequirementsMap(): Promise<Record<string, ParsedJobRequirements>> {\n const cache = await loadSubJson<ParsedJobsCache>('jobs', 'parsed.json');\n return cache?.requirements || {};\n}\n","import { loadJson, saveJson } from '../storage/store.js';\nimport type { ApplicationHistory, ApplicationRecord, ApplicationStatus } from '../graph/schema.js';\n\nconst HISTORY_FILE = 'history.json';\n\nexport async function loadHistory(): Promise<ApplicationHistory> {\n const data = await loadJson<ApplicationHistory>(HISTORY_FILE);\n return data || { applications: [], last_updated: new Date().toISOString() };\n}\n\nexport async function saveHistory(history: ApplicationHistory): Promise<void> {\n history.last_updated = new Date().toISOString();\n await saveJson(HISTORY_FILE, history);\n}\n\nexport async function addApplication(record: ApplicationRecord): Promise<void> {\n const history = await loadHistory();\n history.applications.push(record);\n await saveHistory(history);\n}\n\nexport async function updateApplicationStatus(\n appId: string,\n status: ApplicationStatus,\n notes?: string,\n): Promise<ApplicationRecord | null> {\n const history = await loadHistory();\n const app = history.applications.find(\n a => a.id === appId || a.id.startsWith(appId),\n );\n if (!app) return null;\n\n app.status = status;\n app.updated_at = new Date().toISOString();\n if (notes) app.notes = notes;\n\n await saveHistory(history);\n return app;\n}\n\nexport function findByJobId(\n history: ApplicationHistory,\n jobId: string,\n): ApplicationRecord | undefined {\n return history.applications.find(a => a.job_id === jobId);\n}\n\nexport function generateAppId(): string {\n const ts = Date.now().toString(36).slice(-4);\n const rand = Math.random().toString(36).slice(2, 6);\n return `app_${ts}${rand}`;\n}\n","import { callHaikuJson } from '../llm/client.js';\nimport type { SkillGraph, JobListing, ParsedJobRequirements, MatchResult, ResumeTailoring } from '../graph/schema.js';\n\nconst SYSTEM_PROMPT = `You tailor a resume for a specific job. Given the candidate's skill data and target job, produce a tailored resume configuration.\n\nRules:\n- professional_summary: Write 3-4 sentences as if the candidate wrote them. No mention of scores, tools, analysis systems, or automation. Sound natural and specific to this role.\n- project_order: Rank the candidate's projects by relevance to this job. Most relevant first. Use exact project names.\n- bullet_emphasis: For each project, write 2-4 resume bullet points that best align with the job. Start with action verbs, include metrics where possible (commits, LOC, active days).\n- skills_order: List the candidate's tech skills reordered by relevance to this job. Most relevant first. Use exact skill names from the profile.\n\nReturn JSON only, no markdown fences. Schema:\n{\n \"professional_summary\": \"string\",\n \"project_order\": [\"project names\"],\n \"bullet_emphasis\": { \"ProjectName\": [\"bullet1\", \"bullet2\"] },\n \"skills_order\": [\"skill names\"]\n}`;\n\nexport async function tailorResume(\n graph: SkillGraph,\n job: JobListing,\n requirements: ParsedJobRequirements,\n match: MatchResult,\n): Promise<ResumeTailoring> {\n const identity = graph.builder_identity;\n\n const profileLines = [\n `Name: ${identity.name}`,\n `Role: ${identity.primary_role}`,\n ];\n\n // Tech stack\n const skills = Object.entries(graph.tech_stack)\n .sort((a, b) => b[1].proficiency - a[1].proficiency)\n .slice(0, 15);\n if (skills.length > 0) {\n profileLines.push('Skills (code-verified):');\n for (const [name, data] of skills) {\n profileLines.push(` ${name}: ${data.loc.toLocaleString()} LOC, ${data.projects} projects`);\n }\n }\n\n // Projects\n if (graph.projects.length > 0) {\n profileLines.push('Projects:');\n for (const proj of graph.projects) {\n profileLines.push(` ${proj.name}: ${proj.domain} — ${proj.stack.slice(0, 5).join(', ')} — ${proj.commits} commits, ${proj.active_days} active days`);\n if (proj.description) profileLines.push(` ${proj.description}`);\n }\n }\n\n // Work history\n if (identity.previous_companies.length > 0) {\n profileLines.push('Work History:');\n for (const w of identity.previous_companies) {\n profileLines.push(` ${w.role} @ ${w.company} (${w.start_year}-${w.end_year || 'present'})`);\n }\n }\n\n const jobLines = [\n `Title: ${job.title}`,\n `Company: ${job.company}`,\n `Must have: ${requirements.must_have_skills.join(', ')}`,\n `Nice to have: ${requirements.nice_to_have_skills.join(', ')}`,\n `Tech stack: ${requirements.tech_stack.join(', ')}`,\n `Domain: ${requirements.domain}`,\n `Match strengths: ${match.strengths.join(', ')}`,\n ];\n\n const prompt = `CANDIDATE PROFILE:\\n${profileLines.join('\\n')}\\n\\nTARGET JOB:\\n${jobLines.join('\\n')}`;\n\n const result = await callHaikuJson<{\n professional_summary: string;\n project_order: string[];\n bullet_emphasis: Record<string, string[]>;\n skills_order: string[];\n }>(SYSTEM_PROMPT, prompt, 2048);\n\n return {\n job_id: job.id,\n professional_summary: result.professional_summary || '',\n project_order: result.project_order || graph.projects.map(p => p.name),\n bullet_emphasis: result.bullet_emphasis || {},\n skills_order: result.skills_order || Object.keys(graph.tech_stack),\n generated_at: new Date().toISOString(),\n };\n}\n","import PDFDocument from 'pdfkit';\nimport { writeFile } from 'fs/promises';\nimport { ensureSubDir } from '../storage/store.js';\nimport { getPath } from '../storage/store.js';\nimport { join } from 'path';\nimport type { SkillGraph, ResumeTailoring, WorkHistory, ProjectEntry, Education } from '../graph/schema.js';\n\nconst MARGIN = 54; // 0.75 inch\nconst PAGE_WIDTH = 612; // Letter\nconst CONTENT_WIDTH = PAGE_WIDTH - MARGIN * 2;\nconst FONT_BODY = 'Helvetica';\nconst FONT_BOLD = 'Helvetica-Bold';\nconst SIZE_NAME = 18;\nconst SIZE_SECTION = 12;\nconst SIZE_BODY = 10.5;\nconst SIZE_SMALL = 9.5;\nconst COLOR_BLACK = '#000000';\nconst COLOR_GRAY = '#444444';\n\nconst SKILL_CATEGORIES: Record<string, string[]> = {\n Languages: ['TypeScript', 'JavaScript', 'Python', 'Rust', 'Go', 'Java', 'C', 'C++', 'C#', 'Ruby', 'PHP', 'Swift', 'Kotlin', 'Dart', 'Scala', 'Elixir', 'Haskell', 'SQL', 'Shell', 'Lua', 'R', 'Zig'],\n Frameworks: ['React', 'React Native', 'Next.js', 'Vue', 'Nuxt', 'Svelte', 'SvelteKit', 'Angular', 'Express', 'Fastify', 'NestJS', 'Django', 'Flask', 'FastAPI', 'Actix', 'Axum', 'Gin', 'Fiber', 'Expo', 'Hono', 'Remix', 'Astro', 'Gatsby', 'Solid'],\n 'Data & AI': ['Prisma', 'Drizzle', 'TypeORM', 'Sequelize', 'Mongoose', 'SQLAlchemy', 'Pandas', 'NumPy', 'TensorFlow', 'PyTorch', 'LangChain', 'Anthropic SDK', 'OpenAI'],\n Infrastructure: ['Supabase', 'Firebase', 'Docker', 'Kubernetes', 'AWS', 'GCP', 'Azure', 'Vercel', 'Tokio', 'Serde'],\n};\n\nexport async function generateResumePdf(\n graph: SkillGraph,\n tailoring: ResumeTailoring,\n): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const doc = new PDFDocument({\n size: 'LETTER',\n margins: { top: MARGIN, bottom: MARGIN, left: MARGIN, right: MARGIN },\n });\n\n const chunks: Buffer[] = [];\n doc.on('data', (chunk: Buffer) => chunks.push(chunk));\n doc.on('end', () => resolve(Buffer.concat(chunks)));\n doc.on('error', reject);\n\n const identity = graph.builder_identity;\n\n // Header\n doc.font(FONT_BOLD).fontSize(SIZE_NAME).fillColor(COLOR_BLACK);\n doc.text(identity.name || 'Builder', { align: 'center' });\n doc.moveDown(0.3);\n\n const contactParts: string[] = [];\n if (identity.email) contactParts.push(identity.email);\n if (identity.phone) contactParts.push(identity.phone);\n const linkParts: string[] = [];\n for (const [, url] of Object.entries(identity.links || {})) {\n if (url) linkParts.push(url);\n }\n\n doc.font(FONT_BODY).fontSize(SIZE_SMALL).fillColor(COLOR_GRAY);\n if (contactParts.length > 0) {\n doc.text(contactParts.join(' | '), { align: 'center' });\n }\n if (linkParts.length > 0) {\n doc.text(linkParts.join(' | '), { align: 'center' });\n }\n doc.moveDown(0.8);\n\n // Professional Summary\n renderSectionHeader(doc, 'PROFESSIONAL SUMMARY');\n doc.font(FONT_BODY).fontSize(SIZE_BODY).fillColor(COLOR_BLACK);\n doc.text(tailoring.professional_summary, { lineGap: 2 });\n doc.moveDown(0.6);\n\n // Technical Skills\n renderSectionHeader(doc, 'TECHNICAL SKILLS');\n const categorized = categorizeSkills(tailoring.skills_order, graph);\n doc.font(FONT_BODY).fontSize(SIZE_BODY).fillColor(COLOR_BLACK);\n for (const [category, skills] of Object.entries(categorized)) {\n if (skills.length > 0) {\n doc.font(FONT_BOLD).text(`${category}: `, { continued: true });\n doc.font(FONT_BODY).text(skills.join(', '));\n }\n }\n doc.moveDown(0.6);\n\n // Work Experience\n if (identity.previous_companies && identity.previous_companies.length > 0) {\n renderSectionHeader(doc, 'WORK EXPERIENCE');\n for (const work of identity.previous_companies) {\n renderWorkEntry(doc, work);\n }\n doc.moveDown(0.3);\n }\n\n // Projects\n if (graph.projects.length > 0) {\n renderSectionHeader(doc, 'PROJECTS');\n const orderedProjects = orderProjects(graph.projects, tailoring.project_order);\n for (const proj of orderedProjects.slice(0, 4)) {\n renderProject(doc, proj, tailoring.bullet_emphasis[proj.name] || []);\n }\n doc.moveDown(0.3);\n }\n\n // Education\n if (identity.education && identity.education.length > 0) {\n renderSectionHeader(doc, 'EDUCATION');\n for (const edu of identity.education) {\n renderEducation(doc, edu);\n }\n }\n\n doc.end();\n });\n}\n\nexport async function saveResumePdf(pdfBuffer: Buffer, jobId: string): Promise<string> {\n await ensureSubDir('resumes');\n const filename = `${jobId.replace(/[^a-zA-Z0-9_-]/g, '_')}.pdf`;\n const filepath = join(getPath('resumes'), filename);\n await writeFile(filepath, pdfBuffer);\n return filepath;\n}\n\nfunction renderSectionHeader(doc: PDFKit.PDFDocument, title: string): void {\n doc.font(FONT_BOLD).fontSize(SIZE_SECTION).fillColor(COLOR_BLACK);\n doc.text(title);\n doc.moveTo(MARGIN, doc.y + 2).lineTo(PAGE_WIDTH - MARGIN, doc.y + 2).strokeColor(COLOR_GRAY).lineWidth(0.5).stroke();\n doc.moveDown(0.4);\n}\n\nfunction renderWorkEntry(doc: PDFKit.PDFDocument, work: WorkHistory): void {\n const dateRange = `${work.start_year} - ${work.end_year || 'Present'}`;\n doc.font(FONT_BOLD).fontSize(SIZE_BODY).fillColor(COLOR_BLACK);\n doc.text(`${work.role}`, { continued: true });\n doc.font(FONT_BODY).text(` | ${work.company}`);\n doc.font(FONT_BODY).fontSize(SIZE_SMALL).fillColor(COLOR_GRAY);\n doc.text(dateRange);\n doc.fillColor(COLOR_BLACK).fontSize(SIZE_BODY);\n\n if (work.bullets && work.bullets.length > 0) {\n for (const bullet of work.bullets) {\n doc.text(` • ${bullet}`, { indent: 10, lineGap: 1 });\n }\n }\n doc.moveDown(0.4);\n}\n\nfunction renderProject(doc: PDFKit.PDFDocument, proj: ProjectEntry, bullets: string[]): void {\n const stackStr = proj.stack.slice(0, 5).join(', ');\n doc.font(FONT_BOLD).fontSize(SIZE_BODY).fillColor(COLOR_BLACK);\n doc.text(proj.name, { continued: true });\n doc.font(FONT_BODY).fillColor(COLOR_GRAY).text(` | ${proj.domain || 'project'} | ${stackStr}`);\n doc.fillColor(COLOR_BLACK);\n\n if (proj.description) {\n doc.font(FONT_BODY).fontSize(SIZE_BODY).text(proj.description, { lineGap: 1 });\n }\n\n const displayBullets = bullets.length > 0 ? bullets : generateDefaultBullets(proj);\n for (const bullet of displayBullets.slice(0, 3)) {\n doc.text(` • ${bullet}`, { indent: 10, lineGap: 1 });\n }\n doc.moveDown(0.4);\n}\n\nfunction renderEducation(doc: PDFKit.PDFDocument, edu: Education): void {\n doc.font(FONT_BOLD).fontSize(SIZE_BODY).fillColor(COLOR_BLACK);\n doc.text(`${edu.degree} in ${edu.field}`, { continued: true });\n doc.font(FONT_BODY).text(` | ${edu.institution} | ${edu.year}`);\n}\n\nfunction orderProjects(projects: ProjectEntry[], order: string[]): ProjectEntry[] {\n const byName = new Map(projects.map(p => [p.name, p]));\n const ordered: ProjectEntry[] = [];\n for (const name of order) {\n const proj = byName.get(name);\n if (proj) {\n ordered.push(proj);\n byName.delete(name);\n }\n }\n // Append any not mentioned in order\n for (const proj of byName.values()) {\n ordered.push(proj);\n }\n return ordered;\n}\n\nfunction categorizeSkills(\n skillsOrder: string[],\n graph: SkillGraph,\n): Record<string, string[]> {\n const allSkills = skillsOrder.length > 0 ? skillsOrder : Object.keys(graph.tech_stack);\n const result: Record<string, string[]> = {};\n const used = new Set<string>();\n\n for (const [category, known] of Object.entries(SKILL_CATEGORIES)) {\n const knownLower = new Set(known.map(k => k.toLowerCase()));\n const matched = allSkills.filter(s => knownLower.has(s.toLowerCase()) && !used.has(s.toLowerCase()));\n if (matched.length > 0) {\n result[category] = matched;\n matched.forEach(s => used.add(s.toLowerCase()));\n }\n }\n\n const remaining = allSkills.filter(s => !used.has(s.toLowerCase()));\n if (remaining.length > 0) {\n result['Other'] = remaining;\n }\n\n return result;\n}\n\nfunction generateDefaultBullets(proj: ProjectEntry): string[] {\n const bullets: string[] = [];\n if (proj.commits > 0) {\n bullets.push(`${proj.commits} commits over ${proj.active_days} active days${proj.contributors > 1 ? ` with ${proj.contributors} contributors` : ''}`);\n }\n const langStr = Object.entries(proj.languages)\n .sort((a, b) => b[1].loc - a[1].loc)\n .slice(0, 3)\n .map(([lang, { loc }]) => `${lang} (${loc.toLocaleString()} LOC)`)\n .join(', ');\n if (langStr) bullets.push(`Built with ${langStr}`);\n return bullets;\n}\n","import FormData from 'form-data';\nimport { loadRegistry } from './registry.js';\nimport type { JobListing, BuilderIdentity, CompanyRegistryEntry } from '../graph/schema.js';\n\nexport interface SubmitResult {\n success: boolean;\n message: string;\n status?: number;\n}\n\nexport async function submitApplication(\n job: JobListing,\n pdfBuffer: Buffer,\n identity: BuilderIdentity,\n): Promise<SubmitResult> {\n const registry = await loadRegistry();\n const company = registry.find(c => c.slug === job.company_slug);\n if (!company) {\n return { success: false, message: `Company not found in registry: ${job.company_slug}` };\n }\n\n const { source, rawId } = extractRawJobId(job.id);\n\n switch (source) {\n case 'greenhouse':\n return submitToGreenhouse(company.board_token, rawId, pdfBuffer, identity);\n case 'lever':\n return submitToLever(company.board_token, rawId, pdfBuffer, identity);\n case 'ashby':\n return submitToAshby(rawId, pdfBuffer, identity);\n default:\n return { success: false, message: `Unknown ATS source: ${source}` };\n }\n}\n\nfunction extractRawJobId(normalizedId: string): { source: string; rawId: string } {\n if (normalizedId.startsWith('gh_')) return { source: 'greenhouse', rawId: normalizedId.slice(3) };\n if (normalizedId.startsWith('lv_')) return { source: 'lever', rawId: normalizedId.slice(3) };\n if (normalizedId.startsWith('ab_')) return { source: 'ashby', rawId: normalizedId.slice(3) };\n return { source: 'unknown', rawId: normalizedId };\n}\n\nasync function submitToGreenhouse(\n boardToken: string,\n rawJobId: string,\n pdfBuffer: Buffer,\n identity: BuilderIdentity,\n): Promise<SubmitResult> {\n const url = `https://boards-api.greenhouse.io/v1/boards/${boardToken}/jobs/${rawJobId}`;\n\n const nameParts = (identity.name || '').split(' ');\n const firstName = nameParts[0] || '';\n const lastName = nameParts.slice(1).join(' ') || '';\n\n const form = new FormData();\n form.append('first_name', firstName);\n form.append('last_name', lastName);\n form.append('email', identity.email);\n if (identity.phone) form.append('phone', identity.phone);\n form.append('resume', pdfBuffer, { filename: 'resume.pdf', contentType: 'application/pdf' });\n\n // Add links as URLs\n if (identity.links?.github) form.append('urls[GitHub]', identity.links.github);\n if (identity.links?.linkedin) form.append('urls[LinkedIn]', identity.links.linkedin);\n if (identity.links?.portfolio) form.append('urls[Portfolio]', identity.links.portfolio);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: form.getHeaders(),\n body: form.getBuffer(),\n signal: AbortSignal.timeout(30000),\n });\n\n if (response.ok) {\n return { success: true, message: 'Application submitted via Greenhouse', status: response.status };\n }\n\n const body = await response.text().catch(() => '');\n return { success: false, message: `Greenhouse HTTP ${response.status}: ${body.slice(0, 200)}`, status: response.status };\n } catch (err: any) {\n return { success: false, message: `Greenhouse error: ${err.message}` };\n }\n}\n\nasync function submitToLever(\n boardToken: string,\n rawPostingId: string,\n pdfBuffer: Buffer,\n identity: BuilderIdentity,\n): Promise<SubmitResult> {\n const url = `https://api.lever.co/v0/postings/${boardToken}/${rawPostingId}`;\n\n const form = new FormData();\n form.append('name', identity.name || '');\n form.append('email', identity.email);\n if (identity.phone) form.append('phone', identity.phone);\n form.append('resume', pdfBuffer, { filename: 'resume.pdf', contentType: 'application/pdf' });\n\n if (identity.links?.github) form.append('urls[GitHub]', identity.links.github);\n if (identity.links?.linkedin) form.append('urls[LinkedIn]', identity.links.linkedin);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: form.getHeaders(),\n body: form.getBuffer(),\n signal: AbortSignal.timeout(30000),\n });\n\n if (response.ok) {\n return { success: true, message: 'Application submitted via Lever', status: response.status };\n }\n\n const body = await response.text().catch(() => '');\n return { success: false, message: `Lever HTTP ${response.status}: ${body.slice(0, 200)}`, status: response.status };\n } catch (err: any) {\n return { success: false, message: `Lever error: ${err.message}` };\n }\n}\n\nasync function submitToAshby(\n rawJobId: string,\n pdfBuffer: Buffer,\n identity: BuilderIdentity,\n): Promise<SubmitResult> {\n const url = 'https://api.ashbyhq.com/posting-api/applicationForm.submit';\n\n const nameParts = (identity.name || '').split(' ');\n\n const body = {\n jobPostingId: rawJobId,\n applicationForm: {\n firstName: nameParts[0] || '',\n lastName: nameParts.slice(1).join(' ') || '',\n email: identity.email,\n phone: identity.phone || '',\n resume: {\n filename: 'resume.pdf',\n mimeType: 'application/pdf',\n data: pdfBuffer.toString('base64'),\n },\n },\n };\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(30000),\n });\n\n if (response.ok) {\n return { success: true, message: 'Application submitted via Ashby', status: response.status };\n }\n\n const respBody = await response.text().catch(() => '');\n return { success: false, message: `Ashby HTTP ${response.status}: ${respBody.slice(0, 200)}`, status: response.status };\n } catch (err: any) {\n return { success: false, message: `Ashby error: ${err.message}` };\n }\n}\n","import chalk from 'chalk';\nimport { loadHistory, updateApplicationStatus } from '../history/tracker.js';\nimport type { ApplicationStatus } from '../graph/schema.js';\nimport * as log from '../utils/logger.js';\n\nconst VALID_STATUSES: ApplicationStatus[] = [\n 'applied', 'screening', 'interview', 'offer', 'rejected', 'withdrawn', 'no-response',\n];\n\nconst STATUS_COLORS: Record<string, (s: string) => string> = {\n applied: chalk.cyan,\n screening: chalk.blue,\n interview: chalk.green,\n offer: chalk.bold.green,\n rejected: chalk.red,\n withdrawn: chalk.dim,\n 'no-response': chalk.yellow,\n};\n\nexport async function historyCommand(\n action?: string,\n id?: string,\n options?: { status?: string; notes?: string },\n): Promise<void> {\n if (action === 'update' && id) {\n await handleUpdate(id, options?.status, options?.notes);\n return;\n }\n\n await handleList();\n}\n\nasync function handleList(): Promise<void> {\n const history = await loadHistory();\n\n if (history.applications.length === 0) {\n log.info('\\n No applications yet. Run `hiregraph apply <job-id>` to apply.\\n');\n return;\n }\n\n log.header(`\\n HireGraph Application History (${history.applications.length})\\n`);\n\n const sorted = [...history.applications].sort(\n (a, b) => new Date(b.applied_at).getTime() - new Date(a.applied_at).getTime(),\n );\n\n for (const app of sorted) {\n const colorFn = STATUS_COLORS[app.status] || chalk.white;\n const age = getTimeAgo(app.applied_at);\n console.log(\n ` ${chalk.dim(app.id.padEnd(14))} ${app.job_title.padEnd(35)} @ ${app.company.padEnd(18)} ${colorFn(app.status.padEnd(12))} ${chalk.dim(age)}`,\n );\n if (app.notes) {\n console.log(` ${' '.repeat(14)} ${chalk.dim(`Notes: ${app.notes}`)}`);\n }\n }\n\n console.log();\n}\n\nasync function handleUpdate(id: string, status?: string, notes?: string): Promise<void> {\n if (!status) {\n log.error(`Status required. Valid: ${VALID_STATUSES.join(', ')}`);\n return;\n }\n\n if (!VALID_STATUSES.includes(status as ApplicationStatus)) {\n log.error(`Invalid status \"${status}\". Valid: ${VALID_STATUSES.join(', ')}`);\n return;\n }\n\n const updated = await updateApplicationStatus(id, status as ApplicationStatus, notes);\n if (!updated) {\n log.error(`Application not found: ${id}`);\n return;\n }\n\n const colorFn = STATUS_COLORS[updated.status] || chalk.white;\n log.success(`Updated ${updated.id}: ${updated.job_title} @ ${updated.company} -> ${colorFn(updated.status)}`);\n}\n\nfunction getTimeAgo(isoDate: string): string {\n const diff = Date.now() - new Date(isoDate).getTime();\n const minutes = Math.floor(diff / 60000);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n"],"mappings":"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","names":["existsSync","readFile","readFile","existsSync","resolve","existsSync","readFile","join","extname","readFile","join","existsSync","join","extname","readFile","readFile","join","existsSync","readFile","readdir","join","extname","relative","readFile","extname","current","readdir","join","relative","existsSync","join","readFile","join","existsSync","existsSync","join","readFile","existsSync","join","SYSTEM_PROMPT","resolve","existsSync","chalk","chalk","chalk","readFile","join","existsSync","join","existsSync","readFile","resolve","chalk","chalk","SYSTEM_PROMPT","BATCH_SIZE","BATCH_DELAY_MS","SYSTEM_PROMPT","BATCH_SIZE","BATCH_DELAY_MS","chalk","chalk","inquirer","SYSTEM_PROMPT","writeFile","join","resolve","writeFile","chalk","inquirer","chalk","chalk","getTimeAgo"]}
|