llm-wiki-kit 0.2.6 → 0.2.7

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.
package/README.md CHANGED
@@ -86,7 +86,7 @@ Use Claude Code or Codex normally.
86
86
 
87
87
  The installed hooks:
88
88
 
89
- - inject `wiki/memory.md`, `wiki/index.md`, and relevant wiki context at session start, instructions loaded, prompt submit, and post-compact time
89
+ - inject functional compact context at session start, instructions loaded, prompt submit, and post-compact time. The hook still uses `wiki/memory.md`, `wiki/index.md`, relevant wiki search results, maintenance signals, and update status; it formats only the useful parts so user-visible hook context does not look like a raw debug dump.
90
90
  - remove Codex-facing legacy `oh-my-codex:wiki`/`omx_wiki` surfaces at session start so `llm-wiki/` remains the active wiki implementation
91
91
  - record small redacted raw event envelopes and per-turn state
92
92
  - capture decision points, debugging findings, changed files, and verification notes
@@ -119,11 +119,11 @@ Most users should not need these during daily Claude Code/Codex work. They exist
119
119
 
120
120
  `llm-wiki update` upgrades the global npm package when npm has a newer target, reinstalls the hook entries, and reapplies safe managed template updates across known project roots. If the installed runtime already satisfies the registry target, it skips `npm install -g` and still runs post-update maintenance. Use `--current-only` when you intentionally want to update only the supplied workspace. Existing wiki content is not overwritten. The command prints step progress to stderr, including registry lookup, npm install, post-update, and project discovery. Use `--timeout-ms <ms>` to bound external commands and `--max-dirs <n>` to bound project discovery under large or slow roots such as WSL `/mnt/*` trees.
121
121
 
122
- Installed npm runtimes also perform a cached update notice check from hooks while the user works. This does not install anything automatically. When a newer npm release is detected, the injected hook context gives the active agent a Korean update reminder and tells it to offer `llm-wiki update --workspace <project-or-search-root>`. The cache is scoped to the npm command used for lookup so test/fake npm checks do not leak into normal hook sessions. Set `LLM_WIKI_KIT_UPDATE_NOTICE=0` only when diagnosing or suppressing that reminder.
122
+ Installed npm runtimes also perform a cached update notice check from hooks while the user works. This does not install anything automatically. When a newer npm release is detected, Codex and Claude receive the same passive runtime update status in hook context: current runtime, npm registry target, and the manual command to use when the user asks for update or maintenance work. It is not an instruction to interrupt the current answer or to sell the update to the user. The cache is scoped to the npm command used for lookup so test/fake npm checks do not leak into normal hook sessions. Set `LLM_WIKI_KIT_UPDATE_NOTICE=0` only when diagnosing or suppressing that status block.
123
123
 
124
124
  `llm-wiki post-update --workspace <project>` reapplies the current runtime's hook entries and safe managed template updates without running `npm install -g`. Use `post-update --all --workspace <search-root>` to reapply templates across discovered project roots.
125
125
 
126
- `llm-wiki context "<query>"` prints the same layered context used by hooks. It is mainly for debugging what Codex/Claude Code will see; daily use should rely on hook injection. By default, episodic `wiki/queries/` pages are excluded from search unless they were promoted with `memory_type: semantic` or `procedural` and `importance >= 4`; use `--include-episodic` only when debugging old automatic query records.
126
+ `llm-wiki context "<query>"` prints the full debug view of the layered context sources used by hooks. Hook injection may render those sources as functional compact context for Codex and Claude, but this CLI stays verbose so maintainers can inspect retrieval, snippets, memory, index, and expansion behavior. Daily use should rely on hook injection. By default, episodic `wiki/queries/` pages are excluded from search unless they were promoted with `memory_type: semantic` or `procedural` and `importance >= 4`; use `--include-episodic` only when debugging old automatic query records.
127
127
 
128
128
  `llm-wiki lint` checks wiki health and detects outdated managed rules from older kit versions. Agents may use it before/after meaningful wiki maintenance.
129
129
 
@@ -42,12 +42,12 @@ when no project `CLAUDE.md` exists. Existing `CLAUDE.md` files are not overwritt
42
42
 
43
43
  The hook records redacted turn summaries but does not deny tool calls only because an input looks sensitive. Hook payloads are stored as small redacted event envelopes rather than full transcripts, and context output is redacted field by field before it is returned to Claude Code.
