Skip to content

feat: Add Hiring Copilot Agent AgentKit#98

Merged
d-pamneja merged 22 commits intoLamatic:mainfrom
anuraag-5:feat/hiring-copilot-agent
Mar 31, 2026
Merged

feat: Add Hiring Copilot Agent AgentKit#98
d-pamneja merged 22 commits intoLamatic:mainfrom
anuraag-5:feat/hiring-copilot-agent

Conversation

@anuraag-5
Copy link
Copy Markdown
Contributor

@anuraag-5 anuraag-5 commented Mar 24, 2026

🚀 What This Kit Does

Hiring Copilot Agent is an AI-powered recruiter assistant that automates resume screening and candidate evaluation. It reduces the manual effort required by HR teams to review multiple resumes by intelligently analyzing candidate data, scoring relevance, and providing hiring recommendations.

This kit demonstrates how AI can streamline hiring workflows, making recruitment faster, more scalable, and data-driven.


🔌 Providers & Prerequisites

  • Lamatic AI (for flow orchestration)
  • OpenAI_API_KEY (for File Scanning)
  • Node.js (v18+)
  • npm (v9+)

Setup Required:

  • A deployed Lamatic flow
  • Valid API keys and project configuration from Lamatic

⚙️ How to Run Locally

  1. cd kits/agentic/hiring-copilot-agent

  2. npm install

  3. cp .env.example .env and fill in values:

    • AGENTIC_GENERATE_CONTENT
    • LAMATIC_API_URL
    • LAMATIC_PROJECT_ID
    • LAMATIC_API_KEY
    • OPENAI_API_KEY
  4. npm run dev


🌐 Live Preview

https://hiring-copilot-agent.vercel.app/


🔗 Lamatic Flow

Flow ID: 78c33d5b-a3fb-4db1-99b8-21859ad4c22f

Hiring Copilot Agent - Files Added Summary

Core Application Files

  • Next.js Setup: next.config.ts, tsconfig.json, eslint.config.mjs, postcss.config.mjs, package.json
  • Environment: .env.example, .gitignore (root + project-level)
  • Styling: app/globals.css, app/fonts.ts (Poppins, Dela Gothic One, Jost fonts)
  • Root Layout: app/layout.tsx with Sonner Toaster, metadata
  • Landing Page: app/page.tsx

Configuration Files

  • components.json (shadcn UI generator config)
  • config.json (agent metadata & mandatory flow binding)
  • orchestrate.js (Lamatic flow orchestration with input/output schemas)

API & Server Actions

  • actions/orchestrate.ts - Server action executing Lamatic workflow
  • app/api/parse-resume/route.ts - Resume file upload → OpenAI Files API → gpt-4o-mini parsing
  • app/api/evaluate/route.ts - Candidate evaluation via Lamatic workflow

Client Components

  • components/header.tsx - Animated header with logo, docs/GitHub links
  • components/MainPart.tsx - Main UI: job description input, resume file upload, batch processing (5 resumes/batch), evaluation display
  • components/Toast.tsx - Custom toast UI wrapper
  • components/theme-provider.tsx - next-themes integration

UI Component Library (50+ Components)

Accordion, Alert Dialog, Alert, Aspect Ratio, Avatar, Badge, Breadcrumb, Button Group, Calendar, Card, Carousel, Chart, Checkbox, Collapsible, Command, Context Menu, Dialog, Drawer, Dropdown Menu, Empty State, Field, Form, Hover Card, Input Group, Input OTP, Input, Item, Kbd, Label, Menubar, Navigation Menu, Pagination, Popover, Progress, Radio Group, Resizable, Scroll Area, Select, Separator, Sheet, Sidebar, Skeleton, Slider, Spinner, Switch, Table, Tabs, Textarea, Toast UI, Toggle, Toggle Group, Tooltip, Toaster

Utilities & Hooks

  • lib/lamatic-client.ts - Lamatic SDK with env validation
  • lib/types.ts - ToastProps interface
  • lib/utils.ts - cn() class merging, getMedal() ranking badges
  • hooks/use-mobile.ts, use-debounce.ts, use-toast.ts - React hooks

Lamatic AI Flow (flows/first-flow/)

Configuration (config.json, inputs.json, meta.json, README.md)

Workflow Architecture (6 sequential nodes):

  1. triggerNode - "Initial Request"

    • Input schema: job_description, name, skills[], projects[{name, skills_gained[]}], education, certificates[], experience_years
  2. InstructorLLMNode_277 - "JD Analyzer Agent"

    • Extracts structured requirements from job description
    • Output: role, skills_required[], experience_level, tools[], nice_to_have[]
    • Strict deterministic rules: only extract from provided input, no hallucination, lowercase normalization
  3. InstructorLLMNode_582 - "Matching Agent"

    • Compares candidate profile against extracted JD requirements
    • Output: skill_match (0-100), experience_match (0-100), project_relevance (0-100)
    • Calculations: skill overlap %, experience ratio, project-to-job-requirement alignment
  4. InstructorLLMNode_264 - "Scoring Agent"

    • Normalizes and weights match scores
    • Output: final_score (0-100 integer), verdict (Perfect Fit/Strong Fit/Good Fit/Weak Fit), breakdown {skill_match, experience_match, project_relevance}
    • Formula: final_score = (0.5 × skill_match) + (0.3 × experience_match) + (0.2 × project_relevance)
    • Verdicts: ≥95→Perfect, ≥85→Strong, ≥70→Good, else→Weak
  5. LLMNode_982 - "Reasoning Agent"

    • Generates hiring rationale based on scores
    • Output: reasoning (max 3 sentences covering strengths, weaknesses, missing skills)
    • Uses job requirements and candidate scoring details
  6. responseNode - "API Response"

    • Aggregates final output mapping
    • Returns JSON with: candidate{name, skills, experience}, evaluation{final_score, verdict, breakdown{skill_match, experience_match, project_relevance}}, reasoning

Data Flow:
Input → JD Analysis → Skill/Experience/Project Matching → Score Calculation → Reasoning → Final JSON Response

Key Features:

  • Deterministic LLM evaluation (strict JSON outputs, no hallucination rules)
  • Weighted multi-criteria scoring (skill 50%, experience 30%, projects 20%)
  • Structured verdicts with breakdown metrics
  • Professional reasoning summary

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a new "Hiring Copilot Agent" Next.js kit: application scaffold, extensive UI library (shadcn/Radix wrappers), server actions and API routes for resume parsing and evaluation, Lamatic orchestration/flow definitions, project configs, utilities, and example environment docs. Also updates root .gitignore to ignore .env.

Changes

