한국 정부·공공기관 지원사업(창업지원, 사업화 자금, 입주공간, R&D, 바우처, 경진대회) 전수조사 및 프로젝트 적합성 판정 스킬. K-Startup·기업마당(bizinfo)·NIPA·KOCCA·SMTECH 공고를 크롤링해 현재 작업 폴더의 프로젝트(아이템) 프로필에 맞는 사업을 "즉시 지원 가능 / 요건 충족 시 / 변형하면 가능" 3단계로 분류하고 마감일·자격요건을 원문 검증해 보고서를 만든다. 사용자가 "지원사업 찾아줘", "정부지원", "창업지원 사업", "입주공간/사업화 자금 알아봐", "공모전/경진대회 조사", "우리 아이템에 맞는 지원사업", "K-Startup/기업마당 조사" 등을 요청하면 반드시 이 스킬을 사용한다. 이전에 조사한 적이 있는 프로젝트에서 "재조사", "새로 나온 지원사업 있나", "지난번 이후 뭐 올라왔나"를 물으면 diff 모드(증분 재조사)로 이 스킬을 사용한다. 특정 사이트를 지목하지 않아도 지원사업·보조금·정부과제 탐색 의도가 보이면 트리거된다. 단, 이미 운영 중인 소상공인·가게·점포·자영업자의 지원(소상공인 지원금, 정책자금 대출, 가게 시설개선, 소상공인24, 폐업·재기 지원)은 이 스킬이 아니라 sole-search 스킬을 사용한다. 신호가 섞이면(예: ''온라인 셀러 지원금'') 어느 쪽인지 한 번 묻는다. 사용자 신분보다 요청 목적이 우선이다 — 가게 사장이라도 신규 아이템 창업지원·R&D를 찾으면 ir-search. 한국 지원사업 전용.
npx skills add https://github.com/djfksjd/ir-search --skill ir-search
> 스크립트 위치: 크롤러·유틸리티는 플러그인 디렉토리 아래 ${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/ 에 있다. ${CLAUDE_PLUGIN_ROOT}가 미정의(단독 스킬 설치)면 폴백: ~/.claude/skills/ir-search/skills/ir-search/scripts/ (클래식 설치) 또는 이 SKILL.md와 같은 폴더의 scripts/. 아래 코드 블록의 ${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/ 부분을 실제 확인된 경로로 치환해 실행한다.
정부 지원사업 탐색의 3대 실패 원인을 구조적으로 막는 스킬이다:
먼저 프로젝트 폴더에서 ir-search-profile.md를 찾는다. 있으면 내용을 요약해 보여주고 "바뀐 것 있나요?" 한 번만 확인한 뒤 바로 1단계로 간다 — 같은 질문을 조사 때마다 반복하는 것이 이 스킬의 가장 큰 마찰이므로, 프로필이 있으면 아래 질문은 생략한다.
없으면 현재 작업 폴더에서 프로젝트 정보를 수집한다: CLAUDE.md, README, docs/, 메모리(있다면). 그래도 비는 항목은 사용자에게 한 번에 묻는다 (여러 번 나눠 묻지 않는다):
이미 대화나 폴더에서 파악된 항목은 다시 묻지 않는다.
프로필 확정 후 프로젝트 폴더에 ir-search-profile.md로 저장한다 (기존 파일이 있으면 갱신). 형식:
# ir-search 프로필
- 대상: <프로젝트명 (아이템 한 줄)>
- 창업 단계: <예비창업자 / 개인사업자 / 법인 N년차>
- 지역 연고: <소재지 (이전 가능: ...)>
- 대표자: <연령대 / 성별 / 소속>
- 필요한 것: <자금, 공간, R&D, ...>
- 마지막 조사: <보고서 폴더 경로> (<YYYY-MM-DD>)
마지막 조사 줄은 매 조사 완료 시 갱신한다 — 재조사(diff 모드)가 이 경로로 직전 결과를 찾는다. 이 파일은 로컬 프로젝트 폴더에만 저장되며, 프로필 축 외의 개인정보는 넣지 않는다.
실제 수집 전에 범위 계획기를 실행해 사용자 선택과 커버리지 한계를 고정한다. 계획기는
Python 표준 라이브러리만 사용하고 네트워크·LLM을 호출하지 않으므로 모델 토큰은 0이다.
# 빠른 확인: K-Startup만
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/scope_plan.py" \
--preset quick -o scope-plan.json
# 특정 소스 하나만
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/scope_plan.py" \
--preset focused --source kstartup -o scope-plan.json
# 프로필 기반 권장 범위
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/scope_plan.py" \
--preset recommended --need ai --need rnd --province 서울 -o scope-plan.json
# 사용자가 직접 고른 범위 (후보 소스는 자동화하지 않고 manual로 남음)
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/scope_plan.py" \
--preset custom --source kstartup --source iris -o scope-plan.json
프리셋 의미:
quick: K-Startup만. 빠른 확인이지 전체 조사가 아니다focused: 사용자가 지목한 소스 정확히 하나recommended: K-Startup·기업마당 + 프로필 태그에 맞는 검증된 어댑터all_registered: 현재 저장소에 검증된 자동 어댑터 5개 전체. 인터넷 전체가 아니다all_known: 등록 어댑터와 알려진 공식 후보 전체. 후보는 모두 수동 확인으로 남는다custom: 사용자가 명시한 소스 조합. 미검증 후보는 candidate/manualscope-plan.json의 모든 소스 상태(selected / omitted_by_user / not_applicable,
automated / manual)와 요청 수·시간 추정을 먼저 보여준다. 보고서에는
scope_fingerprint와 "선택 범위 기준" 커버리지를 기록한다. 재조사는 직전과 fingerprint가
같을 때만 GONE·UNCHANGED 승계를 허용한다. fingerprint가 다르면 소스 제외를 GONE으로
오판하지 말고 범위 변경으로 표시해 전체 재판정한다. 후보·수동 출처 목록과 등록 조건은
references/sources.md를 따른다.
프로필의 마지막 조사 폴더가 존재하면 (또는 사용자가 이전 보고서 폴더를 지목하면) 전수 재검토 대신 증분 조사를 한다. 지원사업 조사는 2~4주마다 반복하는 일이고, 매번 250건+를 다시 읽는 것은 낭비다:
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/diff_surveys.py" <직전_폴더> <새_폴더> --out new_items.jsonl \
--old-profile <직전_폴더>/ir-profile-snapshot.md --new-profile ir-search-profile.md
new_items.jsonl(신규 + 변경 + NEEDS_REHASH + 새 소스분)만 한다. UNCHANGED 항목은 직전 보고서의 A/B/C 판정을 그대로 승계하고 재검증하지 않는다. --out 파일은 sole-search와 공통인 wrapper 형식이다 — 한 줄에 {"kind": NEW|CHANGED|NEEDS_REHASH, "diff_status": kind와 동일, "changed_fields": [...], "record": {원본 레코드 + source/source_id 정규화}} (references/diff_record_schema.json 계약). NEEDS_REHASH(직전엔 content_hash가 있었는데 새 조사에 없음)는 상세 재수집(--merge-into) 후 재분류한다. 소멸 공고는 --out이 아니라 옆의 gone_new_items.jsonl(kind GONE)에 기록된다 — 기회 소멸 알림 재료--merge-into)을 거친 레코드는 content_hash로도 비교된다: 목록 필드가 그대로여도 본문(해시)이 바뀌면 CHANGED다. 두 조사의 hash_version이 다르면(v2↔v3 산식 전환 — 값 비교 불가) 1회 CHANGED(상세 재검증)로 흡수한다--out에 기록한다ir-profile-snapshot.md로 저장한다 — 다음 diff의 --old-profile 입력이 된다diff 스크립트가 출력하는 WARNING(재크롤 안 된 소스)이 있으면 그 소스는 "미갱신"으로 보고서에 명시한다 — 조용히 빠뜨리지 않는다.
두 개의 검증된 크롤러가 동봉되어 있다:
# 기본: K-Startup 모집중 전수 (창업지원 중심, 250~300건, 1~2분)
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/kstartup_crawl.py" list -o kstartup_all.jsonl
# 보강: 기업마당·NIPA·KOCCA·SMTECH (프로필에 따라 선택)
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/sources_crawl.py" list bizinfo -o bizinfo.jsonl --max-pages 20
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/sources_crawl.py" list all -o sources_all.jsonl
K-Startup 공식 API 우선 (data.go.kr 키가 있으면): kstartup_crawl.py list는 data.go.kr 서비스키가 있으면 공식 오픈API(K-Startup 사업공고, 데이터셋 15125364)로 모집중 공고를 받고, 키가 없거나 API가 실패/응답 이상/커버리지 부족이면 자동으로 공개 페이지 크롤로 폴백한다. 출력 jsonl 스키마·run_manifest.json은 두 경로가 동일하다. 커버리지 정직성: 이 데이터셋은 등록순(최신우선)이고 모집중 공고가 마감 이력 사이에 분산돼 있어, API는 최신우선 스캔으로 모집중 집합을 모은다 — 데이터셋 끝까지 스캔해 totalCount로 소진을 증명하면 manifest stop_reason: "api"·status ok·exit 0(전수 증명), 최신우선 무마감 페이지 연속으로 조기 종료하면 stop_reason: "api-window"·status partial·exit 2로 정직하게 남긴다(최근 창(window) 커버리지, 전수 증명 아님 — 기존 exit 계약과 일치). api-window일 때는 뒤늦게 재연장된 오래된 공고가 누락될 수 있으므로 전수 보증은 크롤이 권위이며, diff 모드는 partial(api-window) 실행에서 GONE(소멸)을 단정하지 않는다. reported_total은 전체 이력 건수다. 401/403·200 위장 차단(CAPTCHA)은 크롤로 우회하지 않고 수동 전환(exit 3)한다. 키는 DATA_GO_KR_KEY 환경변수 → 리포 루트 .env → ~/.config/ir-search/data_go_kr_key 순으로 탐색하고 로그·에러·명령행에 절대 출력하지 않는다(리다이렉트·URL 인코딩 변형까지 마스킹, apis.data.go.kr 호스트 검증, 자동 리다이렉트 차단). 키 발급: data.go.kr/data/15125364/openapi.do에서 활용신청 → 서비스키 확인(같은 키를 bizinfo·gov24 등 다른 data.go.kr API에 재사용 가능). .env는 gitignore로 커밋되지 않는다.
크롤러 종료코드 계약: 0 = 전체 수집 성공 / 2 = partial(네트워크 오류·구조 변경·페이지 캡·소스 일부 실패). exit 2면 partial이다 — 절대 "0건이지만 성공"으로 취급하지 않는다. jsonl은 partial이어도 수집분까지는 저장돼 있다.
커버리지 기록 — run_manifest.json 기준: 두 크롤러 모두 list 실행이 끝나면(성공·partial 모두) 출력 jsonl 옆에 run_manifest.json(schema v1)을 원자적으로 기록한다. 소스별 run 항목에 status(ok/partial)·exit_code·pages_fetched·collected·duplicates·stop_reason·errors가 들어 있고, 같은 폴더에 여러 소스를 수집하면(all 모드 포함) 소스별 항목이 한 파일에 누적된다(같은 소스는 최신으로 교체). 보고서의 커버리지(한계 고지)는 stderr 메시지가 아니라 이 파일을 읽어 작성한다 — 어떤 소스가 몇 페이지까지·몇 건 수집됐고 왜 멈췄는지(stop_reason·errors)를 그대로 옮긴다. status가 partial인 소스는 "미완 수집"으로 명시한다. manifest에는 카운트·상태만 있고 검색어·프로필·공고 본문은 넣지 않는다.
소스 선택 매트릭스 — 프로필에서 도출한 필요에 따라 K-Startup에 추가한다:
| 프로필/필요 | 추가 소스 | 이유 |
|---|---|---|
| 커버리지 최대화, 지자체·전 부처 | bizinfo (기업마당) | 최대 통합 포털. K-Startup에 없는 공고 다수 |
| AI/ICT/SW 아이템 | nipa | AI 바우처·AI 융합 등 대형 사업 |
| 콘텐츠 앵글 (변형 포함) | kocca | 제작지원·콘텐츠 스타트업 |
| R&D 자금 (법인) | smtech | 중기부 기술개발(디딤돌 등) 전용 접수처 |
사용자가 "전부 다", "빠짐없이"를 요구하면 all을 쓴다. 소스별 특성과 함정은 ${CLAUDE_PLUGIN_ROOT}/skills/ir-search/references/sources.md 참조.
교차 소스 중복 주의: 같은 사업이 K-Startup과 기업마당에 동시 게재되는 경우가 흔하다. 제목 유사도로 중복을 접고, 보고서에는 소스를 병기한다.
기업마당 주의: 공고량이 많고(모집중 1,000건 이상) 마감 임박~지난 것이 섞여 나온다. 두 모드를 구분해 쓴다 — 전수 모드: --max-pages를 확대(~96p, 15건/p)해 모집중 전체를 수집. 최근분 모드: 기본 --max-pages 20은 최근 등록분만이며 전수가 아니다 — 이 경우 보고서에 반드시 "기업마당은 최근 등록분 N건 기준"이라고 명시한다. 어느 모드든 마감일 필터를 반드시 적용한다.
수집된 전체 목록의 제목·카테고리·기관·마감일을 직접 읽고 후보를 뽑는다. grep 필터링으로 대체하지 않는다 — 변형 가능성(예: TTS 기업에게 콘텐츠 제작지원, 예술×기술 입주사업)은 키워드로 잡히지 않는다.
선별 기준:
통상 250건 중 25~40건이 후보로 남는다.
후보 전건의 상세공고를 가져와 자격요건을 원문 확인한다:
# K-Startup 공고 (공고번호로)
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/kstartup_crawl.py" detail <pbancSn> <pbancSn> ... -o details/
# 그 외 소스 공고 (jsonl의 url로)
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/sources_crawl.py" detail <url> <url> ... -o details/
첨부 다운로드 (--download-dir) — 본문이 첨부파일(HWP/PDF)에만 있는 공고를 검증할 때 쓴다. 소스별 지원 여부 (robots·계약 실측 근거는 references/sources.md "첨부 다운로드 계약" 표):
| 소스 | 첨부 지원 | 비고 |
|---|---|---|
| 기업마당 (bizinfo) | 다운로드 | /uploads/…만 robots 불허 — 링크만(skipped_robots) |
| NIPA | 다운로드 | robots 제한 없음 (2026-07-24) |
| SMTECH | 다운로드 | /front/comn/AtchFileDownload.do (2026-07-24) |
| KOCCA | 부분 | 팝업1(공고관련자료) 다운로드 / 팝업2(pms.kocca.kr)는 계약 미확정 — 링크만(skipped_unverified) |
| K-Startup | 링크만 | 첨부 경로 /afile/… 전체가 robots 불허 (2026-07-23) |
# bizinfo/NIPA/KOCCA/SMTECH: 첨부 다운로드 + 목록 jsonl에 해시·첨부 병합 (jsonl의 url 사용)
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/sources_crawl.py" detail <url> \
-o details/ --download-dir attachments/ --merge-into sources.jsonl
# K-Startup: 첨부 링크 수집 + 본문 해시 (아래 robots 주의)
python3 "${CLAUDE_PLUGIN_ROOT}/skills/ir-search/scripts/kstartup_crawl.py" detail <pbancSn> \
-o details/ --download-dir attachments/ --merge-into kstartup_all.jsonl
주의: KOCCA는 첨부 목록이 팝업(noticeFilePop.do)에 있어 공고당 요청이 1회 추가된다. SMTECH 상세는 목록 jsonl의 url(전체 쿼리 포함)을 그대로 써야 한다 — 파라미터를 줄이면 intro 페이지로 302된다.
동작 계약:
blocked_redirect) — 허용 경로가 robots 불허 경로로 302해도 요청이 나가지 않는다. 파일당 50MB 스트리밍 상한, sha256 기록, 서버 파일명은 정제(latin-1→UTF-8 모지바케 복구 + basename)해서만 저장한다. 첨부는 --download-dir 아래 공고별 하위 폴더(pblancId/pbancSn)에 저장돼 여러 공고의 동명 첨부(공고문.pdf 등)가 충돌하지 않는다.download_status: "skipped_robots"). 기업마당은 /uploads/…가, K-Startup은 첨부 다운로드 경로 전체(/afile/…)가 불허다(2026-07-23 확인) — 따라서 K-Startup 첨부는 항상 링크만 남고, 내용 확인이 필요하면 사용자에게 브라우저에서 직접 내려받으라고 안내한다.content_hash가 v3(본문 + 정렬된 첨부 sha256 결합)로 스탬프된다(hash_version: 3). v2(본문만)와 v3는 비교 불가 — diff가 hash_version 불일치를 1회 CHANGED(상세 재검증)로 흡수한다.hash_version: 2 — None으로 지우지 않는다, 지우면 반복 실패 사이의 본문 변경이 diff에서 숨는다) attachments_complete: false + exit 2(partial) 로 끝난다. 이 경우 보고서 한계 고지에 "첨부 미검증"을 명시한다.--merge-into는 목록 jsonl의 해당 레코드에 content_hash / hash_version / attachments / attachments_complete를 원자적으로 병합한다.각 건에서 확인할 것 (없으면 '불명'으로 기록):
건수가 많으면(15건 이상) 서브에이전트에게 구조화 추출을 위임하고, 본인은 적합성 판정만 직접 한다.
검증 결과를 다음 구조로 분류한다. 이 3분류가 이 스킬의 핵심 산출물이다:
~/Documents/지원사업조사_<대상>_<YYYYMMDD>/ — 보고서 md + 원시 jsonl + 상세 원문...bizpbanc-ongoing.do?schM=view&pbancSn={공고번호}, 그 외 소스는 jsonl의 url 필드impersonate='safari'로 접근 (스크립트 내장, 미설치 시 안내)--download-dir로 첨부를 내려받아 확인할 수 있고, K-Startup·KOCCA 팝업2(PMS)는 링크만 수집되므로 "본문은 첨부 참조(링크) + 문의처"로 기록한다Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation
Use when completing tasks, implementing major features, or before merging to verify work meets requirements
Execute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions "/commit". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type/scope/description overrides, (4) Intelligent file staging for logical grouping
Comprehensive GitHub code review with AI-powered swarm coordination
Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.
Use this skill to review code. It supports both local changes (staged or working tree) and remote Pull Requests (by ID or URL). It focuses on correctness, maintainability, and adherence to project standards.
Refactor bloated AGENTS.md, CLAUDE.md, or similar agent instruction files to follow progressive disclosure principles. Splits monolithic files into organized, linked documentation.
Create high-quality git commits: review/stage intended changes, split into logical commits, and write clear commit messages (including Conventional Commits). Use when the user asks to commit, craft a commit message, stage changes, or split work into multiple commits.
Take djfksjd/ir-search from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.