44
44
 
45
- At `SessionStart`/`InstructionsLoaded`, the hook first attempts a safe managed-template refresh, recovers stale turn state into `outputs/maintenance/queue.md`, performs a cached npm update notice check for npm installs, then injects `llm-wiki/wiki/memory.md`, `llm-wiki/wiki/index.md`, recent log context, operating rules, a one-item maintenance summary when needed, any Korean update notice, and any maintenance note for outdated or customized managed rules. At `UserPromptSubmit`, it recovers stale turn state, searches wiki pages with MiniSearch or substring fallback, expands one-hop wikilinks, redacts context fields, performs the same cached update notice check, and injects the smallest useful context set. Update notice cache is scoped by npm command, and maintenance reminders are shown only when the prompt is wiki/maintenance related or matches a queue topic.
45
+ At `SessionStart`/`InstructionsLoaded`, the hook first attempts a safe managed-template refresh, recovers stale turn state into `outputs/maintenance/queue.md`, performs a cached npm update notice check for npm installs, then injects functional compact context. The context still uses `llm-wiki/wiki/memory.md`, `llm-wiki/wiki/index.md`, relevant wiki/search state, operating rules, maintenance signals, passive runtime update status, and managed-template cleanup notes; the hook formats those signals so they are usable if shown in the Claude Code UI. At `UserPromptSubmit`, it recovers stale turn state, searches wiki pages with MiniSearch or substring fallback, expands one-hop wikilinks, redacts context fields, performs the same cached update notice check, and injects the smallest useful functional compact context set. Update notice cache is scoped by npm command, and maintenance reminders are shown only when the prompt is wiki/maintenance related or matches a queue topic.
46
46
 
47
47
  `PostToolUse` and `PostToolBatch` record redacted tool summaries in the same turn buffer. `PreCompact` records a compaction note, and `PostCompact` records the note and returns fresh wiki context. In the default `answer-first` mode, `SubagentStop` does not create live Q&A, query, decision, or maintenance files. `Stop` and `SessionEnd` append live Q&A only for meaningful work turns and do not auto-create `wiki/queries/` or `wiki/decisions/`. If the user explicitly asked to record or document durable knowledge and no durable wiki update is detected, `Stop`/`SessionEnd` queue a pending maintenance item for agent review. `Stop` and `SessionEnd` then clear the per-session turn buffer; `SubagentStop` does not.
48
48
 
49
49
  Set `LLM_WIKI_KIT_AUTO_PROJECT_UPDATE=0` only while diagnosing automatic managed-template refresh behavior.
50
- Set `LLM_WIKI_KIT_UPDATE_NOTICE=0` only while suppressing the cached npm update reminder.
50
+ Set `LLM_WIKI_KIT_UPDATE_NOTICE=0` only while suppressing the cached passive runtime update status.
51
51
  Set `LLM_WIKI_KIT_CAPTURE_MODE=legacy-eager` only as deprecated compatibility mode for the old eager query/decision capture behavior.
52
52
 
53
53
  After installation or update, run:
@@ -29,8 +29,8 @@ Handled events:
29
29
 
30
30
  Expected behavior:
31
31
 
32
- - `SessionStart` first attempts a safe managed-template refresh, removes Codex-facing legacy `oh-my-codex:wiki`/`omx_wiki` surfaces when they reappear, recovers stale turn state into `outputs/maintenance/queue.md`, performs a cached npm update notice check for npm installs, then injects `llm-wiki/wiki/memory.md`, `llm-wiki/wiki/index.md`, recent log context, operating rules, a one-item maintenance summary when needed, any Korean update notice, and any maintenance note for outdated or customized managed rules.
33
- - `UserPromptSubmit` recovers stale turn state, searches project wiki pages with MiniSearch or substring fallback, expands one-hop wikilinks, redacts context fields, performs the same cached update notice check, and injects the smallest useful context set. Update notice cache is scoped by npm command, and maintenance reminders are shown only when the prompt is wiki/maintenance related or matches a queue topic.
32
+ - `SessionStart` first attempts a safe managed-template refresh, removes Codex-facing legacy `oh-my-codex:wiki`/`omx_wiki` surfaces when they reappear, recovers stale turn state into `outputs/maintenance/queue.md`, performs a cached npm update notice check for npm installs, then injects functional compact context. The context still uses `llm-wiki/wiki/memory.md`, `llm-wiki/wiki/index.md`, relevant wiki/search state, operating rules, maintenance signals, passive runtime update status, and managed-template cleanup notes; the hook formats those signals so they are usable if shown in the Codex UI.
33
+ - `UserPromptSubmit` recovers stale turn state, searches project wiki pages with MiniSearch or substring fallback, expands one-hop wikilinks, redacts context fields, performs the same cached update notice check, and injects the smallest useful functional compact context set. Update notice cache is scoped by npm command, and maintenance reminders are shown only when the prompt is wiki/maintenance related or matches a queue topic.
34
34
  - `PreToolUse` records redacted tool summaries without blocking tool calls.
35
35
  - `PostToolUse` records redacted tool summaries in a turn buffer.
36
36
  - `PreCompact` records a compaction note; `PostCompact` records the note and returns fresh wiki context.
@@ -38,10 +38,10 @@ Expected behavior:
38
38
  - If the user explicitly asked to record or document durable knowledge and no durable wiki update is detected, `Stop` queues a pending maintenance item for agent review.
39
39
  - `Stop` clears the per-session turn buffer after recording. `SubagentStop` leaves the parent turn buffer available for the final stop event.
40
40
 
41
- Hook payloads are stored as small redacted event envelopes rather than full transcripts. Context output is also redacted field by field before it is returned to Codex.
41
+ Hook payloads are stored as small redacted event envelopes rather than full transcripts. Context output is also redacted field by field before it is returned to Codex. Functional compact context is a presentation policy, not a feature reduction: Codex still receives the wiki memory, search, maintenance, and passive update signals needed for the hook workflow.
42
42
 
43
43
  Set `LLM_WIKI_KIT_AUTO_PROJECT_UPDATE=0` only while diagnosing automatic managed-template refresh behavior.
44
- Set `LLM_WIKI_KIT_UPDATE_NOTICE=0` only while suppressing the cached npm update reminder.
44
+ Set `LLM_WIKI_KIT_UPDATE_NOTICE=0` only while suppressing the cached passive runtime update status.
45
45
  Set `LLM_WIKI_KIT_CAPTURE_MODE=legacy-eager` only as deprecated compatibility mode for the old eager query/decision capture behavior.
46
46
 
47
47
  Run these after install:
package/docs/manual.md CHANGED
@@ -50,7 +50,7 @@ llm-wiki/
50
50
  └── procedures/