Cohort / File(s) Summary
Repository top-level
/.gitignore
Now ignores .env and adds a trailing newline to the file.
Kit manifest & tooling
kits/agentic/hiring-copilot-agent/package.json, kits/agentic/hiring-copilot-agent/tsconfig.json, kits/agentic/hiring-copilot-agent/next.config.ts, kits/agentic/hiring-copilot-agent/postcss.config.mjs, kits/agentic/hiring-copilot-agent/eslint.config.mjs
Added project manifest and build/lint/PostCSS/TypeScript/Next configurations for the new Next.js kit.
Kit ignore & env examples
kits/agentic/hiring-copilot-agent/.gitignore, kits/agentic/hiring-copilot-agent/.env.example
New .gitignore for kit; added .env.example with OpenAI and Lamatic placeholders.
Documentation
kits/agentic/hiring-copilot-agent/README.md, kits/agentic/hiring-copilot-agent/AGENTS.md, kits/agentic/hiring-copilot-agent/CLAUDE.md, kits/agentic/hiring-copilot-agent/flows/first-flow/README.md
New README and docs describing kit purpose, setup, flow overview and guidance.
Orchestration & flows
kits/agentic/hiring-copilot-agent/orchestrate.js, kits/agentic/hiring-copilot-agent/config.json, kits/agentic/hiring-copilot-agent/flows/first-flow/*
Added orchestrate config (flows, api env wiring), kit-level config.json, and a new first-flow with config.json, inputs.json, meta.json and README defining the hiring evaluation pipeline.
Lamatic client & wiring
kits/agentic/hiring-copilot-agent/lib/lamatic-client.ts, kits/agentic/hiring-copilot-agent/orchestrate.js
Lamatic client initializer with runtime env validation; orchestrate.js supplies workflowId/env wiring.
Server action & APIs
kits/agentic/hiring-copilot-agent/actions/orchestrate.ts, kits/agentic/hiring-copilot-agent/app/api/evaluate/route.ts, kits/agentic/hiring-copilot-agent/app/api/parse-resume/route.ts
Added server action generateContent calling Lamatic and two API routes: resume parsing (uploads to OpenAI Responses) and evaluate (invokes generateContent and returns results).
App shell & styling
kits/agentic/hiring-copilot-agent/app/layout.tsx, kits/agentic/hiring-copilot-agent/app/page.tsx, kits/agentic/hiring-copilot-agent/app/fonts.ts, kits/agentic/hiring-copilot-agent/app/globals.css
Root layout, landing page, font imports, global Tailwind CSS, theme variables and dark-mode styles.
Main UI & components
kits/agentic/hiring-copilot-agent/components/MainPart.tsx, kits/agentic/hiring-copilot-agent/components/header.tsx, kits/agentic/hiring-copilot-agent/components/Toast.tsx, kits/agentic/hiring-copilot-agent/components/theme-provider.tsx
Main client UI for upload/batching/evaluation, header, custom toast wrapper and theme provider.
UI primitives & library
kits/agentic/hiring-copilot-agent/components/ui/*
Large set of new shadcn/Radix-based UI components and wrappers (accordion, alert, dialog, inputs, layout primitives, sidebar, chart, carousel, toast system, etc.).
Hooks & toast state
kits/agentic/hiring-copilot-agent/hooks/*, kits/agentic/hiring-copilot-agent/components/ui/use-toast.ts
Added hooks (debounce, mobile detection) and global toast management utilities/hooks.
Types & utilities
kits/agentic/hiring-copilot-agent/lib/types.ts, kits/agentic/hiring-copilot-agent/lib/utils.ts
Added basic toast types and utilities (cn, getMedal).
Component generator config
kits/agentic/hiring-copilot-agent/components.json
New components.json describing UI generator settings and aliases.
Misc files
kits/agentic/hiring-copilot-agent/*
Additional supporting files (AGENTS.md, CLAUDE.md, eslint/postcss configs, etc.).

Suggested reviewers

  • d-pamneja
  • amanintech

Mission control: change set delivered.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

⚠️ This pull request might be slop. It has been flagged by CodeRabbit slop detection.

@anuraag-5
Copy link
Copy Markdown
Contributor Author

Hi maintainers 👋

I built this Hiring Copilot Agent to automate resume screening and reduce manual hiring effort. Would love your feedback and happy to improve further.

Thanks!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (18)
kits/agentic/hiring-copilot-agent/components/ui/collapsible.tsx-1-1 (1)

1-1: ⚠️ Potential issue | 🟡 Minor

Rename file to PascalCase to match component naming convention.

components/ui/collapsible.tsx should be renamed (for example, components/ui/Collapsible.tsx) to satisfy the repository rule for React component filenames under components/.

As per coding guidelines, "kits/**/components/**/*.{tsx,ts}: Use PascalCase for React component filenames in the components/ directory".

.gitignore-3-3 (1)

3-3: ⚠️ Potential issue | 🟡 Minor

Add .env.local to prevent accidental secret commits.

The guideline requires excluding both .env and .env.local. Next.js applications commonly use .env.local for local development secrets, which should also be ignored.

Proposed fix
 .env
+.env.local

Based on learnings: "The .gitignore file must exclude .env and .env.local to prevent accidental secret commits."

kits/agentic/hiring-copilot-agent/.gitignore-33-42 (1)

33-42: ⚠️ Potential issue | 🟡 Minor

Remove duplicate .vercel and add .env.local.

Two issues:

  1. .vercel appears twice (lines 36 and 42)
  2. .env.local should be excluded per guidelines
Proposed fix
 # env files (can opt-in for committing if needed)
 .env
+.env.local
+
 # vercel
 .vercel

 # typescript
 *.tsbuildinfo
 next-env.d.ts
-
-.vercel

Based on learnings: "The .gitignore file must exclude .env and .env.local to prevent accidental secret commits."

kits/agentic/hiring-copilot-agent/components/ui/form.tsx-45-66 (1)

45-66: ⚠️ Potential issue | 🟡 Minor

Ineffective context guard check.

The guard on line 52-54 checks !fieldContext after fieldContext.name has already been accessed on line 49 in the useFormState call. If FormFieldContext returns the default empty object (when used outside <FormField>), fieldContext.name will be undefined, causing silent failures before the error is thrown.

This is a known pattern inherited from shadcn/ui, but for robustness, the check should come first:

