Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
## 2024-06-21 - Added skip-to-content link
**Learning:** Found a missing skip-to-content link, which is a key accessibility feature to help keyboard and screen reader users bypass navigation. Additionally learned that giving `<main>` `tabindex="-1"` and removing its outline when `:focus-visible` ensures proper focus handling after clicking the skip link without disruptive visual outlines.
**Action:** Always include a skip-to-content link near the start of the `body` and manage target focus appropriately.

## 2026-06-25 - Fix Header Overlap
**Learning:** When using a sticky header, clicking anchor links can cause the target element to scroll under the header, hindering the user experience.
**Action:** Use `scroll-padding-top` on the `html` element with the height of the sticky header to ensure anchor links scroll to a position just below the header.
3,058 changes: 3,058 additions & 0 deletions .github/workflows/opencode-review.yml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
venv/
3 changes: 3 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 2024-06-20 - Unnecessary initial DOM updates for default language
**Learning:** The simple static i18n implementation runs `node.textContent = dict[node.dataset.i18n]` for every translatable node on the initial script load, even when the HTML is already written in the target language (Korean). This creates unnecessary layout/paint operations and blocking time on the main thread for elements that don't need text changes.
**Action:** Always check if the current value matches the desired value before updating the DOM (`node.textContent !== newText`), and add early exits when setting state to the same value to avoid redundant DOM traversal and writes.
## 2024-06-27 - 초기 언어 로드 시 불필요한 DOM 탐색 제거
**Learning:** 초기 로드 시 요청된 언어가 HTML의 기본 언어(ko)와 동일한 경우, 모든 DOM 텍스트 노드를 탐색하고 치환하는 불필요한 작업을 생략하면 성능이 향상됨을 확인했습니다.
**Action:** `isInitialDefault` 조건을 추가하여 초기 로드 시 불필요한 DOM 순회 코드가 실행되지 않도록 개선했습니다.
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@
**Vulnerability:** Unhandled exceptions when accessing `localStorage` in strict browser privacy modes (e.g., when cookies are blocked).
**Learning:** Browsers throw a `SecurityError` when `localStorage` is accessed and the user has blocked third-party cookies or is in a strict privacy mode. If unhandled, this crashes the executing script, leading to a degraded user experience (DoS-like behavior for privacy-conscious users).
**Prevention:** Always wrap `localStorage.getItem` and `localStorage.setItem` in `try-catch` blocks to fail securely and fall back to sensible defaults.
## 2025-06-25 - Fix missing noopener noreferrer on external links
**Vulnerability:** External links (target="_blank") lacked rel="noopener noreferrer", allowing target pages to access window.opener and potentially execute reverse tabnabbing attacks.
**Learning:** Even simple static HTML sites are vulnerable to reverse tabnabbing if external links open in a new tab without proper rel attributes.
**Prevention:** Always append rel="noopener noreferrer" when adding target="_blank" to anchor tags pointing to external domains.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# CHANGELOG