51
51
  ```
52
52
 
53
- `wiki/memory.md`는 hook context에 들어가는 짧은 hot index다. 긴 설명을 복사하지 말고 중요한 entry point만 둔다.
53
+ `wiki/memory.md`는 hook context에 들어가는 짧은 hot index다. hook은 기능을 유지하되 사용자 화면에 보일 수 있는 부분을 functional compact context로 정제하므로, 긴 설명을 복사하지 말고 중요한 entry point만 둔다.
54
54
 
55
55
  `wiki/index.md`는 wiki 전체의 navigation map이다. agent는 넓은 질문을 받으면 여기와 `memory.md`에서 시작한다.
56
56
 
@@ -62,7 +62,7 @@ llm-wiki/
62
62
 
63
63
  설치된 hook은 다음 일을 자동으로 수행한다.
64
64
 
65
- - session start, prompt submit, post compact 시점에 `wiki/memory.md`, `wiki/index.md`, 관련 wiki 검색 결과를 context 주입한다.
65
+ - session start, prompt submit, post compact 시점에 functional compact context를 주입한다. `wiki/memory.md`, `wiki/index.md`, 관련 wiki 검색 결과, maintenance signal, update status는 계속 사용하되 사용자 화면에 보일 수 있는 hook context 필요한 정보 중심으로 정제한다.
66
66
  - prompt/tool/result summary를 redaction한 뒤 turn buffer에 기록한다.
67
67
  - 의미 있는 작업 turn만 `outputs/questions/YYYY-MM-DD-live-qa.md`에 live Q&A로 남긴다.
68
68
  - 기본 answer-first mode에서는 `wiki/queries/`와 `wiki/decisions/`를 매 turn 자동 생성하지 않는다.
@@ -71,6 +71,8 @@ llm-wiki/
71
71
  - 새 runtime이 오래된 project rules/templates를 발견하면 안전하게 갱신 가능한 managed file만 refresh한다.
72
72
  - `SessionStart`/`InstructionsLoaded`에서 Codex-facing legacy `oh-my-codex:wiki`/`omx_wiki` 설정과 스킬 표면이 되살아났는지 확인하고 제거한다. wiki 기능은 `llm-wiki/`가 단일 활성 구현이다.
73
73
 
74
+ hook UX 정책은 기능 보존이 우선이다. Codex와 Claude Code 모두 같은 기능 신호를 받으며, 차이는 raw dump가 아니라 읽기 쉬운 functional compact formatting으로 보여주는 것이다.
75
+
74
76
  매번 저장 여부를 사용자가 고민해야 한다면 잘못 쓰고 있는 것이다. 답변보다 wiki maintenance가 먼저 오면 안 된다. 현재 사용자 요청을 먼저 처리하고, 오래 쓸 지식만 필요한 만큼 정리한다.
75
77
 
76
78
  ## Capture Modes
@@ -161,7 +163,7 @@ llm-wiki update --workspace /path/to/search-root --timeout-ms 120000 --max-dirs
161
163
 
162
164
  `update`는 source checkout에서 self-update하지 않는다. source checkout 개발 중에는 npm package나 local tarball로 global install한 뒤 update behavior를 테스트한다.
163
165
 
164
- global npm runtime으로 설치된 경우 hook은 사용 흐름 중 cached update notice check를 수행한다. 자동 설치는 하지 않는다. 새 npm release가 감지되면 hook context가 active agent에게 한국어로 “업데이트 가능”을 짧게 알리고 `llm-wiki update --workspace <project-or-search-root>` 실행을 제안하게 한다. cache는 lookup에 사용한 npm command별로 분리되어 test/fake npm 결과가 일반 hook session에 섞이지 않는다. `LLM_WIKI_KIT_UPDATE_NOTICE=0`으로 이 reminder만 끌 수 있다.
166
+ global npm runtime으로 설치된 경우 hook은 사용 흐름 중 cached update notice check를 수행한다. 자동 설치는 하지 않는다. 새 npm release가 감지되면 hook context에는 passive runtime update status들어간다. block은 현재 runtime, npm registry target, 업데이트/정비 요청이 있을 때 쓸 수 있는 `llm-wiki update --workspace <project-or-search-root>` 명령을 짧게 보여주는 상태 정보다. 현재 답변을 중단하거나 업데이트 권유를 하라는 지시문이 아니다. cache는 lookup에 사용한 npm command별로 분리되어 test/fake npm 결과가 일반 hook session에 섞이지 않는다. `LLM_WIKI_KIT_UPDATE_NOTICE=0`으로 이 status block만 끌 수 있다.
165
167
 
166
168
  ### `llm-wiki post-update`
167
169
 
@@ -260,7 +262,7 @@ older OMX/OMC/`omx_wiki/` material은 migration input일 뿐이다. 현재 proje
260
262
 
261
263
  ### `llm-wiki context`
262
264
 
263
- hook이 주입하는 layered context를 수동으로 확인한다.
265
+ hook이 사용하는 layered context sourcefull debug 형태로 수동 확인한다. Codex/Claude hook은 같은 source를 functional compact context로 정제해 주입할 수 있지만, 이 CLI는 retrieval과 formatting 문제를 점검할 수 있도록 verbose debug 출력을 유지한다.
264
266
 
265
267
  ```bash
266
268
  llm-wiki context "auth architecture" --workspace /path/to/project
@@ -384,6 +386,8 @@ Claude Code handled events:
384
386
 
385
387
  Hook payload는 full transcript가 아니라 작은 redacted event envelope다. context output도 field별 redaction을 거친다.
386
388
 
389
+ Context를 반환하는 Codex/Claude hook event는 기능을 제거하지 않는다. memory hot index, navigation index, relevant wiki hits, link expansion, maintenance signal, passive runtime update status를 계속 사용할 수 있고, 사용자 화면에 보일 수 있는 `additionalContext`만 functional compact context로 정제한다. `llm-wiki context` CLI의 full debug 출력은 이 hook formatting 정책과 별도로 유지한다.
390
+
387
391
  ## Security Defaults
388
392
 
389
393
  기본 정책은 aggressive blocking보다 useful local work wiki를 우선한다.
@@ -118,7 +118,7 @@ llm-wiki maintenance --workspace /path/to/project
118
118
 
119
119
  `update --check [--to <version-or-tag>]` is online and asks npm for the target version. It reports `update available` only when that registry target is newer than the installed version, so it does not suggest downgrades.
120
120
 
121
- Installed npm runtimes also run a cached hook-side update notice check while the user works. It never installs automatically. If npm has a newer release, `SessionStart`/`InstructionsLoaded`/`UserPromptSubmit` context gives the active agent a Korean update reminder and tells it to offer `llm-wiki update --workspace <project-or-search-root>`. The cache is scoped to the npm command used for lookup so test/fake npm checks do not leak into normal hook sessions. Set `LLM_WIKI_KIT_UPDATE_NOTICE=0` to suppress this reminder while diagnosing.
121
+ Installed npm runtimes also run a cached hook-side update notice check while the user works. It never installs automatically. If npm has a newer release, `SessionStart`/`InstructionsLoaded`/`UserPromptSubmit` context includes a passive runtime update status for both Codex and Claude: current runtime, npm registry target, and the manual `llm-wiki update --workspace <project-or-search-root>` command to use when the user asks for update or maintenance work. It is not an active instruction to interrupt the current answer or tell the user to update. The cache is scoped to the npm command used for lookup so test/fake npm checks do not leak into normal hook sessions. Set `LLM_WIKI_KIT_UPDATE_NOTICE=0` to suppress this status block while diagnosing.
122
122
 
123
123
  `projects --workspace <search-root>` lists discovered project roots that have `llm-wiki/.kit-state.json` or an older `llm-wiki/wiki/index.md`, reports whether their managed templates are current, and prints the update commands for the search root.
124
124
 
@@ -141,13 +141,13 @@ After a plain `npm install -g llm-wiki-kit@latest`, existing hooks keep working
141
141
 
142
142
  ## Context And Wiki Maintenance
143
143
 
144
- Daily use should be Claude Code/Codex first. The user should not need to run a chain of `llm-wiki` commands while working. Hooks inject context automatically, but the current user answer takes priority over wiki cleanup. The active agent updates durable wiki pages when reusable project knowledge appears and the turn's importance or user consent justifies persistence.
144
+ Daily use should be Claude Code/Codex first. The user should not need to run a chain of `llm-wiki` commands while working. Hooks inject context automatically, but the current user answer takes priority over wiki cleanup. The active agent updates durable wiki pages when reusable project knowledge appears and the turn's importance or user consent justifies persistence. Hook context policy is function-first: memory, search, maintenance, and update signals remain available, while user-visible context is formatted as functional compact context instead of a raw dump.
145
145
 
146
146
  In the default `LLM_WIKI_KIT_CAPTURE_MODE=answer-first` mode, `Stop` and `SessionEnd` append live Q&A only for meaningful work turns. They do not auto-create `wiki/queries/` or `wiki/decisions/`. If the user explicitly asked for recording/documentation and no durable wiki update is detected, a pending cleanup candidate is written to `llm-wiki/outputs/maintenance/queue.md`. `SessionStart` and `UserPromptSubmit` also recover stale per-turn state into the same queue when the previous stop hook did not complete. `SessionStart` injects a one-item queue summary; `UserPromptSubmit` injects a soft reminder only when the prompt is wiki/maintenance related or matches a queue topic. This is a recovery and reminder layer, not a full transcript capture path.
147
147
 
148
148
  `LLM_WIKI_KIT_CAPTURE_MODE=legacy-eager` keeps the old eager live Q&A/query/decision/maintenance behavior for compatibility only. New projects should rely on the answer-first default.
149
149
 
150
- `llm-wiki context "<query>"` is the manual debug form of hook context injection. It reads:
150
+ `llm-wiki context "<query>"` is the manual full-debug form of the context sources used by hook injection. Hook output for Codex and Claude may be functionally compact, but this command remains verbose so maintainers can inspect all source layers. It reads:
151
151
 
152
152
  - `llm-wiki/wiki/memory.md` as the short hot index
153
153
  - `llm-wiki/wiki/index.md` as the navigation map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-wiki-kit",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Hook-first living LLM Wiki runtime for Codex and Claude Code.",