Proposed fix
 const useFormField = () => {
   const fieldContext = React.useContext(FormFieldContext)
   const itemContext = React.useContext(FormItemContext)
+
+  if (!fieldContext.name) {
+    throw new Error('useFormField should be used within <FormField>')
+  }
+
   const { getFieldState } = useFormContext()
   const formState = useFormState({ name: fieldContext.name })
   const fieldState = getFieldState(fieldContext.name, formState)
-
-  if (!fieldContext) {
-    throw new Error('useFormField should be used within <FormField>')
-  }

   const { id } = itemContext
kits/agentic/hiring-copilot-agent/.env.example-1-5 (1)

1-5: ⚠️ Potential issue | 🟡 Minor

Fix formatting inconsistencies in .env.example.

The file has inconsistent formatting: spaces around = signs on some lines, and missing trailing newline. Standard .env files use KEY=value without spaces.

Suggested fix
-OPENAI_API_KEY="OPENAI_API_KEY"
-AGENTIC_GENERATE_CONTENT = "AGENTIC_GENERATE_CONTENT Flow ID"
-LAMATIC_API_URL = "LAMATIC_API_URL"
-LAMATIC_PROJECT_ID = "LAMATIC_PROJECT_ID"
-LAMATIC_API_KEY = "LAMATIC_API_KEY"
+AGENTIC_GENERATE_CONTENT=your_flow_id_here
+LAMATIC_API_KEY=your_lamatic_api_key_here
+LAMATIC_API_URL=your_lamatic_api_url_here
+LAMATIC_PROJECT_ID=your_lamatic_project_id_here
+OPENAI_API_KEY=your_openai_api_key_here
kits/agentic/hiring-copilot-agent/components/Toast.tsx-13-20 (1)

13-20: ⚠️ Potential issue | 🟡 Minor

description prop is accepted but never rendered.

The Toast component receives description via ToastProps but only renders title. Either render the description or remove it from the type/usage.

Proposed fix to render description
 function Toast(props: ToastProps) {
-  const { title } = props;
+  const { title, description } = props;

   return (
     <div className="h-[60px] bg-[`#D0FF00`] flex flex-col justify-center items-center rounded-full py-2 px-5">
       <div className={`text-black text-sm ` + poppins.className}>{title}</div>
+      {description && (
+        <div className={`text-black/70 text-xs ` + poppins.className}>{description}</div>
+      )}
     </div>
   );
 }
kits/agentic/hiring-copilot-agent/lib/lamatic-client.ts-4-19 (1)

4-19: ⚠️ Potential issue | 🟡 Minor

Inconsistent validation: env vars validated but config values used.

Lines 4-14 validate that environment variables are set, but lines 16-19 use config.api.* values to construct the client. If config already reads from these env vars, the manual checks are redundant. If it doesn't, the validation provides no guarantee the client receives valid values.

Consider using env vars directly for consistency:

Proposed fix
-import {config} from '../orchestrate.js';
-
-if (!process.env.AGENTIC_GENERATE_CONTENT) {
-  throw new Error(
-    "All Workflow IDs in environment variable are not set. Please add it to your .env.local file."
-  );
-}
-
-if (!process.env.LAMATIC_API_URL || !process.env.LAMATIC_PROJECT_ID || !process.env.LAMATIC_API_KEY) {
-  throw new Error(
-    "All API Credentials in environment variable are not set. Please add it to your .env.local file."
-  );
-}
+const endpoint = process.env.LAMATIC_API_URL;
+const projectId = process.env.LAMATIC_PROJECT_ID;
+const apiKey = process.env.LAMATIC_API_KEY;
+
+if (!endpoint || !projectId || !apiKey) {
+  throw new Error(
+    "LAMATIC_API_URL, LAMATIC_PROJECT_ID, and LAMATIC_API_KEY must be set in .env.local"
+  );
+}

 export const lamaticClient = new Lamatic({
-  endpoint: config.api.endpoint ?? "",
-  projectId: config.api.projectId ?? null,
-  apiKey: config.api.apiKey ?? ""
+  endpoint,
+  projectId,
+  apiKey,
 });
kits/agentic/hiring-copilot-agent/README.md-101-101 (1)

101-101: ⚠️ Potential issue | 🟡 Minor

Fix typo: "Uplpoad" → "Upload".

Fix
-1. Uplpoad candidate resume and paste JD
+1. Upload candidate resume and paste JD
kits/agentic/hiring-copilot-agent/components/ui/kbd.tsx-18-26 (1)

18-26: ⚠️ Potential issue | 🟡 Minor

Type/element mismatch in KbdGroup.

The KbdGroup component accepts React.ComponentProps<'div'> but renders a <kbd> element. This type inconsistency could cause confusion and potential runtime issues if div-specific props are passed.

Proposed fix
-function KbdGroup({ className, ...props }: React.ComponentProps<'div'>) {
+function KbdGroup({ className, ...props }: React.ComponentProps<'kbd'>) {
   return (
     <kbd
       data-slot="kbd-group"
       className={cn('inline-flex items-center gap-1', className)}
       {...props}
     />
   )
 }
kits/agentic/hiring-copilot-agent/orchestrate.js-34-35 (1)

34-35: ⚠️ Potential issue | 🟡 Minor

polling should be a boolean, not a string.

Using the string "false" instead of the boolean false can cause unexpected behavior. String "false" is truthy in JavaScript, so checks like if (config.flows.hiring_copilot.polling) would incorrectly evaluate to true.

🐛 Proposed fix
       mode: "sync",
-      polling: "false"
+      polling: false
kits/agentic/hiring-copilot-agent/components/ui/empty.tsx-71-81 (1)

71-81: ⚠️ Potential issue | 🟡 Minor

Type mismatch: ComponentProps<'p'> declared but renders a <div>.

The function signature declares React.ComponentProps<'p'> but the component renders a <div> element. This causes incorrect prop typing.

Proposed fix
-function EmptyDescription({ className, ...props }: React.ComponentProps<'p'>) {
+function EmptyDescription({ className, ...props }: React.ComponentProps<'div'>) {
   return (
     <div
       data-slot="empty-description"
kits/agentic/hiring-copilot-agent/components/ui/command.tsx-46-58 (1)

46-58: ⚠️ Potential issue | 🟡 Minor

Keep the hidden dialog title/description inside DialogContent.

Right now the sr-only header is rendered even when the dialog is closed, so assistive tech can still encounter “Command Palette” text in the page outside the modal. Move the hidden header into DialogContent so it only exists while the dialog is mounted.

Suggested change
   return (
     <Dialog {...props}>
-      <DialogHeader className="sr-only">
-        <DialogTitle>{title}</DialogTitle>
-        <DialogDescription>{description}</DialogDescription>
-      </DialogHeader>
       <DialogContent
         className={cn('overflow-hidden p-0', className)}
         showCloseButton={showCloseButton}
       >
+        <DialogHeader className="sr-only">
+          <DialogTitle>{title}</DialogTitle>
+          <DialogDescription>{description}</DialogDescription>
+        </DialogHeader>
         <Command className="[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
           {children}
         </Command>
kits/agentic/hiring-copilot-agent/components/ui/pagination.tsx-107-115 (1)

107-115: ⚠️ Potential issue | 🟡 Minor

Don’t hide the screen-reader label here.

aria-hidden on the outer <span> removes the nested “More pages” text from the accessibility tree too, so screen readers get nothing for this affordance. Hide only the icon.

Suggested change
     <span
-      aria-hidden
       data-slot="pagination-ellipsis"
       className={cn('flex size-9 items-center justify-center', className)}
       {...props}
     >
-      <MoreHorizontalIcon className="size-4" />
+      <MoreHorizontalIcon aria-hidden="true" className="size-4" />
       <span className="sr-only">More pages</span>
     </span>
kits/agentic/hiring-copilot-agent/components/ui/button.tsx-44-63 (1)

44-63: ⚠️ Potential issue | 🟡 Minor

Give the native button a safe default type.

Without this, every <Button> inside a form becomes a submit button unless the caller remembers to override it.

Suggested change
 function Button({
   className,
   variant = "default",
   size = "default",
   asChild = false,
+  type,
   ...props
 }: React.ComponentProps<"button"> &
   VariantProps<typeof buttonVariants> & {
     asChild?: boolean
   }) {
   const Comp = asChild ? Slot.Root : "button"
 
   return (
     <Comp
       data-slot="button"
       data-variant={variant}
       data-size={size}
+      type={asChild ? type : type ?? "button"}
       className={cn(buttonVariants({ variant, size, className }))}
       {...props}
     />
   )
 }
kits/agentic/hiring-copilot-agent/components/ui/chart.tsx-235-239 (1)

235-239: ⚠️ Potential issue | 🟡 Minor

Falsy check excludes zero values from rendering.

The condition item.value && will not render values of 0, which could be legitimate data points in charts. Consider using a nullish check instead.

🐛 Proposed fix to handle zero values
-                    {item.value && (
+                    {item.value !== undefined && item.value !== null && (
                       <span className="text-foreground font-mono font-medium tabular-nums">
                         {item.value.toLocaleString()}
                       </span>
                     )}
kits/agentic/hiring-copilot-agent/components/ui/button-group.tsx-1-6 (1)

1-6: ⚠️ Potential issue | 🟡 Minor

Missing React import.

The file uses React.ComponentProps (lines 28, 44, 64) but doesn't import React. While this may work with modern JSX transforms, explicitly importing React when using React.ComponentProps is more robust and consistent with the other UI components in this kit.

🔧 Proposed fix to add React import
+import * as React from 'react'
 import { Slot } from '@radix-ui/react-slot'
 import { cva, type VariantProps } from 'class-variance-authority'

 import { cn } from '@/lib/utils'
 import { Separator } from '@/components/ui/separator'
kits/agentic/hiring-copilot-agent/components/ui/carousel.tsx-96-105 (1)

96-105: ⚠️ Potential issue | 🟡 Minor

Incomplete event listener cleanup — reInit listener is not removed.

The effect subscribes to both reInit and select events (lines 99-100), but the cleanup function only removes the select listener. This can cause memory leaks or stale callback invocations if the component unmounts or dependencies change.

🧹 Proposed fix to remove both listeners
   React.useEffect(() => {
     if (!api) return
     onSelect(api)
     api.on('reInit', onSelect)
     api.on('select', onSelect)

     return () => {
+      api?.off('reInit', onSelect)
       api?.off('select', onSelect)
     }
   }, [api, onSelect])
kits/agentic/hiring-copilot-agent/components/ui/input-group.tsx-70-75 (1)

70-75: ⚠️ Potential issue | 🟡 Minor

InputGroupAddon click handler only focuses input, not textarea.

The click handler queries for input elements but the component also supports InputGroupTextarea. When a textarea is used in the group, clicking the addon won't focus it.

Proposed fix to support both input and textarea
       onClick={(e) => {
         if ((e.target as HTMLElement).closest('button')) {
           return
         }
-        e.currentTarget.parentElement?.querySelector('input')?.focus()
+        const parent = e.currentTarget.parentElement
+        const control = parent?.querySelector('input') ?? parent?.querySelector('textarea')
+        control?.focus()
       }}
🧹 Nitpick comments (34)
kits/agentic/hiring-copilot-agent/components/ui/aspect-ratio.tsx (1)

1-11: Rename component file to PascalCase

aspect-ratio.tsx should be renamed to AspectRatio.tsx to match the component-file naming convention in components/ directories.

As per coding guidelines: kits/**/components/**/*.{tsx,ts}: Use PascalCase for React component filenames in the components/ directory.

kits/agentic/hiring-copilot-agent/components/ui/switch.tsx (1)

8-11: Rename file to Switch.tsx to follow PascalCase convention.

The filename switch.tsx should be Switch.tsx to comply with the project's naming convention for React component files in the components/ directory. As per coding guidelines: "Use PascalCase for React component filenames in the components/ directory."

kits/agentic/hiring-copilot-agent/components/ui/toggle-group.tsx (1)

73-73: Consider file naming convention.

The file uses kebab-case (toggle-group.tsx) which follows standard shadcn/ui conventions but conflicts with the coding guideline requiring PascalCase for component filenames. Since this is a UI primitive following shadcn patterns, the current naming is acceptable—consider clarifying the guideline to distinguish between shadcn/ui primitives and custom components if needed.

As per coding guidelines: "Use PascalCase for React component filenames in the components/ directory."

kits/agentic/hiring-copilot-agent/hooks/use-mobile.ts (1)

5-19: Remove unused duplicate in components/ui/use-mobile.tsx.

The useIsMobile hook is duplicated within each kit—once in hooks/use-mobile.ts and again in components/ui/use-mobile.tsx with identical implementations. However, all imports across the codebase reference only @/hooks/use-mobile. The components/ui/use-mobile.tsx files are unused and create maintenance burden; consolidate to a single source by removing the duplicate from components/ui/.

kits/agentic/hiring-copilot-agent/components/theme-provider.tsx (1)

1-11: Consider renaming to PascalCase filename.

The coding guidelines specify PascalCase for React component filenames in the components/ directory. This file should be renamed from theme-provider.tsx to ThemeProvider.tsx.

As per coding guidelines: "Use PascalCase for React component filenames in the components/ directory."

kits/agentic/hiring-copilot-agent/flows/first-flow/meta.json (1)

1-9: Populate flow metadata for better discoverability.

The metadata fields are mostly empty placeholders. Consider filling in:

  • description: Describe what the hiring copilot flow does
  • tags: Add relevant tags like ["hiring", "resume-screening", "candidate-evaluation"]
  • name: Consider a more descriptive name than first_flow
kits/agentic/hiring-copilot-agent/components/ui/use-mobile.tsx (1)

5-18: Initial render returns false before hydration completes.

The hook returns !!isMobile which coerces undefined to false on initial SSR render. This may cause a brief layout shift if the actual viewport is mobile. Consider returning undefined initially and handling the loading state in consumers, or using a consistent approach with mql.matches.

Optional: Use mql.matches for consistency
   React.useEffect(() => {
     const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
     const onChange = () => {
-      setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
+      setIsMobile(mql.matches)
     }
     mql.addEventListener('change', onChange)
-    setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
+    setIsMobile(mql.matches)
     return () => mql.removeEventListener('change', onChange)
   }, [])
kits/agentic/hiring-copilot-agent/components/ui/sonner.tsx (1)

1-25: LGTM on implementation; consider PascalCase filename.

The Toaster wrapper correctly integrates sonner with next-themes following shadcn/ui patterns. The filename sonner.tsx could be renamed to Sonner.tsx per guidelines, though this is a common shadcn/ui convention that uses lowercase.

As per coding guidelines: "Use PascalCase for React component filenames in the components/ directory."

kits/agentic/hiring-copilot-agent/components/ui/slider.tsx (1)

16-24: Verify single-value slider behavior.

The _values computation only handles array values. If a consumer passes a single number for value (e.g., value={50}), it will fall through to defaultValue or the [min, max] fallback, potentially rendering incorrect thumb count.

Radix Slider does accept single numbers, so you may want to handle that case:

 const _values = React.useMemo(
   () =>
     Array.isArray(value)
       ? value
+      : typeof value === 'number'
+        ? [value]
       : Array.isArray(defaultValue)
         ? defaultValue
-        : [min, max],
+        : typeof defaultValue === 'number'
+          ? [defaultValue]
+          : [min, max],
   [value, defaultValue, min, max],
 )

If single-value sliders aren't used in this kit, this is fine as-is.

kits/agentic/hiring-copilot-agent/components/ui/select.tsx (1)

1-185: Filename should use PascalCase.

The component filename select.tsx should be renamed to Select.tsx to follow the PascalCase convention for React component files in the components/ directory.

The implementation itself is well-structured, correctly wrapping Radix UI primitives with consistent styling and using lucide-react icons as required.

As per coding guidelines: "Use PascalCase for React component filenames in the components/ directory"

kits/agentic/hiring-copilot-agent/components/ui/dropdown-menu.tsx (1)

1-257: Filename should use PascalCase.

The component filename dropdown-menu.tsx should be renamed to DropdownMenu.tsx to follow the PascalCase convention for React component files in the components/ directory.

The implementation correctly uses Radix UI primitives and lucide-react icons with consistent styling patterns.

As per coding guidelines: "Use PascalCase for React component filenames in the components/ directory"

kits/agentic/hiring-copilot-agent/components/ui/spinner.tsx (1)

1-16: Rename component file to PascalCase.

Please rename components/ui/spinner.tsx to components/ui/Spinner.tsx to match repository naming conventions for React component files.

As per coding guidelines, "Use PascalCase for React component filenames in the components/ directory".

kits/agentic/hiring-copilot-agent/components/ui/skeleton.tsx (1)

1-13: Rename component file to PascalCase.

Please rename components/ui/skeleton.tsx to components/ui/Skeleton.tsx for consistency with the component filename convention.

As per coding guidelines, "Use PascalCase for React component filenames in the components/ directory".

kits/agentic/hiring-copilot-agent/components/ui/toaster.tsx (1)

1-35: Rename component file to PascalCase.

Please rename components/ui/toaster.tsx to components/ui/Toaster.tsx to align with the repo’s React component filename convention.

As per coding guidelines, "Use PascalCase for React component filenames in the components/ directory".

kits/agentic/hiring-copilot-agent/components/ui/textarea.tsx (1)

1-18: Rename component file to PascalCase.

Please rename components/ui/textarea.tsx to components/ui/Textarea.tsx to satisfy the component filename standard.

As per coding guidelines, "Use PascalCase for React component filenames in the components/ directory".

kits/agentic/hiring-copilot-agent/components/ui/label.tsx (1)

1-24: Rename file to use PascalCase.

The filename label.tsx should be Label.tsx to follow the component naming convention.

As per coding guidelines: "Use PascalCase for React component filenames in the components/ directory"

kits/agentic/hiring-copilot-agent/components/ui/input.tsx (1)

1-21: Rename file to use PascalCase.

The filename input.tsx should be Input.tsx to follow the component naming convention.

As per coding guidelines: "Use PascalCase for React component filenames in the components/ directory"

kits/agentic/hiring-copilot-agent/app/api/parse-resume/route.ts (1)

8-12: Add file type validation before processing.

The endpoint accepts any file without validating the MIME type. Consider restricting to PDF files to prevent unexpected errors or potential abuse.

Proposed fix
     const file = formData.get("file") as File;

     if (!file) {
       return Response.json({ error: "No file uploaded" }, { status: 400 });
     }

+    if (file.type !== "application/pdf") {
+      return Response.json({ error: "Only PDF files are supported" }, { status: 400 });
+    }
+
     const arrayBuffer = await file.arrayBuffer();
kits/agentic/hiring-copilot-agent/app/api/evaluate/route.ts (1)

5-23: Missing input validation for required fields.

The destructured fields are passed directly to generateContent without validation. If job_description or other required fields are missing/malformed, errors may be cryptic. Consider validating inputs before processing.

Proposed fix with basic validation
     const {
       job_description,
       name,
       skills,
       projects,
       education,
       certificates,
       experience_years,
     } = await req.json();

+    if (!job_description || typeof job_description !== "string") {
+      return Response.json({ error: "job_description is required" }, { status: 400 });
+    }
+
     const result = await generateContent({
kits/agentic/hiring-copilot-agent/components/header.tsx (2)

1-61: Rename file to use PascalCase.

The filename header.tsx should be Header.tsx to follow the component naming convention.

As per coding guidelines: "Use PascalCase for React component filenames in the components/ directory"


20-26: Consider using a local asset for the logo.

The logo references an external Vercel Blob Storage URL which could become unavailable. Consider placing the logo in the public/ directory for reliability.

kits/agentic/hiring-copilot-agent/app/layout.tsx (1)

6-9: Update the generic metadata description.

The description "Generated by create next app" is a placeholder. Consider updating it to something more descriptive like "AI-powered recruiter assistant for automated resume screening and candidate evaluation."

Suggested improvement
 export const metadata: Metadata = {
   title: "HiringCopilot",
-  description: "Generated by create next app",
+  description: "AI-powered recruiter assistant for automated resume screening and candidate evaluation",
 };
kits/agentic/hiring-copilot-agent/app/globals.css (1)

131-146: Consider accessibility implications of hiding scrollbars globally.

Hiding scrollbars globally can impact users who rely on visible scrollbars for navigation or those with motor impairments. Consider scoping this to specific containers where scrollbar hiding is intentional rather than applying it universally.

Alternative: scope to specific elements
-/* Hide scrollbar globally */
-
-/* Chrome, Safari, Edge */
-::-webkit-scrollbar {
-  display: none;
-}
-
-/* Firefox */
-* {
-  scrollbar-width: none;
-}
-
-/* IE & old Edge */
-* {
-  -ms-overflow-style: none;
-}
+/* Hide scrollbar - apply via .hide-scrollbar class where needed */
+.hide-scrollbar::-webkit-scrollbar {
+  display: none;
+}
+.hide-scrollbar {
+  scrollbar-width: none;
+  -ms-overflow-style: none;
+}
kits/agentic/hiring-copilot-agent/README.md (2)

126-138: Add language specifier to fenced code block.

The folder structure code block should have a language specifier for proper rendering and linting compliance.

Fix
-```
+```text
 kits/agentic/hiring-copilot-agent/
 ├── actions/

110-113: Avoid hardcoding Flow ID in documentation.

The Flow ID is hardcoded here but the kit is designed to read it from environment variables (AGENTIC_GENERATE_CONTENT). Consider noting that users should configure their own flow ID via the .env file rather than documenting a specific ID that may not be accessible to others.

Suggested change
 ## 🔗 Lamatic Flow

-Flow ID: `78c33d5b-a3fb-4db1-99b8-21859ad4c22f`
+Configure your own Lamatic Flow ID via the `AGENTIC_GENERATE_CONTENT` environment variable.
+See the [Environment Variables](`#-environment-variables`) section for setup instructions.
kits/agentic/hiring-copilot-agent/actions/orchestrate.ts (2)

42-45: Add null safety check for resData.result.

If lamaticClient.executeFlow returns undefined or an object without a result property, accessing resData?.result is safe, but returning it directly could propagate undefined to callers expecting data on success.

Suggested improvement
     return {
       success: true,
-      data: resData?.result,
+      data: resData?.result ?? null,
     };

46-52: Avoid using any type for caught errors.

Using any bypasses TypeScript's type checking. Use unknown and narrow the type safely.

Proposed fix
-  } catch (error: any) {
+  } catch (error: unknown) {
     console.error("[orchestrate] Error:", error);
 
     return {
       success: false,
-      error: error.message || "Unknown error",
+      error: error instanceof Error ? error.message : "Unknown error",
     };
   }
kits/agentic/hiring-copilot-agent/orchestrate.js (1)

1-43: Consider converting to TypeScript for consistency.

The coding guidelines specify using TypeScript for all kit components and server actions. This file uses plain JavaScript (.js extension) which lacks type safety for the config structure.

♻️ Suggested conversion to TypeScript

Rename the file to orchestrate.ts and add type definitions:

interface FlowConfig {
  name: string;
  type: string;
  workflowId: string | undefined;
  description: string;
  inputSchema: Record<string, string>;
  outputSchema: Record<string, unknown>;
  mode: string;
  polling: boolean;
}

interface Config {
  type: string;
  flows: Record<string, FlowConfig>;
  api: {
    endpoint: string | undefined;
    projectId: string | undefined;
    apiKey: string | undefined;
  };
}

export const config: Config = {
  // ... existing config
};

As per coding guidelines: "Use TypeScript for all kit components and server actions".

kits/agentic/hiring-copilot-agent/components/ui/use-toast.ts (1)

8-9: Unusually long toast removal delay.

TOAST_REMOVE_DELAY of 1,000,000ms (~16.7 minutes) is atypical for toast notifications. If the intent is to effectively disable auto-removal, consider using Infinity or adding a comment explaining the design choice. If this should be a standard toast duration, typical values are 3,000–5,000ms.

kits/agentic/hiring-copilot-agent/components/ui/card.tsx (1)

1-3: Rename the new components/ui files to PascalCase.

This batch adds lowercase component filenames (card.tsx, accordion.tsx, button.tsx, table.tsx, sheet.tsx, command.tsx, pagination.tsx). That conflicts with the repo naming rule for components/.

As per coding guidelines, "Use PascalCase for React component filenames in the components/ directory".

kits/agentic/hiring-copilot-agent/components/ui/item.tsx (1)

8-72: Consider adding role="listitem" to Item for accessibility consistency.

ItemGroup has role="list" (line 11), but Item doesn't have role="listitem". For proper accessibility semantics when these are used together, the list items should have the corresponding role.

♿ Proposed fix to add listitem role
 function Item({
   className,
   variant = 'default',
   size = 'default',
   asChild = false,
   ...props
 }: React.ComponentProps<'div'> &
   VariantProps<typeof itemVariants> & { asChild?: boolean }) {
   const Comp = asChild ? Slot : 'div'
   return (
     <Comp
       data-slot="item"
       data-variant={variant}
       data-size={size}
+      role="listitem"
       className={cn(itemVariants({ variant, size, className }))}
       {...props}
     />
   )
 }
kits/agentic/hiring-copilot-agent/components/ui/alert-dialog.tsx (1)

121-143: Consider adding data-slot attributes for consistency.

AlertDialogAction and AlertDialogCancel don't have data-slot attributes, unlike all other components in this file. For consistency with the shadcn pattern used throughout, consider adding them.

✨ Proposed fix to add data-slot attributes
 function AlertDialogAction({
   className,
   ...props
 }: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {
   return (
     <AlertDialogPrimitive.Action
+      data-slot="alert-dialog-action"
       className={cn(buttonVariants(), className)}
       {...props}
     />
   )
 }

 function AlertDialogCancel({
   className,
   ...props
 }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {
   return (
     <AlertDialogPrimitive.Cancel
+      data-slot="alert-dialog-cancel"
       className={cn(buttonVariants({ variant: 'outline' }), className)}
       {...props}
     />
   )
 }
kits/agentic/hiring-copilot-agent/components/ui/navigation-menu.tsx (1)

102-120: Consider using cn() for consistency in viewport wrapper.

The wrapper div in NavigationMenuViewport has a hardcoded className string (line 108) instead of using the cn() utility. While functionally fine, using cn() would be consistent with the pattern used throughout the file.

✨ Proposed fix for consistency
 function NavigationMenuViewport({
   className,
   ...props
 }: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>) {
   return (
     <div
-      className={'absolute top-full left-0 isolate z-50 flex justify-center'}
+      className={cn('absolute top-full left-0 isolate z-50 flex justify-center')}
     >
       <NavigationMenuPrimitive.Viewport
kits/agentic/hiring-copilot-agent/components/ui/chart.tsx (1)

72-103: Acknowledged: dangerouslySetInnerHTML usage for dynamic CSS generation.

The static analysis tool flagged dangerouslySetInnerHTML (line 83). In this context, the injected HTML consists of CSS rules generated from developer-provided ChartConfig keys and color values—not user input. The risk is low since the config is controlled at build/development time.

However, if config keys or color values were ever derived from untrusted sources, this could enable CSS injection. Ensure that ChartConfig values are always developer-controlled and never sourced from user input or external APIs.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cec88a00-1acf-468d-86d3-4a1a225aa611

📥 Commits

Reviewing files that changed from the base of the PR and between cd0d519 and 291652f.

⛔ Files ignored due to path filters (5)
  • kits/agentic/hiring-copilot-agent/image-1.png is excluded by !**/*.png
  • kits/agentic/hiring-copilot-agent/image.png is excluded by !**/*.png
  • kits/agentic/hiring-copilot-agent/package-lock.json is excluded by !**/package-lock.json
  • kits/agentic/hiring-copilot-agent/public/add.svg is excluded by !**/*.svg
  • kits/agentic/hiring-copilot-agent/public/up-arrow.svg is excluded by !**/*.svg
📒 Files selected for processing (93)
  • .gitignore
  • kits/agentic/hiring-copilot-agent/.env.example
  • kits/agentic/hiring-copilot-agent/.gitignore
  • kits/agentic/hiring-copilot-agent/AGENTS.md
  • kits/agentic/hiring-copilot-agent/CLAUDE.md
  • kits/agentic/hiring-copilot-agent/README.md
  • kits/agentic/hiring-copilot-agent/actions/orchestrate.ts
  • kits/agentic/hiring-copilot-agent/app/api/evaluate/route.ts
  • kits/agentic/hiring-copilot-agent/app/api/parse-resume/route.ts
  • kits/agentic/hiring-copilot-agent/app/fonts.ts
  • kits/agentic/hiring-copilot-agent/app/globals.css
  • kits/agentic/hiring-copilot-agent/app/layout.tsx
  • kits/agentic/hiring-copilot-agent/app/page.tsx
  • kits/agentic/hiring-copilot-agent/components.json
  • kits/agentic/hiring-copilot-agent/components/MainPart.tsx
  • kits/agentic/hiring-copilot-agent/components/Toast.tsx
  • kits/agentic/hiring-copilot-agent/components/header.tsx
  • kits/agentic/hiring-copilot-agent/components/theme-provider.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/accordion.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/alert-dialog.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/alert.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/aspect-ratio.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/avatar.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/badge.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/breadcrumb.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/button-group.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/button.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/calendar.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/card.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/carousel.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/chart.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/checkbox.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/collapsible.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/command.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/context-menu.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/dialog.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/drawer.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/dropdown-menu.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/empty.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/field.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/form.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/hover-card.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/input-group.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/input-otp.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/input.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/item.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/kbd.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/label.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/menubar.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/navigation-menu.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/pagination.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/popover.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/progress.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/radio-group.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/resizable.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/scroll-area.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/select.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/separator.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/sheet.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/sidebar.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/skeleton.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/slider.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/sonner.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/spinner.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/switch.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/table.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/tabs.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/textarea.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/toast.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/toaster.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/toggle-group.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/toggle.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/tooltip.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/use-mobile.tsx
  • kits/agentic/hiring-copilot-agent/components/ui/use-toast.ts
  • kits/agentic/hiring-copilot-agent/config.json
  • kits/agentic/hiring-copilot-agent/eslint.config.mjs
  • kits/agentic/hiring-copilot-agent/flows/first-flow/README.md
  • kits/agentic/hiring-copilot-agent/flows/first-flow/config.json
  • kits/agentic/hiring-copilot-agent/flows/first-flow/inputs.json
  • kits/agentic/hiring-copilot-agent/flows/first-flow/meta.json
  • kits/agentic/hiring-copilot-agent/hooks/use-debounce.ts
  • kits/agentic/hiring-copilot-agent/hooks/use-mobile.ts
  • kits/agentic/hiring-copilot-agent/hooks/use-toast.ts
  • kits/agentic/hiring-copilot-agent/lib/lamatic-client.ts
  • kits/agentic/hiring-copilot-agent/lib/server-actions.ts
  • kits/agentic/hiring-copilot-agent/lib/types.ts
  • kits/agentic/hiring-copilot-agent/lib/utils.ts
  • kits/agentic/hiring-copilot-agent/next.config.ts
  • kits/agentic/hiring-copilot-agent/orchestrate.js
  • kits/agentic/hiring-copilot-agent/package.json
  • kits/agentic/hiring-copilot-agent/postcss.config.mjs
  • kits/agentic/hiring-copilot-agent/tsconfig.json

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
kits/agentic/hiring-copilot-agent/components/MainPart.tsx (2)

12-12: Typo in state setter name.

The setter setJodDesc appears to be missing a 'b' — should be setJobDesc to match the state variable jobDesc.

Suggested fix
-  const [jobDesc, setJodDesc] = useState("");
+  const [jobDesc, setJobDesc] = useState("");

Then update all usages (lines 120, 168, 264) from setJodDesc to setJobDesc.


206-214: Consider using the existing getMedal utility.

The AI summary indicates getMedal exists in lib/utils.ts. Extracting this inline logic to reuse that helper improves consistency and reduces duplication.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4f36e1d1-8529-48c5-8747-18158b0efdb6

📥 Commits

Reviewing files that changed from the base of the PR and between 291652f and d85f1eb.

📒 Files selected for processing (2)
  • kits/agentic/hiring-copilot-agent/app/api/evaluate/route.ts
  • kits/agentic/hiring-copilot-agent/components/MainPart.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • kits/agentic/hiring-copilot-agent/app/api/evaluate/route.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
kits/agentic/hiring-copilot-agent/components/MainPart.tsx (1)

12-12: Typo in state setter name.

setJodDesc should be setJobDesc to match the state variable jobDesc. This typo propagates to lines 119, 120, 169, and 265.

Suggested fix
-  const [jobDesc, setJodDesc] = useState("");
+  const [jobDesc, setJobDesc] = useState("");

Then update all usages:

  • Line 119: setJobDesc("");
  • Line 120: Remove (per prior feedback, this moves into the try block)
  • Line 169: onChange={(e) => setJobDesc(e.target.value)}
  • Line 265: onChange={(e) => setJobDesc(e.target.value)}

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7a53949e-0134-466c-bcab-a467d7596c79

📥 Commits

Reviewing files that changed from the base of the PR and between d85f1eb and 42fde62.

📒 Files selected for processing (1)
  • kits/agentic/hiring-copilot-agent/components/MainPart.tsx

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
kits/agentic/hiring-copilot-agent/hooks/use-toast.ts (1)

8-9: Unusually long toast removal delay.

TOAST_REMOVE_DELAY is set to 1,000,000 ms (~16.7 minutes). This seems atypically long for a toast notification. Typically toast removal delays are in the range of 3-10 seconds. If this is intentional (e.g., persistent toasts that require manual dismissal), consider adding a comment explaining the rationale.

kits/agentic/hiring-copilot-agent/components/MainPart.tsx (1)

11-19: Consider using react-hook-form with zod for form state management.

The component uses raw useState for form fields (jobDesc, files) with manual validation. Per coding guidelines, form handling in kit components should use react-hook-form with zod validation for consistent, declarative form management.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c7956365-2bd1-4035-97a5-12100f8b964c

📥 Commits

Reviewing files that changed from the base of the PR and between 42fde62 and 7b2ee78.

📒 Files selected for processing (8)
  • kits/agentic/hiring-copilot-agent/actions/orchestrate.ts
  • kits/agentic/hiring-copilot-agent/app/api/evaluate/route.ts
  • kits/agentic/hiring-copilot-agent/components/MainPart.tsx
  • kits/agentic/hiring-copilot-agent/config.json
  • kits/agentic/hiring-copilot-agent/hooks/use-toast.ts
  • kits/agentic/hiring-copilot-agent/lib/types.ts
  • kits/agentic/hiring-copilot-agent/orchestrate.js
  • kits/agentic/hiring-copilot-agent/package.json
✅ Files skipped from review due to trivial changes (1)
  • kits/agentic/hiring-copilot-agent/package.json
🚧 Files skipped from review as they are similar to previous changes (4)
  • kits/agentic/hiring-copilot-agent/config.json
  • kits/agentic/hiring-copilot-agent/lib/types.ts
  • kits/agentic/hiring-copilot-agent/app/api/evaluate/route.ts
  • kits/agentic/hiring-copilot-agent/orchestrate.js

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a35eb415-49db-437c-aad4-97b89f61933c

📥 Commits

Reviewing files that changed from the base of the PR and between 7b2ee78 and 4af1fc7.

📒 Files selected for processing (1)
  • kits/agentic/hiring-copilot-agent/actions/orchestrate.ts

@github-actions
Copy link
Copy Markdown

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai bot requested review from amanintech and d-pamneja March 30, 2026 09:43
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
kits/agentic/hiring-copilot-agent/components/MainPart.tsx (1)

25-35: ⚠️ Potential issue | 🟠 Major

Mission-critical: this flow still needs to be a real form, not clickable containers.

Lines 185-199 and 281-295 still render upload/submit as clickable divs, so they are not keyboard-reachable, cannot be semantically disabled while evaluating, and the icon-only submit control has no accessible name. The validation in Lines 25-35 is also still hand-rolled instead of living in a schema-backed form boundary.

#!/bin/bash
set -euo pipefail

FILE="kits/agentic/hiring-copilot-agent/components/MainPart.tsx"

echo "-- Current control implementation --"
sed -n '25,35p;185,199p;281,295p' "$FILE"

echo
echo "-- Existing kit form/button/icon conventions --"
rg -n -C2 'useForm\(|zodResolver|from "lucide-react"|<Button\b|type="submit"' kits --glob '**/*.tsx'

As per coding guidelines, "Use react-hook-form with zod validation for form handling in kits", "Use shadcn/ui and Radix UI primitives for UI components in kits", and "Use lucide-react for icons throughout kits".

Also applies to: 185-199, 281-295

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@kits/agentic/hiring-copilot-agent/components/MainPart.tsx` around lines 25 -
35, The current handleSubmit flow in MainPart.tsx uses manual validation and
clickable divs which are not keyboard-accessible or semantically disableable;
replace this with a react-hook-form + zod schema boundary for jobDesc and files,
move the submit logic into a real <form> submit handler (use the existing
handleSubmit function name as the RHF submit callback) and wrap form state with
FormProvider/useForm so validation is schema-backed; replace the clickable
upload/submit divs (the components rendered around the upload and icon-only
submit at the blocks referenced) with shadcn/ui Button primitives (type="submit"
for the submit control) and use lucide-react icons inside the Button providing
an accessible name (aria-label or visible text), and ensure Buttons receive the
evaluating boolean to set disabled so keyboard users and assistive tech respect
the disabled state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@kits/agentic/hiring-copilot-agent/actions/orchestrate.ts`:
- Around line 27-33: The current orchestrate action returns success
unconditionally after calling lamaticClient.executeFlow; update it to validate
resData.status (from executeFlow) before reporting success: if status is "ok"
(or a defined success value) return { success: true, data: resData.result },
otherwise log the error/status and return or throw a failure (e.g., { success:
false, error: resData.error || resData.status }) so callers of orchestrate (and
/api/evaluate) do not treat failed Lamatic flows as successful; modify the code
around lamaticClient.executeFlow and the return block to implement this guard.

In `@kits/agentic/hiring-copilot-agent/components/MainPart.tsx`:
- Around line 81-83: The projects mapping currently serializes missing skills as
"undefined" via the template `${p.name}: ${p.skills_gained?.join(", ")}`; update
the projects mapping (the parsed.projects → map callback) so it only appends the
": <skills>" suffix when p.skills_gained exists and has length (e.g., check
p.skills_gained && p.skills_gained.length or p.skills_gained?.length) and
otherwise return just p.name (or an empty skills string), ensuring
p.skills_gained is not coerced to "undefined" in the output.
- Around line 75-80: Remove the unused synthesized field by deleting
experience_level from the request body in MainPart.tsx (where body:
JSON.stringify is built using jobDesc and parsed). The flow's contract only
exposes experience_years (see flows/first-flow/config.json advance_schema and
triggerNode_1.output.experience_years), so drop experience_level to prevent
payload drift and keep the evaluator inputs mapped to the declared
experience_years only; also scan for any other references to experience_level in
this component and remove or replace them with parsed.experience_years if
actually needed.

---

Duplicate comments:
In `@kits/agentic/hiring-copilot-agent/components/MainPart.tsx`:
- Around line 25-35: The current handleSubmit flow in MainPart.tsx uses manual
validation and clickable divs which are not keyboard-accessible or semantically
disableable; replace this with a react-hook-form + zod schema boundary for
jobDesc and files, move the submit logic into a real <form> submit handler (use
the existing handleSubmit function name as the RHF submit callback) and wrap
form state with FormProvider/useForm so validation is schema-backed; replace the
clickable upload/submit divs (the components rendered around the upload and
icon-only submit at the blocks referenced) with shadcn/ui Button primitives
(type="submit" for the submit control) and use lucide-react icons inside the
Button providing an accessible name (aria-label or visible text), and ensure
Buttons receive the evaluating boolean to set disabled so keyboard users and
assistive tech respect the disabled state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3ba8e570-5452-4a05-8c56-83202607c6d1

📥 Commits

Reviewing files that changed from the base of the PR and between 7b2ee78 and 2780965.

📒 Files selected for processing (2)
  • kits/agentic/hiring-copilot-agent/actions/orchestrate.ts
  • kits/agentic/hiring-copilot-agent/components/MainPart.tsx

anuraag-5 and others added 7 commits March 30, 2026 15:53
added e.currentTarget.value = "" to hidden input

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@anuraag-5 anuraag-5 force-pushed the feat/hiring-copilot-agent branch from 2780965 to 1329cb2 Compare March 30, 2026 10:23
@anuraag-5 anuraag-5 force-pushed the feat/hiring-copilot-agent branch from 1dfca6a to af268c4 Compare March 31, 2026 07:16
Copy link
Copy Markdown
Contributor

@d-pamneja d-pamneja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@d-pamneja d-pamneja merged commit 105568e into Lamatic:main Mar 31, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants