LC-2835 유저 맞춤형 챌린지 큐레이션 페이지 개발#2141
Hidden character warning
Conversation
- 종류별 분류(data/hooks/model/ui)에서 기능별 분류(flow/challenge-comparison/frequent-comparison/faq)로 - 변경하여 함께 수정되는 파일의 응집도를 높이고 의존 관계를 명확하게 함
Claude/nice allen
…et-s-intern/lets-intern-client into LC-2835-유저-맞춤형-챌린지-큐레이션-페이지-개발
Skills/Agents/Hooks 역할 분리로 태스크 워크플로우 재설계 - vercel-react-best-practices: user-invocable:false로 자동 로드 - task-maker: disable-model-invocation, todo/ 폴더 기반으로 변경 - task-runner: 오케스트레이터 역할로 경량화, task-executor 위임 - task-executor: vercel 규칙 내장, dontAsk 권한의 자율 실행 에이전트 - test-runner: haiku 모델 기반 경량 테스트 에이전트 - post-edit-lint.sh: jq 방식으로 재작성 (공식 문서 권장) - check-tasks.sh: Stop 훅으로 모든 task 완료 전 중단 방지 - inject-task-context.sh: 컴팩션 후 task 상태 재주입 - settings.json: PostToolUse/Stop/SessionStart 훅 통합 등록 Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Summary of ChangesHello @dusvlf111, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the application by developing a user-customized challenge curation page, which includes a personalized recommendation system, an interactive challenge comparison feature, and a refined FAQ section. Concurrently, it integrates advanced AI-assisted development workflows through new Claude agents, skills, and automated hooks, streamlining coding, testing, and adherence to best practices. The changes also include comprehensive documentation for the project's architecture and technical stack, ensuring better understanding and future maintainability. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This PR significantly refactors and improves the curation page, reorganizing the file structure around domains with functional separation for challenge-comparison, flow, and faq. It also introduces several Claude Code agent configurations (hooks, skills, and agents) to automate development workflows. While the React code for the curation page appears secure, security vulnerabilities were found in the Claude Code shell scripts and agent configurations. Specifically, a command injection vulnerability exists in the check-tasks.sh hook, and the task-executor agent is configured with overly permissive autonomous execution capabilities that could be exploited via malicious files in the repository. The refactoring itself is well-executed, enhancing maintainability and reusability. Please address the identified security vulnerabilities and review the specific improvement point left in the comments below.
| fi | ||
|
|
||
| # todo/ 에서 미완료 항목([ ])이 있는 파일 탐색 | ||
| REMAINING=$(ls todo/*.md 2>/dev/null | xargs -I{} sh -c 'grep -l "\[ \]" {} 2>/dev/null' 2>/dev/null | head -1) |
There was a problem hiding this comment.
The use of xargs -I{} sh -c '...' with a template containing {} is vulnerable to command injection if a filename in the todo/ directory contains shell metacharacters (e.g., single quotes, semicolons). An attacker could create a file with a malicious name like todo/foo'; touch pwned; '.md which would result in arbitrary command execution when this hook is triggered by Claude Code.
To remediate this, avoid using sh -c to wrap the command. Instead, pass the arguments directly to grep using xargs or use find -exec.
| description: Autonomous task execution agent for lets-intern-client. Implements features, writes tests, commits code, and fixes errors. Delegates from task-runner skill. Use proactively for all coding implementation tasks. | ||
| tools: Read, Write, Edit, Bash, Glob, Grep, Task | ||
| model: inherit | ||
| permissionMode: dontAsk |
There was a problem hiding this comment.
The task-executor agent is configured with permissionMode: dontAsk and granted access to the Bash tool. This allows the agent to execute arbitrary shell commands on the host machine without user confirmation. When combined with the task-runner skill, which automates the execution of tasks defined in repository files, this creates a significant security risk. If a repository contains a malicious task file (e.g., from an untrusted pull request), the agent might execute harmful commands autonomously.
Recommendation: Change permissionMode to default to ensure that sensitive operations like Bash commands always require explicit user approval.
| const titleParts = programs.map((p) => { | ||
| if (p.title.includes('경험정리')) return '경험정리'; | ||
| if (p.title.includes('이력서')) return '이력서'; | ||
| if (p.title.includes('대기업')) return '대기업 자소서'; | ||
| if (p.title.includes('자기소개서')) return '자소서'; | ||
| if (p.title.includes('포트폴리오')) return '포트폴리오'; | ||
| if (p.title.includes('마케팅')) return '마케팅'; | ||
| if (p.title.includes('HR')) return 'HR'; | ||
| return p.title; | ||
| }); |
There was a problem hiding this comment.
현재 비교 결과 제목을 생성하는 로직이 includes를 사용하여 문자열을 확인하고 있어, 향후 프로그램 이름이 변경되거나 새로운 프로그램이 추가될 때 깨지기 쉬운 구조입니다. 예를 들어, '경험정리'와 '경험분석' 챌린지가 모두 '경험'을 포함하고 있어 의도치 않은 결과가 나올 수 있습니다.
PROGRAMS 데이터 객체에 shortTitle이나 alias 같은 짧은 별칭을 추가하고, 이 값을 조합하여 제목을 생성하는 방식을 고려해 보세요. 이렇게 하면 데이터와 로직이 분리되어 유지보수성이 향상됩니다.
예시:
src/domain/curation/shared/programs.ts
export const PROGRAMS: Record<ProgramId, ProgramContent> = {
experience: {
// ...
shortTitle: '경험정리',
// ...
},
// ...
}; const titleParts = programs.map((p) => p.shortTitle || p.title);
References
- 프로그램의 짧은 제목(short title)은 프로그램 데이터의 일부이므로, 표시 로직과 분리하여 프로그램 데이터 모델에 함께 정의하는 것이 응집도를 높입니다. 현재는 제목 생성 로직이 표시 컴포넌트 내에 하드코딩되어 있어 데이터와 로직이 불필요하게 결합되어 있습니다. (link)
연관 작업