5
5
  "type": "module",
6
6
  "files": [
@@ -153,12 +153,5 @@ export function formatDurableCaptureGuidance(query) {
153
153
  '- 새 문서는 관련 기존 문서가 없을 때만 만들고, credentials/private data는 저장하지 않는다.',
154
154
  ].join('\n');
155
155
  }
156
- if (hasDurableKeyword(text)) {
157
- return [
158
- 'LLM Wiki 저장 후보 알림:',
159
- '- 현재 답변을 먼저 한다.',
160
- '- 다음 세션에도 재사용할 만한 내용(결정, 정책, 디버깅 결과, 운영 절차, 검증된 상태 등)이 있으면 답변 끝에서 짧게 wiki 문서화 여부를 물어본다.',
161
- ].join('\n');
162
- }
163
156
  return '';
164
157
  }
@@ -240,15 +240,15 @@ export function formatMaintenanceContext(summary, options = {}) {
240
240
 
241
241
  const lines = [
242
242
  eventName === 'UserPromptSubmit'
243
- ? 'LLM Wiki maintenance queue soft reminder:'
244
- : 'LLM Wiki maintenance queue summary:',
245
- `- pending: ${summary.pendingCount}. 현재 사용자 요청을 지연시키지 말고, 관련 있을 때만 기존 durable wiki 문서에 병합한다.`,
243
+ ? 'LLM Wiki maintenance status:'
244
+ : 'LLM Wiki maintenance status:',
245
+ `- pending review items: ${summary.pendingCount}. 현재 요청이 우선이며, 관련 있을 때만 durable wiki 정리에 사용한다.`,
246
246
  ];
247
247
  for (const item of pending) {
248
- lines.push(`- ${item.topic || item.id}: source=${item.source}; target=${item.suggested_target}; reason=${item.reason}${item.result_missing ? '; result_missing=true' : ''}`);
248
+ lines.push(`- ${item.topic || item.id}: ${item.suggested_target}; source=${item.source}${item.result_missing ? '; result missing' : ''}`);
249
249
  }
250
250
  if (summary.pending.length > pending.length) {
251
- lines.push(`- ${summary.pending.length - pending.length} more pending item(s) hidden from context.`);
251
+ lines.push(`- ${summary.pending.length - pending.length} more pending item(s) available in llm-wiki/outputs/maintenance/queue.md.`);
252
252
  }
253
253
  return lines.join('\n');
254
254
  }
package/src/project.js CHANGED
@@ -13,7 +13,7 @@ import { formatMaintenanceContext, maintenanceSummary } from './maintenance.js';
13
13
  import { normalizeForStorage, redactText, summarizeForStorage } from './redaction.js';
14
14
  import { gitignore, indexPage, llmWikiAgents, logPage, memoryPage, procedure, rootAgentsPolicy } from './templates.js';
15
15
  import { formatProjectMaintenanceContext, inspectProjectState, recordManagedTemplates } from './project-state.js';
16
- import { buildContextPack, formatContextPack, searchWiki as searchWikiWithIndex } from './wiki-search.js';
16
+ import { buildContextPack, formatHookContextPack, searchWiki as searchWikiWithIndex } from './wiki-search.js';
17
17
 
