@kybird/llm-wiki 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,186 @@
1
+ // wiki-search — grep 정확 매칭 + QMD 시맨틱 검색을 항상 병합해 출력한다.
2
+ // 원본: TTSTextViewer/.agents/skills/wiki-search/scripts/search.js
3
+ // 변경점:
4
+ // - __dirname '../../../../' 4단 종속 제거 → findDocRoot(), findQmd() 사용.
5
+ // - findstr(Windows 전용) → process.platform 분기 (win32=findstr, else=grep).
6
+ // - 2026-08-29 (개선계획 0-1): "QMD 성공 시 grep 건너뛰기" 분기 제거. QMD가 유사도로
7
+ // 뭐라도 물어오면 정확 문자열 매칭이 묻히는 구조라 색인이 싱싱할수록 재현율이
8
+ // 떨어졌다(plan.md 5.1(1)). 시맨틱은 대체재가 아니라 보완재 — 둘 다 항상 돌린다.
9
+ // grep 결과를 먼저 출력한다. 실무 검색어는 에러 메시지 붙여넣기가 대부분이라
10
+ // 정확 매칭이 첫 화면에 와야 한다.
11
+ // - 2026-08-29 (개선계획 0-2): grep에 순위를 부여했다. 키워드마다 Set에 합치던 것을
12
+ // 파일별 "매칭 키워드 수"로 집계해 내림차순 정렬하고, 파일명만 보여주던 것을
13
+ // 매칭된 줄 스니펫과 함께 출력한다 (plan.md 5.1(2)).
14
+ // - 2026-08-29 (개선계획 1-6): 수집(collect)과 렌더(render)를 분리. --json이면
15
+ // {schemaVersion: 1, kind: 'search-results', ...} 봉투로 출력 — 스킬 프롬프트가
16
+ // 사람용 출력 문자열에 깨지지 않게 하는 계약.
17
+ const { execSync } = require('child_process');
18
+ const path = require('path');
19
+ const fs = require('fs');
20
+ const { findDocRoot, loadConfig } = require('./find-doc-root');
21
+ const { findQmd } = require('./find-qmd');
22
+
23
+ const MAX_SNIPPETS_PER_FILE = 3;
24
+ const MAX_SNIPPET_LENGTH = 200;
25
+
26
+ function search(query, options = {}) {
27
+ if (!query) {
28
+ console.error('Usage: llm-wiki search "<search keywords>"');
29
+ process.exit(1);
30
+ }
31
+
32
+ const docRoot = findDocRoot();
33
+ const wikiPath = path.join(docRoot, 'wiki');
34
+ const rawPath = path.join(docRoot, 'raw');
35
+ const config = loadConfig(docRoot);
36
+
37
+ const result = {
38
+ schemaVersion: 1,
39
+ kind: 'search-results',
40
+ query,
41
+ // grep이 정확 매칭의 본체. QMD 여부와 무관하게 항상 채워진다.
42
+ grep: collectGrepResults(query, wikiPath, rawPath),
43
+ semantic: collectQmdResults(query, config),
44
+ };
45
+
46
+ if (options.json) {
47
+ console.log(JSON.stringify(result, null, 2));
48
+ return result;
49
+ }
50
+ renderSearchText(result);
51
+ return result;
52
+ }
53
+
54
+ function collectGrepResults(query, wikiPath, rawPath) {
55
+ // 따옴표는 findstr/grep 인용 규칙을 깨므로 키워드에서 제거.
56
+ const keywords = query.split(/\s+/)
57
+ .map(k => k.replace(/"/g, ''))
58
+ .filter(k => k.length > 1);
59
+ // 전부 1글자뿐인 극단 쿼리는 원문 하나를 통짜 키워드로.
60
+ if (keywords.length === 0 && query.trim()) keywords.push(query.trim());
61
+
62
+ const found = new Map(); // absPath → { keywords: Set, snippets: Map<lineText, true> }
63
+ const searchDirs = [wikiPath, rawPath];
64
+ const isWindows = process.platform === 'win32';
65
+
66
+ for (const dir of searchDirs) {
67
+ if (!fs.existsSync(dir)) continue;
68
+ for (const kw of keywords) {
69
+ try {
70
+ let grepCmd;
71
+ if (isWindows) {
72
+ // /C: 통짜 문자열 매칭(정규식 아님) — 에러 메시지의 . : ( 등이 그대로 걸린다.
73
+ // /M(files-only)을 쓰지 않는다 — 매칭 줄 자체가 스니펫이 된다.
74
+ grepCmd = `findstr /S /I /C:"${kw}" "${path.join(dir, '*.md')}"`;
75
+ } else {
76
+ // -F 고정 문자열(정규식 메타문자 무력화), -n 줄번호, -i 대소문자무시
77
+ grepCmd = `grep -rniF --include="*.md" -e "${kw}" "${dir}"`;
78
+ }
79
+ const output = execSync(grepCmd, { encoding: 'utf8' });
80
+ for (const line of output.split(/\r?\n/)) {
81
+ if (!line.trim()) continue;
82
+ const { file, snippet } = splitGrepLine(line);
83
+ if (!file) continue;
84
+ const abs = path.resolve(file);
85
+ if (!found.has(abs)) found.set(abs, { keywords: new Set(), snippets: new Map() });
86
+ const entry = found.get(abs);
87
+ entry.keywords.add(kw);
88
+ if (snippet && !entry.snippets.has(snippet)) entry.snippets.set(snippet, true);
89
+ }
90
+ } catch (e) {
91
+ // findstr/grep returns exit code 1 if no matches
92
+ }
93
+ }
94
+ }
95
+
96
+ // 정렬: 매칭 키워드 수 내림차순 → 스니펫 수 내림차순(밀도) → 경로명(안정화).
97
+ const files = [...found.entries()]
98
+ .map(([file, v]) => ({
99
+ file: file,
100
+ relativePath: path.relative(process.cwd(), file) || file,
101
+ title: path.basename(file, '.md'),
102
+ matchedKeywords: v.keywords.size,
103
+ totalKeywords: keywords.length,
104
+ snippets: [...v.snippets.keys()],
105
+ }))
106
+ .sort((a, b) =>
107
+ b.matchedKeywords - a.matchedKeywords ||
108
+ b.snippets.length - a.snippets.length ||
109
+ a.file.localeCompare(b.file));
110
+
111
+ return { keywords, files };
112
+ }
113
+
114
+ function collectQmdResults(query, config) {
115
+ const qmdPath = findQmd();
116
+ if (!qmdPath) return { available: false, collections: [] };
117
+
118
+ // 두 컬렉션 순회: 컴파일된 wiki + raw 로그.
119
+ const collections = [config.collections.wiki, config.collections.raw];
120
+ const results = [];
121
+ for (const coll of collections) {
122
+ try {
123
+ const output = execSync(`node "${qmdPath}" search "${query}" -c ${coll}`, { encoding: 'utf8', timeout: 30000 });
124
+ if (!isQmdEmpty(output)) results.push({ collection: coll, output: output.trim() });
125
+ } catch (error) {
126
+ // collection missing or QMD error for this collection — try next
127
+ }
128
+ }
129
+ return { available: true, collections: results };
130
+ }
131
+
132
+ function renderSearchText(result) {
133
+ const { query, grep, semantic } = result;
134
+ console.log(`Keyword search (grep) for: "${query}"`);
135
+
136
+ if (grep.files.length === 0) {
137
+ console.log('No direct matches found.');
138
+ } else {
139
+ console.log(`\nDirect matches (${grep.files.length} file(s), ranked by matched keywords):`);
140
+ for (const f of grep.files) {
141
+ console.log(`- [[${f.title}]] (${f.relativePath}) — matched ${f.matchedKeywords}/${f.totalKeywords} keywords`);
142
+ const shown = f.snippets.slice(0, MAX_SNIPPETS_PER_FILE);
143
+ for (const snippet of shown) {
144
+ console.log(` │ ${snippet.length > MAX_SNIPPET_LENGTH ? snippet.slice(0, MAX_SNIPPET_LENGTH) + '…' : snippet}`);
145
+ }
146
+ if (f.snippets.length > shown.length) {
147
+ console.log(` … (${f.snippets.length - shown.length} more matching line(s))`);
148
+ }
149
+ }
150
+ }
151
+
152
+ if (!semantic.available) {
153
+ console.log('\n(QMD not found — semantic search skipped. Install @tobilu/qmd to enable.)');
154
+ return;
155
+ }
156
+
157
+ console.log(`\nSemantic search via QMD: ${query}`);
158
+ if (semantic.collections.length === 0) {
159
+ console.log('No semantic results.');
160
+ return;
161
+ }
162
+ for (const { collection, output } of semantic.collections) {
163
+ console.log(`\n--- Collection: ${collection} ---`);
164
+ console.log(output);
165
+ }
166
+ }
167
+
168
+ // QMD가 빈 결과를 반환하는지 확인 (에러가 아닌 "No results found." 케이스 감지)
169
+ function isQmdEmpty(output) {
170
+ if (!output || !output.trim()) return true;
171
+ return /^no\s+results\s+found\.\s*$/i.test(output.trim());
172
+ }
173
+
174
+ // findstr/grep 출력 행에서 경로와 매칭 줄을 분리한다.
175
+ // findstr: <경로>.md:<내용>
176
+ // grep -n: <경로>.md:<줄번호>:<내용>
177
+ // 경계는 첫 `.md:`로 판정 — 윈도우 절대경로의 드라이브 콜론(`D:`)과 충돌을 피한다.
178
+ function splitGrepLine(line) {
179
+ const idx = line.indexOf('.md:');
180
+ if (idx === -1) return { file: null, snippet: null };
181
+ const file = line.slice(0, idx + 3);
182
+ const snippet = line.slice(idx + 4).replace(/^\d+:/, ''); // POSIX grep 줄번호 제거
183
+ return { file, snippet: snippet.trim() };
184
+ }
185
+
186
+ module.exports = { search };
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@kybird/llm-wiki",
3
+ "version": "0.2.0",
4
+ "description": "LLM-friendly knowledge graph + kanban for AI coding agents. Raw daily logs → compiled wiki → merged semantic+grep search, and a card-per-file kanban the work-loop skill consumes unattended. Drop-in for any repo.",
5
+ "license": "MIT",
6
+ "author": "kybird",
7
+ "bin": {
8
+ "llm-wiki": "bin/llm-wiki.js"
9
+ },
10
+ "files": [
11
+ "bin/",
12
+ "lib/",
13
+ "skills/",
14
+ "templates/",
15
+ "TROUBLESHOOTING.md",
16
+ "README.md"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/kybird/llm-wiki.git"
21
+ },
22
+ "homepage": "https://github.com/kybird/llm-wiki#readme",
23
+ "bugs": "https://github.com/kybird/llm-wiki/issues",
24
+ "optionalDependencies": {
25
+ "@tobilu/qmd": "^2.5.3"
26
+ },
27
+ "engines": {
28
+ "node": ">=18"
29
+ },
30
+ "keywords": [
31
+ "wiki",
32
+ "kanban",
33
+ "llm",
34
+ "ai-agent",
35
+ "knowledge-graph",
36
+ "agentic-memory",
37
+ "claude-code",
38
+ "work-loop"
39
+ ]
40
+ }
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: kanban-plan
3
+ description: Planning loop — turn a plan into board cards the work-loop can consume. Cards are written only via the CLI; decompose with divergence guards, gate what isn't ready.
4
+ skill-version: 2
5
+ ---
6
+ # When to use
7
+
8
+ - When the user plans work: a feature, a refactor, a research question, "이번 주 할 일 정리".
9
+ - When a work session reveals follow-up work — capture it as cards immediately instead of
10
+ letting it evaporate with the session (plan.md 4.1의 파편화가 이것이다).
11
+ - NOT during an unattended loop session — that runs `work-loop`, which consumes cards.
12
+
13
+ # Division of labor (plan.md 2.4)
14
+
15
+ - 기획(this skill) = **분해**: a plan becomes cards.
16
+ - 개발(`work-loop`) = **해소**: pick → done.
17
+ - QA = **수렴 강제**: fake dones get reverted; `board report` shows the ratio.
18
+ - The person watches progress through `llm-wiki board` / `board report` / `board --html`.
19
+ Plan so that this one screen is enough — 리뷰가 카드 수에 비례하면 무인의 의미가 없다.
20
+
21
+ # Before creating cards
22
+
23
+ 1. `llm-wiki search "<keywords>"` — the wall may already have an anti-pattern page or an
24
+ abandoned card with the reason recorded. 폐기 사유는 가장 값비싼 정보다.
25
+ 2. `llm-wiki board` — does a card for this already exist? Extend (`card edit`) or replace
26
+ it (`supersede`); never spawn a near-duplicate. Titles are identifiers (plan.md 3.5):
27
+ no numbers, no versions in titles.
28
+
29
+ # Decomposition rules (divergence guards, plan.md 2.3)
30
+
31
+ - One card = one context = one commit. If you cannot say what the commit would be, it is
32
+ too big — split it.
33
+ - Children must be **strictly smaller** than the parent. When children replace a parent,
34
+ `supersede` it — the parent dissolves, it is not marked done.
35
+ - Depth ≤ 3 (plan → subtask → task). Deeper than that means you are writing the work,
36
+ not planning it.
37
+ - Do not board what is not ready to start:
38
+ - Time condition → `card new "<t>" --not-before 2026-09-05`. `pick` skips it until then.
39
+ - Observational condition → create it, then `handoff <t> --question "조건: …"`. It waits
40
+ in review; anyone who can show the condition holds runs `resume <t> --note "근거"`.
41
+
42
+ # Question timing — start-of-work questions are the cheap ones
43
+
44
+ - In a session where the person is present (planning), ask **before** boarding a card:
45
+ an ambiguous spec answered now costs one question; answered after an unattended loop
46
+ hit the wall, it costs a parked card and a night of latency.
47
+ - The person is away, or the answer can arrive asynchronously: board the card and park it
48
+ immediately — `handoff <t> --question "…"` puts it in review with the question; when the
49
+ answer lands, `resume <t> --note "답: …"` sends it back to todo. handoff is "판정을
50
+ 사람에게 넘기기", not "끝나고 물어보기" — timing follows whoever can answer.
51
+ - An unattended loop session cannot ask before starting (plan.md 2.1 — 승인 대기는
52
+ 오프피크 낭비). There, questions are recorded at the wall and answered in bulk by morning.
53
+
54
+ # Card quality bar
55
+
56
+ - **Goal**: one sentence a stranger can act on (`--goal`). No goal, no card.
57
+ - **AC**: 1–4 items, each verifiable by running or looking at something objective
58
+ (`--ac`, repeat per item). If an AC can only be verified by "읽어보니 되는 것 같다",
59
+ rewrite it — the QA pass reverts evidence-free dones.
60
+ - **Dependencies**: `--depends "다른 카드 제목"` — real DAG edges only (cycles are rejected).
61
+ - **Notes** (`card edit --note`) are the append-only journal; timestamps are added by the CLI.
62
+ - Every write goes through the CLI. A hand-edited card file is out of contract — 사람은 읽기만.
63
+
64
+ # While the work runs
65
+
66
+ - Follow-up discovered mid-task → `card new` right away, then continue. The board is the
67
+ memory, not the session.
68
+ - Plan changed? `supersede` the stale cards. Direction abandoned? `abandon --reason` —
69
+ the reason is mandatory and flows into `doc/raw/` as anti-pattern material.
70
+ - Do not start cards yourself in a planning session — leave them in `todo` for the
71
+ work-loop. 계획과 실행이 같은 세션에 섞이면 파편화가 돌아온다.
@@ -0,0 +1,115 @@
1
+ ---
2
+ name: wiki-compile
3
+ description: Parse raw logs to extract, synthesize, and deprecate project knowledge. Generates high-density grounded wiki pages and maintains the central index.
4
+ skill-version: 2
5
+ ---
6
+ # When to use
7
+ - After accumulating raw logs in doc/raw/
8
+ - When establishing project-wide rules or identifying recurring failures
9
+ - Periodically to restructure the knowledge graph based on new evidence
10
+
11
+ # Action
12
+
13
+ ## Phase 0: Preparation (Automation)
14
+ 1. **Identify New Logs**: Run `llm-wiki compile list`. Detection is date **OR** content-hash
15
+ based (`doc/wiki/compile-state.json`) — same-day appends to an already-compiled log are
16
+ caught too. The listed logs are a real to-do list for Phases 1–3, not a formality.
17
+ 2. **Context Loading**: Read the identified logs and the current `doc/wiki/index.md`.
18
+
19
+ ## Phase 1: High-Density Extraction (LLM)
20
+ 1. For each Case, extract:
21
+ - **Grounding**: Git hash, Confidence score (1-5), Evidence links.
22
+ - **Analytical Core**: The "Why" (First Principles) and "Trade-offs".
23
+ - **Taxonomy**: Concepts, Patterns, Anti-patterns.
24
+ 2. Merge similar cases, favoring the one with the highest **Confidence** and most recent **Git Hash**.
25
+ 3. **Disposition (MANDATORY, per Case)** — classify BEFORE writing any page, and state it in your output:
26
+ - **New**: no existing page covers this → create a page.
27
+ - **Update**: extends an existing page → edit that page, append the Case to its Grounding.
28
+ - **Merge**: duplicates/splits an existing page → fold into it; do not spawn a near-duplicate.
29
+ - **No material**: the Case is a one-off with no reusable lesson → skip it. Raw log is its archive.
30
+ A wiki that grows a page per Case diverges; thin pages dilute search. `No material` is a
31
+ first-class outcome, not a failure.
32
+
33
+ ## Phase 2: Knowledge Promotion & Synthesis (LLM)
34
+ Synthesize extracted data into structured wiki pages. Use the following high-density templates:
35
+
36
+ **Verbatim rule**: quote error messages character-for-character from the raw log — never
37
+ paraphrase. `llm-wiki lint` back-matches every `### Error` quote against `doc/raw/`; a
38
+ summarized quote is reported as an evidence violation.
39
+
40
+ ### Wiki Template (Concept)
41
+ ```markdown
42
+ ---
43
+ status: active | deprecated | draft
44
+ version_context: "e.g., Library X x.y"
45
+ tags: [domain, concept]
46
+ aliases: [synonyms]
47
+ created: YYYY-MM-DD
48
+ confidence: [1-5]
49
+ ---
50
+ # [Concept Name]
51
+ [1-2 sentence summary]
52
+ ## First Principles
53
+ ## Details
54
+ ## Related
55
+ ## Grounding (References)
56
+ ```
57
+
58
+ ### Wiki Template (Pattern)
59
+ ```markdown
60
+ ---
61
+ status: active | deprecated | draft
62
+ version_context: "e.g., Framework X x.y"
63
+ tags: [domain, pattern]
64
+ aliases: [synonyms]
65
+ created: YYYY-MM-DD
66
+ confidence: [1-5]
67
+ ---
68
+ # [Pattern Name]
69
+ [1-2 sentence summary]
70
+ ## The Rule
71
+ ## Why it works
72
+ ## Trade-offs
73
+ ## Anti-Pattern
74
+ ## Related
75
+ ```
76
+
77
+ Anti-pattern pages use `tags: [domain, anti-pattern]` and document the failure mode + prevention checklist.
78
+
79
+ ## Phase 3: Conflict Resolution & Deprecation (LLM)
80
+ 1. **Contradiction Detection**: If a new Case contradicts an old wiki page, mark the old one `status: deprecated` and add `superseded_by: [[new-page]]`.
81
+ 2. **Merging**: If a new Case extends an old page, update the page and append the new Case to "Grounding (References)".
82
+
83
+ ## Phase 4: Indexing & Health (Automation)
84
+ 1. **Rebuild Index**: Run `llm-wiki compile index`. This automatically:
85
+ - Scans all files in `doc/wiki/` (including loose root files, classified by `tags`).
86
+ - Rebuilds the tables in `index.md`.
87
+ - Updates `Statistics` and `Last updated` date.
88
+ - Syncs the QMD search index (creates wiki + raw collections if missing, re-indexes, refreshes embeddings).
89
+ - Regenerates `doc/wiki/compile-state.json` (per-file hashes for same-day append detection).
90
+
91
+ ⚠️ **`compile index` is a "compile complete" declaration.** Running only Phase 4 without
92
+ Phases 1–3 seals every raw log up to now as *compiled*. If the state file ever merges
93
+ badly or goes missing, the resolution is trivial: keep either side (or delete it) and run
94
+ `compile index` once — it is regenerated deterministically from the current `doc/raw/`.
95
+
96
+ ---
97
+
98
+ # QMD (semantic search) notes
99
+
100
+ `llm-wiki compile index` syncs the QMD search index when `@tobilu/qmd` is installed (optional). Without QMD, the wiki index still rebuilds and `llm-wiki search` falls back to grep.
101
+
102
+ ## GPU vs CPU mode (`QMD_LLAMA_GPU`)
103
+
104
+ > **Variable name is `QMD_LLAMA_GPU`** — not `NODE_LLAMA_CPP_GPU`. The latter is read by nothing in the codebase and has no effect.
105
+
106
+ - Default: GPU used automatically when available.
107
+ - To force CPU (e.g., transient CUDA driver issue, VRAM pressure, or NVIDIA GPU asleep):
108
+ ```bash
109
+ QMD_LLAMA_GPU=false llm-wiki compile index
110
+ ```
111
+ - For a permanent override on a problematic machine, set it in your shell profile or a local `.env`.
112
+
113
+ ## Troubleshooting build-time CUDA failures
114
+
115
+ Detailed CUDA Toolkit / MSVC / node-llama-cpp prebuilt-binary diagnostics (Windows + NVIDIA specific) live in **[TROUBLESHOOTING.md](../TROUBLESHOOTING.md)** in the package root. Consult it only if `compile index` prints `falling back to using Vulkan` or `CUDA error` messages.
@@ -0,0 +1,57 @@
1
+ ---
2
+ name: wiki-lint
3
+ description: Validate knowledge graph integrity, detect logical conflicts, and generate a professional health report with Mermaid visualizations.
4
+ skill-version: 1
5
+ ---
6
+ # When to use
7
+ - Before starting a major feature or refactor
8
+ - After a `wiki-compile` run to ensure quality
9
+ - Periodically to prune dead or contradictory knowledge
10
+
11
+ # Action
12
+
13
+ ## Phase 1: Automated Integrity Check (Automation)
14
+ 1. **Run Linter**: Run `llm-wiki lint`.
15
+ 2. **Review Output**:
16
+ - **Broken Links**: List of `[[wikilinks]]` that point to non-existent files.
17
+ - **Missing Metadata**: Files missing required YAML fields or headers.
18
+ - **Version Drift**: Discrepancies between the project package manifest (package.json / pubspec.yaml / Cargo.toml / pyproject.toml) and wiki `version_context`.
19
+
20
+ ## Phase 2: Knowledge Health & Staleness (LLM)
21
+ - Identify pages with `created:` dates older than 6 months for review.
22
+ - Flag concepts that may have been superseded by newer entries but lack `status: deprecated`.
23
+
24
+ ## Phase 3: Conflict & Consistency Check (LLM)
25
+ - Detect pages that directly contradict each other (e.g., one says "always use X", another says "avoid X").
26
+ - When a contradiction is found, decide which is current and mark the other `deprecated` with `superseded_by:` pointing to the winner.
27
+
28
+ ## Phase 4: Professional Health Report
29
+ Generate a summary in `doc/wiki/health_report.md` (or output to console):
30
+
31
+ ### Report Template
32
+ ```markdown
33
+ # 🩺 Wiki Health Report (YYYY-MM-DD)
34
+
35
+ ## 📊 Knowledge Distribution
36
+ \`\`\`mermaid
37
+ pie title Knowledge Types
38
+ "Active Concepts" : [count]
39
+ "Active Patterns" : [count]
40
+ "Deprecated" : [count]
41
+ "Drafts" : [count]
42
+ \`\`\`
43
+
44
+ ## ⚠️ Critical Issues
45
+ - **Broken Links**: [List]
46
+ - **Version Drift**: [List]
47
+ - **Conflicts**: [List]
48
+
49
+ ## 🛠️ Auto-Fix Summary
50
+ - [x] Fixed YAML indentation in 3 files
51
+ - [x] Normalized 2 concept titles
52
+ ```
53
+
54
+ ## Phase 5: Auto-Fixing
55
+ - Automatically fix common YAML formatting errors.
56
+ - Normalize link casing to match file names.
57
+ - Update `index.md` if any titles were normalized (run `llm-wiki compile index`).
@@ -0,0 +1,157 @@
1
+ ---
2
+ name: wiki-log
3
+ description: Record knowledge into raw memory with Karpathy-inspired Agentic Memory format. Captures errors, decisions, and discoveries with high-density grounding.
4
+ skill-version: 1
5
+ ---
6
+ # When to use
7
+ - After an error occurs or a bug is fixed
8
+ - After making a design decision or architectural choice
9
+ - After verifying a hypothesis or benchmarking performance
10
+ - When discovering non-obvious behavior (library quirk, platform limitation)
11
+ - When documenting "why" something was done a certain way
12
+
13
+ # Input
14
+ - type: error | design | verification | discovery (default: error)
15
+ - task: what you tried to do or decided
16
+ - error: (for type=error) error message or incorrect behavior
17
+ - wrong_code: (for type=error) incorrect code that caused the issue
18
+ - fix_code: corrected or final code
19
+ - decision: (for type=design) the decision made and alternatives considered
20
+ - result: (for type=verification) test results, benchmarks, or measurements
21
+ - finding: (for type=discovery) what was discovered
22
+ - environment: key package versions or context
23
+ - is_migration_fix: boolean (true if due to version upgrade or deprecation)
24
+ - git_hash: (optional) current git commit hash for grounding
25
+ - confidence: (1-5) how certain are we about this knowledge
26
+
27
+ # Action
28
+ 1. Determine Date Filename
29
+ - Use current date in format: YYYY-MM-DD.md
30
+ - File path: doc/raw/YYYY-MM-DD.md
31
+
32
+ 2. Concept Drift Protection (MANDATORY)
33
+ - **Search before naming**: Use `llm-wiki search` or `ls doc/wiki/concepts/` to find existing concepts.
34
+ - Reuse existing names to maintain a dense, high-utility knowledge graph.
35
+ - **Collect aliases**: While searching, note every other name the same concept travels under
36
+ (Korean/English variants, error codes, product shorthand). Record them so compile can put
37
+ `aliases: [...]` in the wiki page frontmatter — search fails when the writer's word and the
38
+ searcher's word differ (plan.md 5.1(3)).
39
+
40
+ 3. Verbatim Error Preservation (MANDATORY)
41
+ - The `### Error` section must contain the error message **character-for-character** — copy-paste,
42
+ never paraphrase or summarize. Later searches paste real error strings; a summarized message
43
+ deletes exactly the strings they would match.
44
+
45
+ 4. Create Entry — choose format based on type:
46
+
47
+ ### Type: error
48
+ ```markdown
49
+ ## Case N: [Title]
50
+
51
+ ### Grounding
52
+ - Git Context: `hash:[git_hash]`
53
+ - Evidence: [path/to/artifact or log]
54
+ - Confidence: [1-5]/5
55
+
56
+ ### Error
57
+ [error message or incorrect behavior]
58
+
59
+ ### Environment Context
60
+ - Packages: [environment]
61
+ - Migration Issue: [Yes/No]
62
+
63
+ ### Fix Code
64
+ [corrected code]
65
+
66
+ ### Analysis
67
+ - Root cause: [brief explanation]
68
+ - Why it failed: [First principles analysis]
69
+ - How it was fixed: [explanation]
70
+
71
+ ### Related Knowledge
72
+ - Concepts: [[concept-name]]
73
+ - Patterns: [[pattern-name]]
74
+ - **Anti-Patterns**: [[what-to-avoid]]
75
+ ```
76
+
77
+ ### Type: design
78
+ ```markdown
79
+ ## Case N: [Title]
80
+
81
+ ### Grounding
82
+ - Git Context: `hash:[git_hash]`
83
+ - Confidence: [1-5]/5
84
+
85
+ ### Design Decision
86
+ [what was decided]
87
+
88
+ ### Alternatives Considered
89
+ - Option A: [description] — [why rejected]
90
+ - Option B: [description] — [why rejected]
91
+ - Selected: [why chosen]
92
+
93
+ ### Decision Code
94
+ [code implementing the decision]
95
+
96
+ ### Analysis
97
+ - Context: [situation/constraint]
98
+ - **Trade-offs**: [Memory vs Speed / Cost vs Complexity]
99
+ - Reversibility: [High/Low]
100
+
101
+ ### Related Knowledge
102
+ - Concepts: [[concept-name]]
103
+ - Patterns: [[pattern-name]]
104
+ - **Anti-Patterns**: [[rejected-design-pattern]]
105
+ ```
106
+
107
+ ### Type: verification
108
+ ```markdown
109
+ ## Case N: [Title]
110
+
111
+ ### Grounding
112
+ - Git Context: `hash:[git_hash]`
113
+ - Artifact: [path/to/benchmark_result.json]
114
+ - Confidence: [1-5]/5
115
+
116
+ ### Hypothesis
117
+ [what was being tested]
118
+
119
+ ### Results
120
+ [measurements, benchmarks]
121
+
122
+ ### Analysis
123
+ - Confirmed/Refuted: [result]
124
+ - Key metrics: [numbers]
125
+ - Implications: [project impact]
126
+
127
+ ### Related Knowledge
128
+ - Concepts: [[concept-name]]
129
+ - Patterns: [[pattern-name]]
130
+ ```
131
+
132
+ ### Type: discovery
133
+ ```markdown
134
+ ## Case N: [Title]
135
+
136
+ ### Grounding
137
+ - Git Context: `hash:[git_hash]`
138
+ - Evidence: [logs or data]
139
+ - Confidence: [1-5]/5
140
+
141
+ ### Discovery
142
+ [what was found - non-obvious behavior]
143
+
144
+ ### Analysis
145
+ - Why non-obvious: [Surprise factor]
146
+ - Impact: [how this affects the project]
147
+ - Action taken: [mitigation/leveraging]
148
+
149
+ ### Related Knowledge
150
+ - Concepts: [[concept-name]]
151
+ - Patterns: [[pattern-name]]
152
+ ```
153
+
154
+ # Output
155
+ - File created or updated: doc/raw/YYYY-MM-DD.md
156
+ - Case anchor for direct linking: #case-N
157
+ - **Index Update**: Run `llm-wiki compile index` to make the new case searchable (rebuilds wiki index + syncs QMD search index). If QMD is not installed, the case is still found via grep fallback.
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: wiki-search
3
+ description: Retrieve relevant past knowledge. Filters out deprecated practices and follows migration trails.
4
+ skill-version: 1
5
+ ---
6
+ # When to use
7
+ - BEFORE writing any code
8
+ - At the start of every task
9
+
10
+ # Input
11
+ - current task description
12
+
13
+ # Action
14
+ 1. **Search via CLI (Recommended)**:
15
+ - Run: `llm-wiki search "<task keywords>"`
16
+ - Always runs BOTH grep exact matching AND QMD semantic search (when installed) and merges
17
+ them — grep results are ranked by matched-keyword count with line snippets.
18
+ - Prefer pasting the **verbatim error string** as the query; exact strings are what grep
19
+ guarantees to find.
20
+
21
+ 2. **Follow Links**:
22
+ - Use bidirectional links `[[link]]` and tags to navigate related knowledge.
23
+
24
+ 3. **Deprecation Check (CRITICAL)**:
25
+ - For every page found, check the YAML `status`.
26
+ - If `status: deprecated`, follow `superseded_by`.
27
+
28
+ # Output Format
29
+ - Warnings: Include any anti-patterns or recently deprecated methods found.
30
+ - Recommendations: Based ONLY on `status: active` patterns.
31
+ - Related cases: [[case-link]]
32
+
33
+ # Answer Archiving
34
+ - If this search produced a genuinely useful **synthesized answer** (spanning several pages,
35
+ the kind a future session will re-derive at real cost), promote it:
36
+ - Write `doc/wiki/answers/<topic>.md` — frontmatter: `status: active`, `created: YYYY-MM-DD`,
37
+ `tags: [...]`, `aliases: [...]`, plus the answer body with `[[links]]` back to sources.
38
+ - Next `llm-wiki compile index` lists it in the Answers section and it becomes searchable.
39
+ - Archive answers, not raw search dumps: a question answered in one page does not need this.