From 2e40439cd39c1ade7ac169b05684a83cc5b08a74 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 29 Jul 2026 08:26:16 +0000 Subject: [PATCH 1/2] =?UTF-8?q?memo:=20=EC=A0=80=EC=9E=A5=EB=A7=8C=20?= =?UTF-8?q?=ED=95=B4=EB=91=94=20draft=2012=EA=B0=9C=20archive=EB=A1=9C,=20?= =?UTF-8?q?435=20=EC=82=AD=EC=A0=9C,=20=EB=A7=81=ED=81=AC=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B0=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 작성 중 큐(draft 37개)에 완성될 일 없는 링크 메모가 섞여 있었다. - lint:memo: ``를 링크로 센다 JSX(`^<[A-Z]`)로 걸러지고 있어서 링크 하나뿐인 mdx 메모가 전부 note로 샜다. 여는 줄~닫는 줄을 링크 불릿 하나로 접어서 제목(자식)도 산문이 아니라 링크의 일부로 본다. release 메모의 type은 바뀌지 않았다 (다른 평문 링크가 이미 있어서) - draft → archive 12개 430·433·449·458·467·471·472·474·487 (QuoteLink 링크 모음, type도 bookmarks로) 201·226·372 (그룹 라벨이 붙은 링크 모음이라 note 유지) 작성 중 큐 37 → 24 - 435 삭제 — 채용 공고 원문 붙여넣기. 개인 맥락이고 lint:voice도 못 잡는다 (개조식이라 존댓말 신호가 없다) Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Qv2pQrCq9z1GaxxDu2vohK --- docs/memo-spec.md | 1 + scripts/lint-memo.mjs | 33 ++++++++++++++++++++++++++++++++- src/content/memo/201.md | 2 +- src/content/memo/226.md | 2 +- src/content/memo/372.md | 2 +- src/content/memo/430.mdx | 4 ++-- src/content/memo/433.mdx | 4 ++-- src/content/memo/435.md | 39 --------------------------------------- src/content/memo/449.mdx | 4 ++-- src/content/memo/458.mdx | 4 ++-- src/content/memo/467.mdx | 4 ++-- src/content/memo/471.mdx | 4 ++-- src/content/memo/472.mdx | 4 ++-- src/content/memo/474.mdx | 4 ++-- src/content/memo/487.mdx | 4 ++-- 15 files changed, 54 insertions(+), 61 deletions(-) delete mode 100644 src/content/memo/435.md diff --git a/docs/memo-spec.md b/docs/memo-spec.md index 611d7d3..778bc41 100644 --- a/docs/memo-spec.md +++ b/docs/memo-spec.md @@ -50,6 +50,7 @@ - `debug`·`comparison` 같은 **목적/주제는 `type`이 아니라 `tags`**에 넣는다. - ` ```md ` 처럼 산문을 인용한 펜스는 코드로 세지 않는다. +- `` 같은 **링크 컴포넌트도 링크로 센다** — JSX로 걸러버리면 링크 모음이 `note`로 샌다. - **압축하면 형태가 바뀔 수 있다.** 부풀린 산문을 걷어내면 남는 게 링크뿐일 수 있다. ## status — 공개 상태 diff --git a/scripts/lint-memo.mjs b/scripts/lint-memo.mjs index 81de381..9ee7afb 100644 --- a/scripts/lint-memo.mjs +++ b/scripts/lint-memo.mjs @@ -6,10 +6,16 @@ const strict = process.argv.includes('--strict') const NON_CODE_FENCE = /^(md|markdown|text|plaintext)$/i +/** + * 링크를 렌더하는 컴포넌트 (`제목`). + * JSX 로 걸러버리면 링크가 하나도 없는 것으로 보여서 bookmarks 가 note 로 샌다. + */ +const LINK_COMPONENT = /^<([A-Z]\w*)\s[^>]*\b(?:url|href)="(https?:\/\/[^"]+)"/ + /** * 본문에서 형태 신호를 추출한다. * - 코드 펜스: ```md 처럼 산문을 인용한 펜스는 코드로 세지 않는다 - * - 링크: 불릿 링크 + 맨 URL 줄 + * - 링크: 불릿 링크 + 맨 URL 줄 + 링크 컴포넌트 * - 산문: 불릿/헤딩/각주정의/JSX/import 를 제외한 줄 */ const analyze = (raw) => { @@ -24,6 +30,7 @@ const analyze = (raw) => { let inFence = false let fenceIsCode = true let codeLines = 0 + let linkComponent = null const kept = [] for (const line of body.split('\n')) { @@ -48,6 +55,30 @@ const analyze = (raw) => { continue } + // 링크 컴포넌트는 여는 줄부터 닫는 줄까지를 링크 불릿 하나로 접는다. + // 자식(링크 제목)은 산문이 아니라 링크의 일부다 — `- [제목](URL)` 과 같다. + if (linkComponent) { + if (line.includes(``)) { + linkComponent = null + } + + continue + } + + const component = line.trim().match(LINK_COMPONENT) + + if (component) { + const [, tag, url] = component + + kept.push(`- <${url}>`) + + if (!line.includes(``) && !/\/>\s*$/.test(line)) { + linkComponent = tag + } + + continue + } + kept.push(line) } diff --git a/src/content/memo/201.md b/src/content/memo/201.md index 9a1dbc9..dae363f 100644 --- a/src/content/memo/201.md +++ b/src/content/memo/201.md @@ -1,7 +1,7 @@ --- type: note tags: ['git'] -status: draft +status: archive ctime: 2022-09-23 mtime: 2024-03-22 --- diff --git a/src/content/memo/226.md b/src/content/memo/226.md index 38295a2..729bdf7 100644 --- a/src/content/memo/226.md +++ b/src/content/memo/226.md @@ -1,7 +1,7 @@ --- type: note tags: ['api', 'docs'] -status: draft +status: archive ctime: 2022-11-02 mtime: 2024-03-22 --- diff --git a/src/content/memo/372.md b/src/content/memo/372.md index 3f794df..1865058 100644 --- a/src/content/memo/372.md +++ b/src/content/memo/372.md @@ -1,7 +1,7 @@ --- type: note tags: ['aws'] -status: draft +status: archive ctime: 2025-01-18 mtime: 2025-01-18 --- diff --git a/src/content/memo/430.mdx b/src/content/memo/430.mdx index adef137..11f1357 100644 --- a/src/content/memo/430.mdx +++ b/src/content/memo/430.mdx @@ -1,7 +1,7 @@ --- -type: note +type: bookmarks tags: ['fp-ts', 'fp'] -status: draft +status: archive ctime: 2025-03-02 mtime: 2025-03-02 --- diff --git a/src/content/memo/433.mdx b/src/content/memo/433.mdx index 24a011e..cd82179 100644 --- a/src/content/memo/433.mdx +++ b/src/content/memo/433.mdx @@ -1,7 +1,7 @@ --- -type: note +type: bookmarks tags: ['symbol'] -status: draft +status: archive ctime: 2025-03-03 mtime: 2025-03-03 --- diff --git a/src/content/memo/435.md b/src/content/memo/435.md deleted file mode 100644 index e72c382..0000000 --- a/src/content/memo/435.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -type: note -tags: ['jd'] -status: draft -ctime: 2025-03-03 -mtime: 2025-03-03 ---- - -주요업무 - -- 최신 웹 기술을 사용하여 웹 애플리케이션의 사용자 인터페이스 설계 및 개발 -- 디자이너, PO, 서버개발자와 협업하여 사용자 인터페이스 디자인이 최고 수준으로 구현되도록 보장 -- 깔끔하고 유지 관리가 용이하며 효율적인 코드 작성 -- 프론트엔드 문제 디버깅 및 문제 해결 -- 프론트엔드 개발의 새로운 트렌드와 기술에 대한 최신 정보 파악 - -자격요건 - -- HTML, CSS, JavaScript에 대한 풍부한 경험 -- React, Vue, Angular 또는 이와 유사한 최신 프런트엔드 프레임워크에 대한 경험 -- MobX, React-Query 등 다양한 상태 관리 패턴 사용 경험 -- Git 버전 관리에 익숙함 -- 뛰어난 문제 해결 능력과 세부 사항에 대한 주의력 -- 강력한 커뮤니케이션 및 협업 기술 -- 빠르게 변화하는 환경에서 작업하고 동시에 여러 프로젝트를 처리할 수 있는 능력 -- 능동적인 문제 해결사. 높은 신뢰성, 디테일 지향성, 뛰어난 후속 처리 능력 - -우대사항 - -- Vitest, Jest 그리고 React Testing Library와 같은 테스트 프레임워크에 대한 경험 -- JS -> TS 마이그레이션 경험, -- 프론트엔드 개발에 열정을 갖고 역동적인 팀과 함께 흥미로운 프로젝트를 진행하고자 하는 자세 -- 고객과 직접 작업한 경험 또는 고객과 직접 대면하는 역할을 수행한 경험 -- 고객을 돕고 고객의 요구를 충족하는 최고의 전략 및 기술 솔루션을 조언하는 데 있어 능동적인 자세로 임하는 열정 -- 새로운 웹 개발 트렌드를 포함하여 성장하는 비즈니스의 요구 사항에 대한 이해력 -- 팀 환경 내에서 개별적으로 또는 협력적으로 일할 수 있는 능력 -- 모호함을 편안하게 받아들이고 실패나 실수를 두려워하지 않는 자세. 피드백을 잘 받아들이고 빠르게 반복할 수 있음(스타트업 초기 단계의 경험 적극 선호) - -위의 항목은 대화의 시작점일 뿐, 요구사항의 어려운 목록이 아닙니다. 이 역할에 흥미를 느낀다면 꼭 지원하시기 바랍니다! diff --git a/src/content/memo/449.mdx b/src/content/memo/449.mdx index b06e777..36686cc 100644 --- a/src/content/memo/449.mdx +++ b/src/content/memo/449.mdx @@ -1,7 +1,7 @@ --- -type: note +type: bookmarks tags: ['state'] -status: draft +status: archive ctime: 2025-03-04 mtime: 2025-03-04 --- diff --git a/src/content/memo/458.mdx b/src/content/memo/458.mdx index 0e4e5ab..402e00c 100644 --- a/src/content/memo/458.mdx +++ b/src/content/memo/458.mdx @@ -1,7 +1,7 @@ --- -type: note +type: bookmarks tags: ['concurrency'] -status: draft +status: archive ctime: 2025-03-04 mtime: 2025-03-04 --- diff --git a/src/content/memo/467.mdx b/src/content/memo/467.mdx index fadf426..013f9a9 100644 --- a/src/content/memo/467.mdx +++ b/src/content/memo/467.mdx @@ -1,7 +1,7 @@ --- -type: note +type: bookmarks tags: ['file-reader'] -status: draft +status: archive ctime: 2025-03-04 mtime: 2025-03-04 --- diff --git a/src/content/memo/471.mdx b/src/content/memo/471.mdx index 8337789..6bc1728 100644 --- a/src/content/memo/471.mdx +++ b/src/content/memo/471.mdx @@ -1,7 +1,7 @@ --- -type: note +type: bookmarks tags: ['css', 'highlight'] -status: draft +status: archive ctime: 2025-03-04 mtime: 2025-03-04 --- diff --git a/src/content/memo/472.mdx b/src/content/memo/472.mdx index 7efd7b7..eea4e39 100644 --- a/src/content/memo/472.mdx +++ b/src/content/memo/472.mdx @@ -1,7 +1,7 @@ --- -type: note +type: bookmarks tags: ['reservation'] -status: draft +status: archive ctime: 2025-03-04 mtime: 2025-03-04 --- diff --git a/src/content/memo/474.mdx b/src/content/memo/474.mdx index 092f961..aebd840 100644 --- a/src/content/memo/474.mdx +++ b/src/content/memo/474.mdx @@ -1,7 +1,7 @@ --- -type: note +type: bookmarks tags: ['state'] -status: draft +status: archive ctime: 2025-03-05 mtime: 2025-03-05 --- diff --git a/src/content/memo/487.mdx b/src/content/memo/487.mdx index c2ece02..e8e332e 100644 --- a/src/content/memo/487.mdx +++ b/src/content/memo/487.mdx @@ -1,7 +1,7 @@ --- -type: note +type: bookmarks tags: ['typescript', 'react'] -status: draft +status: archive ctime: 2025-03-05 mtime: 2025-03-05 --- From 79bfb986e679fed9839452c2805d556c1aca4ef7 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 29 Jul 2026 12:02:16 +0000 Subject: [PATCH 2/2] =?UTF-8?q?lint:=20bookmarks=20+=20draft=20=EC=A1=B0?= =?UTF-8?q?=ED=95=A9=EC=9D=84=20=EC=98=A4=EB=A5=98=EB=A1=9C=20=EC=9E=A1?= =?UTF-8?q?=EB=8A=94=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 명세에만 있고 기계는 확인하지 않던 규칙이라 182·256이 남아 있었다. "작성 중"에 대한 규칙이므로 draft 경고 강등(level)을 적용하지 않는다 — 낮추면 영영 발화하지 않는다. - 182·256 → archive (작성 중 큐 24 → 22) Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Qv2pQrCq9z1GaxxDu2vohK --- docs/memo-spec.md | 4 ++-- scripts/lint-memo.mjs | 11 +++++++++++ src/content/memo/182.md | 2 +- src/content/memo/256.md | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/memo-spec.md b/docs/memo-spec.md index 778bc41..b391e57 100644 --- a/docs/memo-spec.md +++ b/docs/memo-spec.md @@ -61,7 +61,7 @@ | `archive` | 저장/보관 (완성 예정 없음) | 비공개 | | `release` | 완성됨 | 공개 | -- **`bookmarks`는 `draft`를 쓰지 않는다.** 링크는 붙여넣은 순간이 최종형이라 "작성 중"이 없다 → `archive` 아니면 `release`. +- **`bookmarks`는 `draft`를 쓰지 않는다.** 링크는 붙여넣은 순간이 최종형이라 "작성 중"이 없다 → `archive` 아니면 `release`. `lint:memo`가 오류로 잡는다. - `draft`를 "공개 안 함"으로 쓰면 작성 중 큐가 방치된 메모로 막힌다. - 비공개 목록은 로컬에서만 보인다: `/memos/draft`, `/memos/archive`. 프로덕션에서는 비어 있다. - 공개 경로(상세·태그·`/type`·RSS·사이트맵·검색)는 모두 `release`만 포함한다. @@ -111,7 +111,7 @@ | 검사 | 대상 | 빌드 | 실패 조건 | |---|---|---|---| -| `lint:memo` | `type` ↔ 본문 형태, 각주 참조 ↔ 정의, 이 문서 ↔ 스키마 | **게이트** | 논리적 모순은 오류, 휴리스틱 불일치는 경고. `draft`는 경고까지만 | +| `lint:memo` | `type` ↔ 본문 형태, `bookmarks` ↔ `draft`, 각주 참조 ↔ 정의, 이 문서 ↔ 스키마 | **게이트** | 논리적 모순은 오류, 휴리스틱 불일치는 경고. `draft`는 경고까지만 | | `lint:voice` | 인용 표시 없는 존댓말 (남의 문장) | **게이트** | `release`에서 검출되면 실패. `draft`·`archive`는 경고 | | `lint:links` | 죽은 링크 | 미연결 | 수동 실행 | diff --git a/scripts/lint-memo.mjs b/scripts/lint-memo.mjs index 9ee7afb..ada45c7 100644 --- a/scripts/lint-memo.mjs +++ b/scripts/lint-memo.mjs @@ -252,6 +252,17 @@ for (const file of files) { // 작성 중(draft)은 아직 형태가 안 잡혔을 수 있으므로 경고로만 본다 const level = status === 'draft' ? 'warn' : 'error' + // 링크는 붙여넣은 순간이 최종형이라 "작성 중"이 없다. + // draft 를 "공개 안 함"으로 쓰면 작성 중 큐가 방치된 링크로 막힌다. + // 이 규칙 자체가 draft 에 대한 것이므로 level 로 낮추지 않는다. + if (declared === 'bookmarks' && status === 'draft') { + add( + 'error', + target, + 'type: bookmarks 인데 status: draft — archive 아니면 release 다' + ) + } + // 각주 짝 — 참조만 있으면 마커가 깨진 채 렌더되고, 정의만 있으면 렌더되지 않는다 for (const id of analyzed.footnoteRefs) { if (!analyzed.footnoteDefs.has(id)) { diff --git a/src/content/memo/182.md b/src/content/memo/182.md index 222e15f..6661ea0 100644 --- a/src/content/memo/182.md +++ b/src/content/memo/182.md @@ -1,7 +1,7 @@ --- type: bookmarks tags: ['photoshop'] -status: draft +status: archive ctime: 2022-04-09 mtime: 2026-07-27 --- diff --git a/src/content/memo/256.md b/src/content/memo/256.md index d051f0f..87759bb 100644 --- a/src/content/memo/256.md +++ b/src/content/memo/256.md @@ -1,7 +1,7 @@ --- type: bookmarks tags: ['micro-frontend', 'webpack'] -status: draft +status: archive ctime: 2023-03-19 mtime: 2026-07-27 ---