18
18
  export async function bootstrapProject(projectRoot, options = {}) {
19
19
  if (process.env.LLM_WIKI_KIT_DISABLE_BOOTSTRAP === '1') return { created: false };
@@ -171,5 +171,9 @@ export async function buildContextBrief(projectRoot, eventName, query = '') {
171
171
  const wikiMaintenance = await maintenanceSummary(projectRoot)
172
172
  .then((summary) => formatMaintenanceContext(summary, { eventName, query }))
173
173
  .catch(() => '');
174
- return [formatContextPack(pack), maintenance, wikiMaintenance].filter(Boolean).join('\n\n');
174
+ return [formatHookContextPack(pack, {
175
+ eventName,
176
+ hitLimit: eventName === 'SessionStart' ? 2 : 3,
177
+ logLineLimit: eventName === 'SessionStart' ? 2 : 0,
178
+ }), maintenance, wikiMaintenance].filter(Boolean).join('\n\n');
175
179
  }
@@ -114,12 +114,11 @@ export async function updateNoticeContext(projectRoot, eventName, options = {})
114
114
  const workspace = resolve(projectRoot || process.cwd());
115
115
  const updateCommand = commandForProject('update', workspace);
116
116
  return [
117
- 'LLM Wiki 업데이트 알림:',
118
- `- 설치된 llm-wiki-kit: ${notice.installedVersion}`,
119
- `- npm 최신 릴리스: ${notice.latestVersion}`,
120
- '- hook 사용 새로운 llm-wiki-kit 릴리스가 자동 감지되었습니다.',
121
- `- 사용자에게 업데이트 가능 사실을 짧게 알리고 다음 명령 실행을 제안하세요: \`${updateCommand}\``,
122
- '- 알려진 모든 프로젝트 root를 업데이트하려면 같은 명령에서 더 넓은 search root를 사용합니다. 예: `--workspace /apps`.',
123
- '- 사용자가 요청하기 전에는 자동 설치하지 마세요.',
117
+ 'LLM Wiki runtime update status:',
118
+ `- current hook runtime: ${notice.installedVersion}; npm registry: ${notice.latestVersion}`,
119
+ '- 현재 요청 처리가 우선이며, 현재 runtime 기능은 계속 동작한다.',
120
+ `- 업데이트/정비를 수행할 사용할 명령: \`${updateCommand}\``,
121
+ '- npm 전역 설치 권한 오류가 나면 환경에 맞게 `npm install -g llm-wiki-kit@latest` 또는 `sudo npm install -g llm-wiki-kit@latest` 후 같은 update 명령을 다시 실행한다.',
122
+ '- status만으로 설치나 업데이트를 실행하지 않는다.',
124
123
  ].join('\n');
125
124
  }
@@ -5,11 +5,13 @@ import {
5
5
  buildWikiGraph,
6
6
  collectWikiPages,
7
7
  pageLookup,
8
+ parseFrontmatter,
8
9
  readMemoryExcerpt,
9
10
  } from './wiki-model.js';
10
11
 
11
12
  const DEFAULT_LIMIT = 5;
12
13
  const SNIPPET_CHARS = 350;
14
+ const HOOK_SNIPPET_CHARS = 180;
13
15
  let miniSearchLoader = null;
14
16
 
15
17
  async function loadMiniSearch() {
@@ -202,6 +204,80 @@ function redactHit(hit) {
202
204
  };
203
205
  }
204
206
 