## [Unreleased]
- **성능 개선**: `i18n.js`에서 초기 로드 시 기본 언어가 한국어(ko)인 경우 불필요한 DOM 순회 및 텍스트 업데이트를 생략하도록 개선했습니다.
- **테스트 추가**: 다국어 처리 로직의 무결성을 검증하기 위해 `test_i18n.html` 테스트 파일을 추가했습니다.
24 changes: 16 additions & 8 deletions i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,7 @@ function setLanguage(lang) {

const dict = messages[lang] || messages.ko;

if (!i18nNodes) {
i18nNodes = document.querySelectorAll("[data-i18n]");
if (!langButtons) {
langButtons = document.querySelectorAll("[data-lang]");
metaDesc = document.querySelector('meta[name="description"]');
ogDesc = document.querySelector('meta[property="og:description"]');
Expand Down Expand Up @@ -346,13 +345,22 @@ function setLanguage(lang) {
}
}

// Only update textContent if it actually changed to avoid layout recalculations
i18nNodes.forEach((node) => {
const newText = dict[node.dataset.i18n];
if (newText && node.textContent !== newText) {
node.textContent = newText;
// ⚡ Bolt: 기본 언어로 초기 로드 시 불필요한 DOM 텍스트 읽기 및 탐색 생략 (성능 개선)
const isInitialDefault = lang === "ko" && !i18nNodes;

if (!isInitialDefault) {
if (!i18nNodes) {
i18nNodes = document.querySelectorAll("[data-i18n]");
}
});

// Only update textContent if it actually changed to avoid layout recalculations
i18nNodes.forEach((node) => {
const newText = dict[node.dataset.i18n];
if (newText && node.textContent !== newText) {
node.textContent = newText;
}
});
}

langButtons.forEach((button) => {
const pressed = String(button.dataset.lang === lang);
Expand Down
29 changes: 15 additions & 14 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src 'self'; object-src 'none'; base-uri 'self'; form-action 'none'; upgrade-insecure-requests;">
<meta name="referrer" content="strict-origin-when-cross-origin">
<title>맥락지혜 연구실 | Contextual Wisdom Lab</title>
<meta
name="description"
Expand Down Expand Up @@ -40,7 +41,7 @@
<a href="#projects" data-i18n="nav.projects">프로젝트</a>
<a href="#forks" data-i18n="nav.forks">Fork</a>
<a href="#work" data-i18n="nav.work">작업</a>
<a href="https://github.com/ContextualWisdomLab">GitHub</a>
<a href="https://github.com/ContextualWisdomLab" target="_blank" rel="noopener noreferrer">GitHub</a>
</nav>
<div class="language-switch" role="group" aria-label="Language">
<button type="button" data-lang="ko" aria-pressed="true">KO</button>
Expand All @@ -57,7 +58,7 @@ <h1 data-i18n="hero.title">맥락지혜 연구실</h1>
구슬이 서 말이어도 꿰어야 보배이듯, 문서, 메일, 로그, 회의록을 맥락 안에서 엮어 사람이 무엇을 결정하고 무엇을 실행할지 보이게 하는 AI 의사결정 지원 시스템을 연구하고 만듭니다.
</p>
<div class="hero-actions" role="group" aria-label="Homepage actions">
<a class="button primary" href="https://github.com/ContextualWisdomLab" data-i18n="hero.primaryCta">GitHub 보기</a>
<a class="button primary" href="https://github.com/ContextualWisdomLab" target="_blank" rel="noopener noreferrer" data-i18n="hero.primaryCta">GitHub 보기</a>
<a class="button secondary" href="#dikw" data-i18n="hero.secondaryCta">DIKW 보기</a>
</div>
</div>
Expand Down Expand Up @@ -251,19 +252,19 @@ <h2 data-i18n="references.title">참고문헌</h2>
<ol class="reference-list">
<li>
<span data-i18n="references.ackoff">Ackoff, R. L. (1989). From data to wisdom. Journal of Applied Systems Analysis, 16(1), 3-9.</span>
<a href="https://faculty.ung.edu/kmelton/documents/datawisdom.pdf">https://faculty.ung.edu/kmelton/documents/datawisdom.pdf</a>
<a href="https://faculty.ung.edu/kmelton/documents/datawisdom.pdf" target="_blank" rel="noopener noreferrer">https://faculty.ung.edu/kmelton/documents/datawisdom.pdf</a>
</li>
<li>
<span data-i18n="references.baskarada">Baskarada, S., &amp; Koronios, A. (2013). Data, information, knowledge, wisdom (DIKW): A semiotic theoretical and empirical exploration of the hierarchy and its quality dimension. Australasian Journal of Information Systems, 18(1).</span>
<a href="https://doi.org/10.3127/ajis.v18i1.748">https://doi.org/10.3127/ajis.v18i1.748</a>
<a href="https://doi.org/10.3127/ajis.v18i1.748" target="_blank" rel="noopener noreferrer">https://doi.org/10.3127/ajis.v18i1.748</a>
</li>
<li>
<span data-i18n="references.fricke">Frické, M. (2009). The knowledge pyramid: A critique of the DIKW hierarchy. Journal of Information Science, 35(2), 131-142.</span>
<a href="https://doi.org/10.1177/0165551508094050">https://doi.org/10.1177/0165551508094050</a>
<a href="https://doi.org/10.1177/0165551508094050" target="_blank" rel="noopener noreferrer">https://doi.org/10.1177/0165551508094050</a>
</li>
<li>
<span data-i18n="references.brienza">Brienza, J. P., Kung, F. Y. H., Santos, H. C., Bobocel, D. R., &amp; Grossmann, I. (2018). Wisdom, bias, and balance: Toward a process-sensitive measurement of wisdom-related cognition. Journal of Personality and Social Psychology, 115(6), 1093-1126.</span>
<a href="https://doi.org/10.1037/pspp0000171">https://doi.org/10.1037/pspp0000171</a>
<a href="https://doi.org/10.1037/pspp0000171" target="_blank" rel="noopener noreferrer">https://doi.org/10.1037/pspp0000171</a>
</li>
</ol>
</section>
Expand Down Expand Up @@ -324,31 +325,31 @@ <h2 data-i18n="projects.title">공개 프로젝트</h2>
</div>
<div class="naruon-grid project-grid">
<article>
<h3><a href="https://github.com/ContextualWisdomLab/naruon" data-i18n="projects.naruonTitle">Naruon</a></h3>
<h3><a href="https://github.com/ContextualWisdomLab/naruon" target="_blank" rel="noopener noreferrer" data-i18n="projects.naruonTitle">Naruon</a></h3>
<p data-i18n="projects.naruonBody">메일, 첨부, 일정, 작업을 맥락으로 묶어 판단과 실행으로 연결하는 AI 이메일 워크스페이스입니다.</p>
</article>
<article>
<h3><a href="https://github.com/ContextualWisdomLab/pg-erd-cloud" data-i18n="projects.pgErdTitle">pg-erd-cloud</a></h3>
<h3><a href="https://github.com/ContextualWisdomLab/pg-erd-cloud" target="_blank" rel="noopener noreferrer" data-i18n="projects.pgErdTitle">pg-erd-cloud</a></h3>
<p data-i18n="projects.pgErdBody">PostgreSQL 스키마를 리버스 엔지니어링하고 ERD와 DDL 공유 흐름으로 관리하는 클라우드 MVP입니다.</p>
</article>
<article>
<h3><a href="https://github.com/ContextualWisdomLab/bandscope" data-i18n="projects.bandscopeTitle">BandScope</a></h3>
<h3><a href="https://github.com/ContextualWisdomLab/bandscope" target="_blank" rel="noopener noreferrer" data-i18n="projects.bandscopeTitle">BandScope</a></h3>
<p data-i18n="projects.bandscopeBody">곡을 섹션, 역할, 템포, 연습 우선순위로 분석하는 로컬 우선 리허설 앱입니다.</p>
</article>
<article>
<h3><a href="https://github.com/ContextualWisdomLab/codec-carver" data-i18n="projects.codecCarverTitle">codec-carver</a></h3>
<h3><a href="https://github.com/ContextualWisdomLab/codec-carver" target="_blank" rel="noopener noreferrer" data-i18n="projects.codecCarverTitle">codec-carver</a></h3>
<p data-i18n="projects.codecCarverBody">긴 녹음을 메타데이터를 보존한 FLAC/Opus 조각으로 변환하는 Python CLI입니다.</p>
</article>
<article>
<h3><a href="https://github.com/ContextualWisdomLab/newsdom-api" data-i18n="projects.newsdomTitle">newsdom-api</a></h3>
<h3><a href="https://github.com/ContextualWisdomLab/newsdom-api" target="_blank" rel="noopener noreferrer" data-i18n="projects.newsdomTitle">newsdom-api</a></h3>
<p data-i18n="projects.newsdomBody">스캔된 일본어 신문 PDF를 기사, 제목, 본문, 이미지 구조의 DOM형 JSON으로 파싱하는 API입니다.</p>
</article>
<article>
<h3><a href="https://github.com/ContextualWisdomLab/scopeweave" data-i18n="projects.scopeweaveTitle">scopeweave</a></h3>
<h3><a href="https://github.com/ContextualWisdomLab/scopeweave" target="_blank" rel="noopener noreferrer" data-i18n="projects.scopeweaveTitle">scopeweave</a></h3>
<p data-i18n="projects.scopeweaveBody">트리 편집, 진행률 계산, CSV/JSON, 주간 Gantt를 지원하는 정적 HTML/CSS/JS WBS 플래너입니다.</p>
</article>
<article>
<h3><a href="https://github.com/ContextualWisdomLab/VibeSec" data-i18n="projects.vibesecTitle">VibeSec</a></h3>
<h3><a href="https://github.com/ContextualWisdomLab/VibeSec" target="_blank" rel="noopener noreferrer" data-i18n="projects.vibesecTitle">VibeSec</a></h3>
<p data-i18n="projects.vibesecBody">바이브코딩 앱을 위한 보안 가드레일입니다. AI 개발 도구 규칙, 정적 점검, 리뷰와 수정 프롬프트를 다룹니다.</p>
</article>
</div>
Expand Down Expand Up @@ -419,7 +420,7 @@ <h2 data-i18n="work.title">연구에서 제품으로</h2>
>
<p>
<span data-i18n="footer.founded">Founded by</span>
<a href="https://github.com/seonghobae">Seongho Bae</a>.
<a href="https://github.com/seonghobae" target="_blank" rel="noopener noreferrer">Seongho Bae</a>.
<span data-i18n="footer.line">Context into judgment. Judgment into action.</span>
</p>
</footer>
Expand Down
30 changes: 30 additions & 0 deletions opencode.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"mcp": {
"codegraph": {
"command": "npx",
"args": ["-y", "@colbymchenry/[email protected]", "serve", "--mcp"]
},
"deepwiki": {
"url": "https://mcp.deepwiki.com/mcp"
},
"context7": {
"command": "npx",
"args": ["-y", "@upstash/[email protected]"]
},
"web_search": {
"command": "npx",
"args": ["-y", "@guhcostan/[email protected]"]
}
},
"models": {
"primary": "openai/gpt-5",
"small_model": "github-models/deepseek/deepseek-v3-0324",
"fallback": [
"deepseek/deepseek-r1-0528",
"deepseek/deepseek-v3-0324"
]
},
"context": 200000,
"output": 100000,
"temperature": 0
}
Loading