kr-patent-docx-builder — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited kr-patent-docx-builder (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
명세서 본문 콘텐츠(텍스트, 청구항, 부호의 설명 등)를 표준화된 JS 객체 형태로 받아, 한국 특허청 별지 양식을 따르는 docx 파일을 자동 생성한다.
핵심 가치: 매번 명세서 docx를 만들 때마다 폰트/들여쓰기/섹션 헤더 코드를 다시 짜지 않아도 된다. 본 스킬의 빌드 스크립트가 이미 검증된 양식을 적용한다.
scripts/build_kr_patent.js — 메인 빌드 스크립트. content 객체를 받아 docx 생성references/content-schema.md — content 객체의 스키마 (어떤 필드를 채워야 하는지)references/example-content.js — 샘플 content 파일# 본 스킬 디렉토리에서 1회만 실행. docx 패키지가 로컬 설치됨.
cd kr-patent-docx-builder
npm install(package.json의 dependencies — docx)
명세서의 각 섹션을 채우는 JS 객체를 작성한다. 스키마는 references/content-schema.md 참조.
작업 디렉토리에 content.js (필요 시 content_part1.js, content_part2.js, … 분할) 파일을 생성한다.
// content.js (최소 골격)
module.exports = {
metadata: {
file_label: "_법인명__관리번호_명세서초안01_담당자__YYYYMMDD_발명명",
invention_title: "예시 발명의 명칭",
representative_drawing: "도 1"
},
technical_field: "본 발명은 입자 가속기의 빔 진단 기술에 관한 것이다.",
background: [
"<배경 1단락>",
"<배경 2단락>",
"<배경 3단락>",
"<배경 4단락 - 해결과제로의 브릿지>"
],
problem_to_solve: [
"본 발명의 첫 번째 목적은, ~ 위한 것이다.",
"본 발명의 두 번째 목적은, ~ 위한 것이다."
],
solution: [
"<해결수단 단락 1>",
"<해결수단 단락 2>"
],
effects: [
"<효과 1 (3단 인과 구조)>",
"<효과 2>"
],
drawings_brief: [
{ fig: "도 1", desc: "본 발명의 일 실시예에 따른 X를 보인 블록도이다." }
],
detailed_description: [
"<실시예 도입부 표준 문구>",
"<도 1 실시예 단락>",
"<도 2 실시예 단락>"
],
// symbols: [ ... ] // ⚠ default: 생략. 한국 변리사 실무상 【부호의 설명】
// 섹션은 의도적으로 두지 않는 게 권리범위 보호·검토 부담
// 양면에서 유리. symbols 키 자체를 누락 또는 [] 빈 배열로 두면
// 빌더가 해당 섹션을 건너뜀. 사용자가 명시적으로 두기로
// 결정한 경우에만 다음 형태로 채움:
// symbols: [
// { num: "10", name: "슬릿 스캐너" },
// { num: "100", name: "빔 진단 시스템" },
// ],
claims: [
"[청구항 1] ~를 포함하는 X 시스템.",
"[청구항 2] 제1항에 있어서, ~인 것을 특징으로 하는 X 시스템."
],
abstract: "본 발명은 ~에 관한 것이다. ~를 통해 ~한 효과를 얻을 수 있다."
};cd <작업 디렉토리>
node /path/to/skill/scripts/build_kr_patent.js \
--content ./content.js \
--output /mnt/user-data/outputs/<filename>.docx또는 더 간단하게 (작업 디렉토리에서):
cp /path/to/skill/scripts/build_kr_patent.js ./build.js
node build.js이때 build.js는 동일 디렉토리의 content.js를 자동 로드.
python3 /mnt/skills/public/docx/scripts/office/validate.py <output.docx>
extract-text <output.docx> | head -50빌드 스크립트가 자동으로 적용하는 사양은 아래와 같다. 사용자가 별도로 신경 쓸 필요 없음.
| 항목 | 값 |
|---|---|
| 폰트 (한글) | 나눔고딕 |
| 폰트 (영문·숫자) | 나눔고딕 (eastAsia + hAnsi + hAnt 모두 지정 — 폰트 일관성) |
| 본문 폰트 크기 | 11pt (Half-point 22) |
| 섹션 타이틀 폰트 크기 | 12pt (24) |
| 줄 간격 | 360 (1.5배 정도) |
| 본문 단락 들여쓰기 | firstLine 280 DXA (약 2글자) |
| 청구항 들여쓰기 | firstLineChars 300 또는 firstLine 677 DXA |
| 정렬 | 본문 양쪽 정렬, 섹션 타이틀 좌측 정렬 또는 중앙 |
| 페이지 크기 | A4 |
| 여백 | 한국 특허법 시행규칙 별지 양식 기준 |
| 섹션 헤더 표기 | 【발명의 명칭】, 【기술분야】 등 한국 표준 |
명세서가 길어지면 content.js를 부분 파일로 분할.
content.js # 전체 모음 (require로 부분 import)
content_part1.js # 발명 명칭, 기술분야, 배경, 해결과제
content_part2.js # 해결수단
content_part3.js # 효과, 도면 설명
content_part4.js # 실시예 (가장 큼)
content_part5.js # 부호 설명, 청구항, 요약, 대표도content.js:
module.exports = {
...require("./content_part1.js"),
...require("./content_part2.js"),
...require("./content_part3.js"),
...require("./content_part4.js"),
...require("./content_part5.js")
};[<사무소관리번호>][<고객REF>]<발명의명칭_공백제거>.docx예:
[사건 C][P26014KR]공정진척도산출방법및시스템.docx
[사건 E][사건 E]자연어기반EPICS제어프로그램자동생성방법및시스템.docx규칙:
[대학·공공 고객]IPYYYY-NNNN[사건 E], 사건 E_사건 E_청구항_….docx).{...} 부분은 제외). 명칭은 "…방법 및 시스템" → …방법및시스템._법인명__관리번호_명세서초안NN_담당자__YYYYMMDD_발명명 폐기).metadata.file_label 필드를 위 형식으로 채우면 빌드 스크립트가 그대로 파일명에 사용한다.
본 스킬은 명세서 본문만 다룬다. 도면은 별도 처리:
도면 placeholder는 빌드 스크립트가 자동으로 도면설명 섹션 끝에 또는 별도 페이지에 둔다.
빌드 스크립트의 양식이 특허청·법인 검토 과정에서 지적받은 패턴은 scripts/build_kr_patent.js를 직접 수정하여 누적. 다음 사용 시 자동으로 개선된 양식이 적용됨.
| 증상 | 원인 | 해결 |
|---|---|---|
Cannot find module 'docx' | docx 패키지 미설치 | cd kr-patent-docx-builder && npm install |
| docx 파일이 열리지 않음 | 빌더 코드 오류로 invalid xml 생성 | validate.py 실행하여 오류 메시지 확인 |
| 한글이 깨져 보임 | 폰트 hint 누락 | TextRun 생성 시 font: { name: "나눔고딕", eastAsia: "나눔고딕", hAnsi: "나눔고딕" } 명시 |
| 청구항 들여쓰기 불일치 | firstLineChars vs firstLine 혼용 | 한 가지로 통일 |
<w:pPr><w:tabs><w:tab w:val="left" w:pos="1021"/></w:tabs></w:pPr> + 런 시작에 <w:r><w:tab/></w:r> (w:ind 없음). 독립항.docx 사례. 사용자 확인 후 빌더에 반영할 것.docx 라이브러리에서 const { Tab, TabStopType } = require("docx") 후, 문단에 tabStops: [{ type: TabStopType.LEFT, position: 1021 }] 를 주고 런을 new TextRun({ children: [new Tab(), text], font, size }) 로 만들어 문단 첫머리에 실제 `<w:tab/>` 를 넣는다. 해당 문단에는 `indent`(firstLine)를 주지 않는다(탭이 들여쓰기를 담당). 적용 대상: 【발명의 명칭】 본문 1문단 + 【청구항 N】 각 청구항의 모든 본문 문단. 본문(기술분야·배경·해결수단·효과·실시예)은 종전대로 firstLine=800 유지(탭 없음). 검증: <w:tab/> 개수 == 1 + 청구항 문단 수, w:pos="1021" 동수, 해당 문단에 <w:ind> 부재. 원본 근거: 사무소 독립항.docx.LAYOUT.claim_tab(기본 true, 청구항·발명의 명칭을 실제 탭 문자로 들여쓰기)와 LAYOUT.claim_linebreak(기본 true, 구성요소 경계마다 문단 분할)를 신설하고 splitClaimLines()·tabPara()·claimParas()를 빌더에 추가. 분할 규칙: ①종속항 전제부 제N항에 있어서, 1행 분리 ②방법항 단계; / 단계; 및 뒤 분할 ③시스템·장치항 ~부; 및 뒤 분할 ④시스템·장치·프로그램항의 ~하고, / ~하며, 뒤 분할. ⚠️ ④를 방법항에 적용하면 안 된다 — 단계 내부의 ~검출하고,에서 잘못 끊긴다. 청구항 말미가 시스템·장치·서버·단말·프로그램으로 끝나는지로 판정하여 차단하도록 구현됨. content의 claims[i]를 {num, text:[...]} 배열로 주면 사용자가 이미 나눈 것으로 보고 자동 분할을 건너뛴다. 검증: <w:tab/> 개수 == 명칭 1 + 전체 청구항 줄 수, <w:ind> 0건.shutil.copy 가 [Errno 13] Permission denied로 실패하면 파일 손상이 아니라 잠금이다. 대처: 같은 폴더에 _v2 접미 파일로 저장하고 사용자에게 Word를 닫아 달라고 요청한 뒤 백업 → 덮어쓰기. 잠긴 파일은 읽기도 실패하므로 diff 대조도 그 시점엔 불가.content 에 invention_title + claims 만 채우면 된다. buildDocument가 【발명의 설명】 컨테이너와 【발명의 명칭】, 【청구범위】만 출력한다. 파일명은 명명 규칙에 _청구범위 접미를 붙여 명세서 전문과 구분.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.