207
+ function compactText(value, maxLength = 220) {
208
+ const text = String(value || '').replace(/\s+/g, ' ').trim();
209
+ if (text.length <= maxLength) return text;
210
+ return `${text.slice(0, Math.max(0, maxLength - 3)).trimEnd()}...`;
211
+ }
212
+
213
+ function stripGeneratedMemoryBlock(value) {
214
+ return String(value || '')
215
+ .replace(/<!-- llm-wiki-kit:memory-start -->[\s\S]*?<!-- llm-wiki-kit:memory-end -->/g, '')
216
+ .trim();
217
+ }
218
+
219
+ function sectionBody(body, heading) {
220
+ const escaped = heading.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
221
+ const match = String(body || '').match(new RegExp(`(?:^|\\n)##\\s+${escaped}\\s*\\n([\\s\\S]*?)(?=\\n##\\s+|$)`, 'i'));
222
+ return match?.[1] || '';
223
+ }
224
+
225
+ function bulletLines(value) {
226
+ return String(value || '')
227
+ .split('\n')
228
+ .map((line) => line.trim())
229
+ .filter((line) => /^-\s+/.test(line))
230
+ .map((line) => compactText(line, 240));
231
+ }
232
+
233
+ function memoryFocusLines(memoryExcerpt, limit = 6) {
234
+ const { body } = parseFrontmatter(memoryExcerpt || '');
235
+ const bodyWithoutGenerated = stripGeneratedMemoryBlock(body);
236
+ const current = bulletLines(sectionBody(bodyWithoutGenerated, 'Current Focus'));
237
+ const entries = bulletLines(sectionBody(bodyWithoutGenerated, 'Durable Entry Points')).slice(0, 2);
238
+ if (current.length > 0) {
239
+ const currentLimit = Math.max(1, limit - entries.length);
240
+ return [...current.slice(-currentLimit), ...entries].slice(0, limit);
241
+ }
242
+
243
+ const bullets = bulletLines(bodyWithoutGenerated);
244
+ if (bullets.length > 0) return bullets.slice(-limit);
245
+
246
+ const lines = bodyWithoutGenerated
247
+ .split('\n')
248
+ .map((line) => line.trim())
249
+ .filter(Boolean);
250
+
251
+ return lines
252
+ .filter((line) => !/^#+\s+/.test(line))
253
+ .map((line) => compactText(line, 240))
254
+ .slice(0, Math.max(1, Math.min(limit, 3)));
255
+ }
256
+
257
+ function logFocusLines(logExcerpt, limit = 2) {
258
+ return String(logExcerpt || '')
259
+ .split('\n')
260
+ .map((line) => line.trim())
261
+ .filter((line) => /^-\s+/.test(line))
262
+ .slice(-limit)
263
+ .map((line) => compactText(line, 220));
264
+ }
265
+
266
+ function metaWikiQuery(query) {
267
+ return /(?:llm-wiki|wiki|위키|memory|메모리|기억|index|인덱스|log|로그|maintenance|queue|문서|문서화|기록|정리|context|컨텍스트)/i.test(String(query || ''));
268
+ }
269
+
270
+ function internalContextPath(path) {
271
+ return /^(?:wiki\/)?(?:memory|index|log)\.md$/i.test(String(path || ''));
272
+ }
273
+
274
+ function hookHits(pack, options = {}) {
275
+ const allowInternal = options.includeInternalHits || metaWikiQuery(pack.query);
276
+ return (pack.hits || [])
277
+ .filter((hit) => allowInternal || !internalContextPath(hit.path))
278
+ .slice(0, options.hitLimit || 3);
279
+ }
280
+
205
281
  export async function buildContextPack(projectRoot, query, options = {}) {
206
282
  const limit = Number(options.limit || DEFAULT_LIMIT);
207
283
  const expand = options.expand !== false;
@@ -258,3 +334,45 @@ export function formatContextPack(pack) {
258
334
  }
259
335
  return lines.join('\n').trim();
260
336
  }
337
+
338
+ export function formatHookContextPack(pack, options = {}) {
339
+ const lines = [
340
+ 'LLM Wiki context (functional compact):',
341
+ '- Priority: answer the current user request first; use wiki context when it helps.',
342
+ '- 기능 유지: hook memory/search/capture/maintenance/update signals are active.',
343
+ '- Durable project knowledge belongs in llm-wiki/wiki; never store credentials, tokens, private keys, or .env contents.',
344
+ ];
345
+ if (pack.query) {
346
+ lines.push(`- query: "${compactText(pack.query, 180)}"`);
347
+ lines.push(`- search: ${pack.search}`);
348
+ }
349
+
350
+ const memoryLines = memoryFocusLines(pack.memoryExcerpt, options.memoryLineLimit ?? 6);
351
+ if (memoryLines.length > 0) {
352
+ lines.push('', 'Memory focus:');
353
+ lines.push(...memoryLines.map((line) => `- ${line.replace(/^-\s+/, '')}`));
354
+ } else {
355
+ lines.push('', 'Memory focus:', '- See llm-wiki/wiki/memory.md and llm-wiki/wiki/index.md when project context is needed.');
356
+ }
357
+
358
+ const hits = hookHits(pack, options);
359
+ if (hits.length > 0) {
360
+ lines.push('', 'Relevant wiki pages:');
361
+ for (const hit of hits) {
362
+ const suffix = hit.source === 'linked' && hit.via.length > 0
363
+ ? `, via ${hit.via.join(', ')}`
364
+ : '';
365
+ lines.push(`- ${hit.path} (${hit.source}${suffix}): ${compactText(hit.snippet, HOOK_SNIPPET_CHARS)}`);
366
+ }
367
+ } else if (pack.query) {
368
+ lines.push('', 'Relevant wiki pages:', '- No directly relevant durable wiki page found; answer normally and inspect files/wiki only if needed.');
369
+ }
370
+
371
+ const logLines = logFocusLines(pack.logExcerpt, options.logLineLimit ?? 2);
372
+ if (logLines.length > 0) {
373
+ lines.push('', 'Recent log:');
374
+ lines.push(...logLines.map((line) => `- ${line.replace(/^-\s+/, '')}`));
375
+ }
376
+
377
+ return lines.join('\n').trim();
378
+ }