llm-wiki-kit 0.2.8 → 0.2.10

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,11 +86,12 @@ Use Claude Code or Codex normally.
86
86
 
87
87
  The installed hooks:
88
88
 
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.
89
+ - inject functional compact context at session start, instructions loaded, and prompt submit. The hook still uses `wiki/memory.md`, `wiki/index.md`, relevant wiki search results, maintenance signals, update status, and any compact recovery packet; 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
93
93
  - before compaction, classify the current turn and save a redacted checkpoint for meaningful or durable work; durable candidates also get a maintenance queue item
94
+ - after compaction, store the redacted compact summary only; if pre-compact preservation failed, prepare a recovery packet for the next legal model-visible context hook
94
95
  - allow tool calls to proceed without secret/PII-based hook blocking
95
96
  - update `llm-wiki/outputs/questions/YYYY-MM-DD-live-qa.md` only for meaningful work turns
96
97
  - avoid automatic `wiki/queries/` and `wiki/decisions/` promotion in the default answer-first mode
@@ -101,7 +102,7 @@ The installed hooks:
101
102
 
102
103
  If you need to think about saving every answer manually, the setup has failed.
103
104
  If wiki maintenance delays the actual answer, the setup is being used wrong. The default capture mode is `LLM_WIKI_KIT_CAPTURE_MODE=answer-first`; the old eager query/decision capture path remains only as deprecated compatibility mode via `LLM_WIKI_KIT_CAPTURE_MODE=legacy-eager`.
104
- Pre-compact preservation uses `LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT=limited|soft|off` with default `limited`. It reads only a bounded transcript tail controlled by `LLM_WIKI_KIT_PRECOMPACT_TRANSCRIPT_TAIL_BYTES`; the raw transcript path and authentication values are redacted before any checkpoint is written.
105
+ Pre-compact preservation always lets compaction proceed. `LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT=off` suppresses failure warnings; `limited` and `soft` both emit a non-blocking warning if checkpoint storage fails. The hook reads only a bounded transcript tail controlled by `LLM_WIKI_KIT_PRECOMPACT_TRANSCRIPT_TAIL_BYTES`; the raw transcript path and authentication values are redacted before any checkpoint or recovery packet is written.
105
106
 
106
107
  ## Operational Commands
107
108
 
@@ -125,13 +126,13 @@ Installed npm runtimes also perform a cached update notice check from hooks whil
125
126
 
126
127
  `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.
127
128
 
128
- `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.
129
+ `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, expansion behavior, and context budget metadata. Daily use should rely on hook injection. By default, episodic `wiki/queries/`, `wiki/context/`, and `session-log` 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 records. Archived or superseded pages are hidden unless `--include-archived` is requested, while stale pages remain searchable with lower score.
129
130
 
130
- `llm-wiki lint` checks wiki health and detects outdated managed rules from older kit versions. Agents may use it before/after meaningful wiki maintenance.
131
+ `llm-wiki lint` checks wiki health and detects outdated managed rules from older kit versions. It also warns when `memory.md` is near budget, wiki page count nears the search cap, hidden episodic/context pages accumulate, or stale/archived pages lack supersession/link discoverability. Agents may use it before/after meaningful wiki maintenance.
131
132
 
132
- `llm-wiki consolidate` refreshes only generated marker blocks in `wiki/memory.md` and `wiki/index.md`. It is an agent maintenance helper, not a command users should run after every turn.
133
+ `llm-wiki consolidate` refreshes only generated marker blocks in `wiki/memory.md` and `wiki/index.md`. Generated maps keep durable non-archived pages, hide default episodic records, skip stale/archived/superseded pages, and report those counts in dry-run output. It is an agent maintenance helper, not a command users should run after every turn.
133
134
 
134
- `llm-wiki maintenance` prints the pending queue from `llm-wiki/outputs/maintenance/queue.md`. Hooks create only selective candidates; the active agent should merge reusable items into existing durable wiki pages and mark queue items `done` or `skipped` without delaying unrelated user answers.
135
+ `llm-wiki maintenance` prints the pending queue and review due status from `llm-wiki/outputs/maintenance/queue.md`. Hooks create only selective candidates; the active agent should merge reusable items into existing durable wiki pages and mark queue items `done` or `skipped` without delaying unrelated user answers. Periodic maintenance is a soft agent-side reminder, not a user command loop.
135
136
 
136
137
  `llm-wiki projects --workspace /apps` lists project roots that already have `llm-wiki-kit` state or an older `llm-wiki/wiki/index.md`, and shows the update commands to run. `llm-wiki update --workspace /apps` updates the global runtime once, then reapplies managed templates across every known or discovered project root under `/apps`.
137
138
 
package/docs/concepts.md CHANGED
@@ -39,7 +39,8 @@ The maintenance loop is intentionally layered:
39
39
 
40
40
  - `memory.md`: short hot index for current durable facts.
41
41
  - `index.md`: broad navigation map.
42
- - MiniSearch + wikilinks: retrieval over durable `wiki/**/*.md`, with episodic `wiki/queries/` hidden by default unless `--include-episodic` is requested.
42
+ - MiniSearch + wikilinks: retrieval over durable `wiki/**/*.md`, with episodic `wiki/queries/`, `wiki/context/`, and `session-log` pages hidden by default unless promoted or `--include-episodic` is requested; archived/superseded pages stay preserved but hidden unless `--include-archived` is requested.
43
43
  - `outputs/maintenance/queue.md`: selective reminders for explicit durable requests that need review, plus stale turn recovery.
44
- - `lint`: finds broken links, stale pages, duplicates, metadata gaps, secret-like content, and outdated managed rules.
45
- - `consolidate`: agent helper that refreshes generated blocks in `memory.md` and `index.md` while preserving handwritten notes and keeping default query/context/session pages out of the durable generated maps.
44
+ - `lint`: finds broken links, stale pages, duplicates, metadata gaps, secret-like content, outdated managed rules, memory/page-count budget pressure, hidden episodic growth, and stale/archived discoverability gaps.
45
+ - `maintenance`: reports `reviewDue` only when periodic thresholds are met; hook reminders are soft and limited to session start/instructions loaded or maintenance-related prompts.
46
+ - `consolidate`: agent helper that refreshes generated blocks in `memory.md` and `index.md` while preserving handwritten notes, keeping default query/context/session pages out of the durable generated maps, and skipping stale/archived/superseded pages.
@@ -44,12 +44,12 @@ The hook records redacted turn summaries but does not deny tool calls only becau
44
44
 
45
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
- `PostToolUse` and `PostToolBatch` record redacted tool summaries in the same turn buffer. `PreCompact` classifies the current turn before compaction: simple turns record only a context note, meaningful work writes a live Q&A checkpoint, and durable candidates write both a checkpoint and a maintenance queue item. The checkpoint can include only a bounded redacted transcript tail, never the full raw transcript or raw `transcript_path`. `PostCompact` stores the redacted compact summary as a context 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.
47
+ `PostToolUse` and `PostToolBatch` record redacted tool summaries in the same turn buffer. `PreCompact` classifies the current turn before compaction: simple turns record only a context note, meaningful work writes a live Q&A checkpoint, and durable candidates write both a checkpoint and a maintenance queue item. The checkpoint can include only a bounded redacted transcript tail, never the full raw transcript or raw `transcript_path`. Compaction is not blocked; if checkpoint storage fails, the hook records a compact recovery packet for the next legal context-injection event. `PostCompact` stores the redacted compact summary as a context note and prepares any pending recovery packet without returning model-visible context directly. 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
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
- Set `LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT=limited|soft|off` to tune pre-compact failure handling; default `limited` blocks only when checkpoint/queue preservation fails on providers with block support. `LLM_WIKI_KIT_PRECOMPACT_TRANSCRIPT_TAIL_BYTES` controls the bounded tail size.
52
+ Set `LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT=off` to suppress pre-compact failure warnings; `limited` and `soft` both keep compaction moving and emit a non-blocking warning when checkpoint/queue preservation fails. `LLM_WIKI_KIT_PRECOMPACT_TRANSCRIPT_TAIL_BYTES` controls the bounded tail size.
53
53
 
54
54
  After installation or update, run:
55
55
 
@@ -33,8 +33,8 @@ Expected behavior:
33
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
- - `PreCompact` classifies the current turn before compaction. Simple turns record only a context note; meaningful work writes a live Q&A checkpoint; durable candidates write both a checkpoint and a maintenance queue item. The checkpoint can include only a bounded redacted transcript tail, never the full raw transcript or raw `transcript_path`.
37
- - `PostCompact` stores the redacted compact summary as a context note and returns fresh wiki context.
36
+ - `PreCompact` classifies the current turn before compaction. Simple turns record only a context note; meaningful work writes a live Q&A checkpoint; durable candidates write both a checkpoint and a maintenance queue item. The checkpoint can include only a bounded redacted transcript tail, never the full raw transcript or raw `transcript_path`. Compaction is not blocked; if checkpoint storage fails, the hook records a compact recovery packet for the next legal context-injection event.
37
+ - `PostCompact` stores the redacted compact summary as a context note and prepares any pending compact recovery packet. It does not return `hookSpecificOutput.additionalContext`, because Codex `PostCompact` only supports common output fields.
38
38
  - In the default `answer-first` mode, `SubagentStop` does not create live Q&A, query, decision, or maintenance files. `Stop` appends live Q&A only for meaningful work turns and does not auto-create `wiki/queries/` or `wiki/decisions/`.
39
39
  - 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.
40
40
  - `Stop` clears the per-session turn buffer after recording. `SubagentStop` leaves the parent turn buffer available for the final stop event.
@@ -44,7 +44,7 @@ Hook payloads are stored as small redacted event envelopes rather than full tran
44
44
  Set `LLM_WIKI_KIT_AUTO_PROJECT_UPDATE=0` only while diagnosing automatic managed-template refresh behavior.
45
45
  Set `LLM_WIKI_KIT_UPDATE_NOTICE=0` only while suppressing the cached passive runtime update status.
46
46
  Set `LLM_WIKI_KIT_CAPTURE_MODE=legacy-eager` only as deprecated compatibility mode for the old eager query/decision capture behavior.
47
- Set `LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT=limited|soft|off` to tune pre-compact failure handling; default `limited` blocks only on supported providers when checkpoint/queue preservation fails. `LLM_WIKI_KIT_PRECOMPACT_TRANSCRIPT_TAIL_BYTES` controls the bounded tail size.
47
+ Set `LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT=off` to suppress pre-compact failure warnings; `limited` and `soft` both keep compaction moving and emit a non-blocking warning when checkpoint/queue preservation fails. `LLM_WIKI_KIT_PRECOMPACT_TRANSCRIPT_TAIL_BYTES` controls the bounded tail size.
48
48
 
49
49
  Run these after install:
50
50
 
package/docs/manual.md CHANGED
@@ -62,8 +62,8 @@ llm-wiki/
62
62
 
63
63
  설치된 hook은 다음 일을 자동으로 수행한다.
64
64
 
65
- - session start, prompt submit, post compact 시점에 functional compact context를 주입한다. `wiki/memory.md`, `wiki/index.md`, 관련 wiki 검색 결과, maintenance signal, update status 계속 사용하되 사용자 화면에 보일 수 있는 hook context는 필요한 정보 중심으로 정제한다.
66
- - pre compact 시점에는 현재 turn을 분류하고, simple turn은 context note만 남기며, meaningful/durable turn은 redacted live Q&A checkpoint와 필요한 maintenance queue 후보를 남긴다.
65
+ - session start, instructions loaded, prompt submit 시점에 functional compact context를 주입한다. `wiki/memory.md`, `wiki/index.md`, 관련 wiki 검색 결과, maintenance signal, update status, compact recovery packet은 계속 사용하되 사용자 화면에 보일 수 있는 hook context는 필요한 정보 중심으로 정제한다.
66
+ - pre compact 시점에는 현재 turn을 분류하고, simple turn은 context note만 남기며, meaningful/durable turn은 redacted live Q&A checkpoint와 필요한 maintenance queue 후보를 남긴다. 저장 실패 시에도 compact는 진행시키고, 중요한 내용만 recovery packet으로 준비한다.
67
67
  - prompt/tool/result summary를 redaction한 뒤 turn buffer에 기록한다.
68
68
  - 의미 있는 작업 turn만 `outputs/questions/YYYY-MM-DD-live-qa.md`에 live Q&A로 남긴다.
69
69
  - 기본 answer-first mode에서는 `wiki/queries/`와 `wiki/decisions/`를 매 turn 자동 생성하지 않는다.
@@ -271,6 +271,7 @@ llm-wiki context "auth architecture" --workspace /path/to/project --json
271
271
  llm-wiki context "auth architecture" --workspace /path/to/project --limit 8
272
272
  llm-wiki context "auth architecture" --workspace /path/to/project --no-expand
273
273
  llm-wiki context "auth architecture" --workspace /path/to/project --include-episodic
274
+ llm-wiki context "auth architecture" --workspace /path/to/project --include-archived
274
275
  ```
275
276
 
276
277
  읽는 자료:
@@ -281,7 +282,7 @@ llm-wiki context "auth architecture" --workspace /path/to/project --include-epis
281
282
  - MiniSearch 또는 substring fallback 결과
282
283
  - strong match의 one-hop wikilink neighbors
283
284
 
284
- 기본 검색은 episodic `wiki/queries/`를 제외한다. 오래된 automatic query record까지 보고 싶을 때만 `--include-episodic`을 쓴다.
285
+ 기본 검색은 durable semantic/procedural page를 우선하고, episodic `wiki/queries/`, `wiki/context/`, `session-log` 계열은 숨긴다. 해당 page가 `memory_type: semantic|procedural`이고 `importance >= 4`이면 promoted durable page로 취급한다. `status: archived` 또는 `superseded_by`가 있는 page도 기본 검색에서 제외하며, 필요한 조사 때만 `--include-archived`로 복구한다. `status: stale` page는 보존하고 검색할 수 있지만 score를 낮춘다. JSON 출력에는 memory/index/hit/snippet budget metadata가 포함된다.
285
286
 
286
287
  ### `llm-wiki lint`
287
288
 
@@ -302,6 +303,10 @@ llm-wiki lint --workspace /path/to/project
302
303
  - secret-like content
303
304
  - duplicate aliases/titles
304
305
  - stale pages and orphan candidates
306
+ - `memory.md` near-budget/oversized 상태
307
+ - wiki page count가 search cap에 근접했는지
308
+ - default-hidden episodic/context/session page 성장
309
+ - stale/archived page의 supersession/link discoverability
305
310
  - outdated managed rules/templates
306
311
  - stale or oversized maintenance queue
307
312
 
@@ -321,7 +326,7 @@ llm-wiki consolidate --workspace /path/to/project --dry-run
321
326
  - `wiki/memory.md`의 generated memory map
322
327
  - `wiki/index.md`의 generated page map
323
328
 
324
- handwritten content는 보존한다. malformed marker block은 덮어쓰지 않고 건너뛴다. 기본 `query`, `context`, `session-log` page는 explicit durable metadata가 없으면 generated map에서 제외한다.
329
+ handwritten content는 보존한다. malformed marker block은 덮어쓰지 않고 건너뛴다. generated map에는 durable non-archived page만 넣는다. `stale`, `archived`, `superseded_by` page는 보존하지만 generated map에서는 제외한다. 기본 `query`, `context`, `session-log` page는 explicit durable metadata가 없으면 generated map에서 제외한다. `--dry-run` 결과는 indexed durable pages, hidden episodic pages, archived/stale/superseded skipped counts를 보고한다.
325
330
 
326
331
  ### `llm-wiki maintenance`
327
332
 
@@ -332,7 +337,18 @@ llm-wiki maintenance --workspace /path/to/project
332
337
  llm-wiki maintenance --workspace /path/to/project --json
333
338
  ```
334
339
 
335
- 이 명령은 page merge를 자동 수행하지 않는다. active agent가 pending item을 읽고, 가장 가까운 durable wiki 문서에 병합한 뒤 queue item을 `done` 또는 `skipped`로 표시한다.
340
+ 이 명령은 page merge를 자동 수행하지 않는다. 정기 maintenance는 agent-side task이며 사용자가 매 turn 실행할 필요가 없다. active agent가 pending item을 읽고, 가장 가까운 durable wiki 문서에 병합한 뒤 queue item을 `done` 또는 `skipped`로 표시한다.
341
+
342
+ JSON 출력에는 `reviewDue`, `reviewReasons`, `pendingCount`, `stalePendingCount`, `health`, `recommendedCommands`가 포함된다. Review due 조건은 마지막 review 후 14일 경과, pending 5개 이상, stale/result-missing pending item, lint warning/error, `memory.md` near-budget 이상, wiki page count가 search cap의 80% 이상인 경우다. Hook은 due 상태를 `SessionStart`/`InstructionsLoaded`에서만 짧게 보여주고, `UserPromptSubmit`에서는 사용자가 wiki/maintenance/정리 관련 질문을 했을 때만 보여준다. 현재 답변을 중단하거나 정리를 강제하지 않는다.
343
+
344
+ Agent checklist:
345
+
346
+ ```bash
347
+ llm-wiki lint --workspace /path/to/project
348
+ llm-wiki maintenance --workspace /path/to/project
349
+ llm-wiki consolidate --workspace /path/to/project --dry-run
350
+ llm-wiki consolidate --workspace /path/to/project
351
+ ```
336
352
 
337
353
  ### `llm-wiki uninstall`
338
354
 
@@ -387,9 +403,9 @@ Claude Code handled events:
387
403
 
388
404
  Hook payload는 full transcript가 아니라 작은 redacted event envelope다. context output도 field별 redaction을 거친다. `PreCompact`는 checkpoint 생성을 위해 작은 bounded transcript tail만 읽을 수 있고, 저장 전 인증값과 raw `transcript_path`를 redaction한다.
389
405
 
390
- 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 정책과 별도로 유지한다.
406
+ Context를 반환하는 Codex/Claude hook event는 기능을 제거하지 않는다. memory hot index, navigation index, relevant wiki hits, link expansion, maintenance signal, passive runtime update status, compact recovery packet을 계속 사용할 수 있고, 사용자 화면에 보일 수 있는 `additionalContext`만 functional compact context로 정제한다. `PostCompact`는 compact summary 저장과 recovery packet 준비만 수행하고 model-visible context를 직접 반환하지 않는다. `llm-wiki context` CLI의 full debug 출력은 이 hook formatting 정책과 별도로 유지한다.
391
407
 
392
- Pre-compact 보존은 기본 `LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT=limited`로 동작한다. `limited`는 checkpoint/queue 저장 실패 시 block을 지원하는 provider에서만 compact block을 시도하고, 그 외에는 failure context를 남긴다. `soft`는 block하지 않고, `off`는 실패 output을 억제한다. `LLM_WIKI_KIT_PRECOMPACT_TRANSCRIPT_TAIL_BYTES`로 transcript tail byte 한도를 조정한다.
408
+ Pre-compact 보존은 compact를 block하지 않는다. `LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT=off`는 실패 warning을 억제하고, `limited`/`soft`는 checkpoint/queue 저장 실패 시 non-blocking warning만 남긴다. `LLM_WIKI_KIT_PRECOMPACT_TRANSCRIPT_TAIL_BYTES`로 transcript tail byte 한도를 조정한다.
393
409
 
394
410
  ## Security Defaults
395
411
 
@@ -143,9 +143,9 @@ After a plain `npm install -g llm-wiki-kit@latest`, existing hooks keep working
143
143
 
144
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
- 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`. `PreCompact` performs the same answer-first classification before context compaction: simple turns get only a context note, archive-worthy turns get a live Q&A checkpoint, and durable candidates get a checkpoint plus queue item. `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.
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`. `PreCompact` performs the same answer-first classification before context compaction: simple turns get only a context note, archive-worthy turns get a live Q&A checkpoint, and durable candidates get a checkpoint plus queue item. If checkpoint storage fails, compaction still proceeds and the hook prepares an important-only compact recovery packet for the next legal context-injection event. `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
- Pre-compact preservation defaults to `LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT=limited`. In that mode, checkpoint/queue write failures can block compact only on providers that support hook blocking; otherwise the hook returns best-effort failure context. `soft` never blocks, and `off` suppresses failure output. `LLM_WIKI_KIT_PRECOMPACT_TRANSCRIPT_TAIL_BYTES` controls the small bounded transcript tail used for checkpoint context. Authentication values and the raw transcript path are redacted before storage.
148
+ Pre-compact preservation defaults to `LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT=limited`, but compaction is never blocked by llm-wiki-kit. `limited` and `soft` emit non-blocking failure warnings, and `off` suppresses failure output. `LLM_WIKI_KIT_PRECOMPACT_TRANSCRIPT_TAIL_BYTES` controls the small bounded transcript tail used for checkpoint context. Authentication values and the raw transcript path are redacted before storage.
149
149
 
150
150
  `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.
151
151
 
@@ -157,7 +157,7 @@ Pre-compact preservation defaults to `LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT=limite
157
157
  - one-hop wikilink neighbors for the strongest matches
158
158
  - redacted output fields for query text, memory/index/log excerpts, hit paths, titles, snippets, matched terms, and link expansion metadata
159
159
 
160
- Default context search excludes episodic `wiki/queries/` pages unless they were explicitly promoted with `memory_type: semantic` or `procedural` and `importance >= 4`. Use `--include-episodic` only when debugging historical automatic query pages:
160
+ Default context search prioritizes durable semantic/procedural pages. It hides episodic `wiki/queries/`, `wiki/context/`, and `session-log` pages unless they were explicitly promoted with `memory_type: semantic` or `procedural` and `importance >= 4`. It also hides `status: archived` and `superseded_by` pages unless `--include-archived` is requested. `status: stale` pages remain searchable but receive a lower score. JSON output includes memory/index/hit/snippet budget metadata so maintainers can see how much context each layer consumed. Use `--include-episodic` only when debugging historical automatic query pages:
161
161
 
162
162
  Use it only when you want to inspect what the next agent turn should see:
163
163
 
@@ -166,6 +166,7 @@ llm-wiki context "auth architecture" --workspace /path/to/project
166
166
  llm-wiki context "auth architecture" --workspace /path/to/project --json
167
167
  llm-wiki context "auth architecture" --workspace /path/to/project --limit 8 --no-expand
168
168
  llm-wiki context "auth architecture" --workspace /path/to/project --include-episodic
169
+ llm-wiki context "auth architecture" --workspace /path/to/project --include-archived
169
170
  ```
170
171
 
171
172
  `llm-wiki lint` checks Markdown wiki health without modifying files:
@@ -179,6 +180,10 @@ llm-wiki context "auth architecture" --workspace /path/to/project --include-epis
179
180
  - secret-like content patterns such as tokens, password assignments, bearer credentials, and private keys
180
181
  - duplicate aliases or titles
181
182
  - stale pages and orphan candidates
183
+ - `memory.md` near-budget or oversized state
184
+ - wiki page count near the default search cap
185
+ - default-hidden episodic/context/session page growth
186
+ - stale/archived pages without supersession metadata or links
182
187
  - outdated managed rules/templates from earlier `llm-wiki-kit` versions
183
188
  - stale or oversized maintenance queues
184
189
 
@@ -188,7 +193,10 @@ Broken links, invalid source IDs, and secret-like content are errors and return
188
193
 
189
194
  - refreshes the generated block inside `wiki/memory.md`
190
195
  - refreshes the generated block inside `wiki/index.md`
196
+ - keeps only durable non-archived pages in generated maps
197
+ - skips `stale`, `archived`, and `superseded_by` pages from generated maps while preserving them on disk
191
198
  - excludes default `query`, `context`, and `session-log` pages from generated maps unless they are explicitly durable (`memory_type: semantic` or `procedural`, `importance >= 4`)
199
+ - reports indexed durable pages, hidden episodic pages, and archived/stale/superseded skipped counts, including in `--dry-run`
192
200
  - skips malformed generated marker blocks instead of overwriting them
193
201
  - preserves handwritten content outside marker blocks
194
202
  - appends a log entry when files change
@@ -196,7 +204,18 @@ Broken links, invalid source IDs, and secret-like content are errors and return
196
204
 
197
205
  Agents may run `consolidate` after meaningful wiki growth. Users should not need to run it after every turn.
198
206
 
199
- `llm-wiki maintenance --workspace <project>` prints queue counts and the first pending items. It does not merge wiki pages by itself; the active agent should review pending items, update the closest existing durable wiki document, then mark the queue item `done` or `skipped`.
207
+ `llm-wiki maintenance --workspace <project>` prints queue counts, review due status, and the first pending items. It does not merge wiki pages by itself; the active agent should review pending items, update the closest existing durable wiki document, then mark the queue item `done` or `skipped`. Periodic maintenance is an agent-side task, not something users need to run after every turn.
208
+
209
+ `llm-wiki maintenance --workspace <project> --json` includes `reviewDue`, `reviewReasons`, `pendingCount`, `stalePendingCount`, `health`, and `recommendedCommands`. Review is due when the last review is older than 14 days, pending queue size reaches 5, stale or result-missing pending items exist, lint has warnings/errors, `memory.md` is near budget, or wiki page count reaches 80% of the search cap. Hook reminders are soft: `SessionStart`/`InstructionsLoaded` may show a short due note, while `UserPromptSubmit` shows it only for wiki/maintenance/cleanup-related prompts. The reminder never blocks the current answer.
210
+
211
+ Recommended agent checklist:
212
+
213
+ ```bash
214
+ llm-wiki lint --workspace /path/to/project
215
+ llm-wiki maintenance --workspace /path/to/project
216
+ llm-wiki consolidate --workspace /path/to/project --dry-run
217
+ llm-wiki consolidate --workspace /path/to/project
218
+ ```
200
219
 
201
220
  When a new runtime sees an older project, `SessionStart`/`InstructionsLoaded` automatically reapplies safe managed template updates. Files that are clearly generated by older kit versions are refreshed. Files that look user-edited are preserved and surfaced to the active agent as cleanup context instead of being overwritten. Set `LLM_WIKI_KIT_AUTO_PROJECT_UPDATE=0` only while diagnosing automatic template refresh behavior.
202
221
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-wiki-kit",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "Hook-first living LLM Wiki runtime for Codex and Claude Code.",
5
5
  "type": "module",
6
6
  "files": [
package/src/cli.js CHANGED
@@ -70,6 +70,8 @@ function parseOptions(args) {
70
70
  options.expand = false;
71
71
  } else if (arg === '--include-episodic') {
72
72
  options.includeEpisodic = true;
73
+ } else if (arg === '--include-archived') {
74
+ options.includeArchived = true;
73
75
  } else if (arg === '--replace-hooks') {
74
76
  options.replaceHooks = true;
75
77
  } else if (arg === '--all') {
@@ -116,7 +118,7 @@ Usage:
116
118
  llm-wiki hook claude <EventName>
117
119
  llm-wiki bootstrap --workspace <project>
118
120
  llm-wiki migrate --workspace <project>
119
- llm-wiki context "<query>" --workspace <project> [--limit 5] [--no-expand] [--include-episodic]
121
+ llm-wiki context "<query>" --workspace <project> [--limit 5] [--no-expand] [--include-episodic] [--include-archived]
120
122
  llm-wiki lint --workspace <project>
121
123
  llm-wiki consolidate --workspace <project> [--dry-run]
122
124
  llm-wiki maintenance --workspace <project> [--json]
@@ -234,7 +236,7 @@ Usage:
234
236
 
235
237
  if (command === 'maintenance') {
236
238
  const projectRoot = resolve(options.workspace || process.cwd());
237
- printJsonOrText(await maintenanceSummary(projectRoot, options), options, formatMaintenanceResult);
239
+ printJsonOrText(await maintenanceSummary(projectRoot, { ...options, includeLint: true }), options, formatMaintenanceResult);
238
240
  return;
239
241
  }
240
242
 
@@ -4,26 +4,12 @@ import { classifyTurn } from './capture-policy.js';
4
4
  import { recordMaintenanceForEntry } from './maintenance.js';
5
5
  import { appendContextNote, appendLiveQa, appendWikiLog } from './project.js';
6
6
  import { redactText, summarizeForStorage } from './redaction.js';
7
- import { buildEntryFromState } from './state.js';
7
+ import { buildEntryFromState, clearCompactRecovery, readCompactRecovery, writeCompactRecovery } from './state.js';
8
8
 
9
9
  const DEFAULT_PRECOMPACT_TAIL_BYTES = 32 * 1024;
10
10
  const MAX_PRECOMPACT_TAIL_BYTES = 256 * 1024;
11
11
  const ENFORCEMENT_MODES = new Set(['limited', 'soft', 'off']);
12
12
 
13
- function contextOutput(eventName, context) {
14
- if (!context) return {};
15
- return {
16
- hookSpecificOutput: {
17
- hookEventName: eventName,
18
- additionalContext: context,
19
- },
20
- };
21
- }
22
-
23
- function providerSupportsBlock(provider) {
24
- return String(provider || '').toLowerCase() === 'claude';
25
- }
26
-
27
13
  export function preCompactEnforcementMode(env = process.env) {
28
14
  const value = String(env.LLM_WIKI_KIT_PRECOMPACT_ENFORCEMENT || 'limited').toLowerCase();
29
15
  return ENFORCEMENT_MODES.has(value) ? value : 'limited';
@@ -118,16 +104,77 @@ function entryWithTranscriptTail(entry, tail) {
118
104
  return next;
119
105
  }
120
106
 
121
- function failureOutput(provider, eventName, message, mode) {
107
+ function captured(value) {
108
+ const text = String(value || '').trim();
109
+ return text && text !== '(not captured)' ? text : '';
110
+ }
111
+
112
+ function sanitizeFailureText(projectRoot, value) {
113
+ let text = String(value || '');
114
+ if (projectRoot) text = text.split(projectRoot).join('[REDACTED:project-root]');
115
+ return summarizeForStorage(text, 1200);
116
+ }
117
+
118
+ function sanitizeFailures(projectRoot, failures) {
119
+ return failures.map((failure) => sanitizeFailureText(projectRoot, failure));
120
+ }
121
+
122
+ function formatRecoveryContext(recovery) {
123
+ const entry = recovery?.entry || {};
124
+ const lines = [
125
+ 'LLM Wiki compact recovery:',
126
+ '- PreCompact preservation could not finish before compaction. Use this fallback context only for important lost details.',
127
+ `- classification: ${recovery?.classification || 'unknown'}`,
128
+ ];
129
+ if (recovery?.postCompactSummary) {
130
+ lines.push(`- compact summary: ${summarizeForStorage(recovery.postCompactSummary, 600)}`);
131
+ }
132
+ if (recovery?.failures) {
133
+ lines.push(`- preservation failure: ${summarizeForStorage(recovery.failures, 600)}`);
134
+ }
135
+ const fields = [
136
+ ['question', 'question', 900],
137
+ ['work', 'work', 1200],
138
+ ['result', 'result', 1400],
139
+ ['changedFiles', 'changed files', 700],
140
+ ['verification', 'verification', 700],
141
+ ['followUp', 'follow-up', 700],
142
+ ];
143
+ for (const [key, label, limit] of fields) {
144
+ const value = captured(entry[key]);
145
+ if (value) lines.push(`\n${label}:\n${summarizeForStorage(value, limit)}`);
146
+ }
147
+ return summarizeForStorage(lines.join('\n'), 5000);
148
+ }
149
+
150
+ async function recordCompactRecoveryFailure(projectRoot, payload, entry, classification, failures) {
151
+ const recovery = {
152
+ created_at: new Date().toISOString(),
153
+ updated_at: new Date().toISOString(),
154
+ classification: classification.kind,
155
+ failures: summarizeForStorage(failures.join('; '), 1200),
156
+ entry: {
157
+ topic: summarizeForStorage(entry.topic, 300),
158
+ question: summarizeForStorage(entry.question, 1000),
159
+ work: summarizeForStorage(entry.work, 1600),
160
+ result: summarizeForStorage(entry.result, 1800),
161
+ changedFiles: summarizeForStorage(entry.changedFiles, 900),
162
+ verification: summarizeForStorage(entry.verification, 900),
163
+ followUp: summarizeForStorage(entry.followUp, 900),
164
+ firstTimestamp: entry.firstTimestamp,
165
+ session: entry.session,
166
+ },
167
+ };
168
+ recovery.context = formatRecoveryContext(recovery);
169
+ await writeCompactRecovery(projectRoot, payload, recovery);
170
+ }
171
+
172
+ function failureOutput(message, mode) {
122
173
  if (mode === 'off') return {};
123
174
  const reason = summarizeForStorage(message, 1200);
124
- if (mode === 'limited' && providerSupportsBlock(provider)) {
125
- return {
126
- decision: 'block',
127
- reason,
128
- };
129
- }
130
- return contextOutput(eventName, `LLM Wiki PreCompact preservation warning:\n${reason}`);
175
+ return {
176
+ systemMessage: `LLM Wiki PreCompact preservation warning: ${reason}`,
177
+ };
131
178
  }
132
179
 
133
180
  export async function handlePreCompactCapture(projectRoot, provider, eventName, payload) {
@@ -193,12 +240,16 @@ export async function handlePreCompactCapture(projectRoot, provider, eventName,
193
240
  }
194
241
 
195
242
  if (failures.length > 0) {
196
- return failureOutput(
197
- provider,
198
- eventName,
199
- `LLM Wiki PreCompact preservation did not complete. ${failures.join('; ')}`,
200
- mode
201
- );
243
+ let safeFailures = sanitizeFailures(projectRoot, failures);
244
+ if (classification.archive) {
245
+ try {
246
+ await recordCompactRecoveryFailure(projectRoot, payload, entry, classification, safeFailures);
247
+ } catch (error) {
248
+ failures.push(`compact recovery marker failed: ${error?.message || error}`);
249
+ safeFailures = sanitizeFailures(projectRoot, failures);
250
+ }
251
+ }
252
+ return failureOutput(`LLM Wiki PreCompact preservation did not complete. ${safeFailures.join('; ')}`, mode);
202
253
  }
203
254
 
204
255
  return {};
@@ -212,3 +263,30 @@ export async function recordPostCompactSummary(projectRoot, eventName, payload)
212
263
  summary ? `Compact summary:\n${redactText(summary, 4000)}` : 'Compact summary was not provided.'
213
264
  );
214
265
  }
266
+
267
+ export async function finalizeCompactRecovery(projectRoot, payload) {
268
+ const recovery = await readCompactRecovery(projectRoot, payload);
269
+ if (!recovery) return null;
270
+ const summary = compactSummaryText(payload);
271
+ const next = {
272
+ ...recovery,
273
+ updated_at: new Date().toISOString(),
274
+ postCompactSummary: summary || recovery.postCompactSummary || '',
275
+ ready: true,
276
+ };
277
+ next.context = formatRecoveryContext(next);
278
+ await writeCompactRecovery(projectRoot, payload, next);
279
+ await appendContextNote(
280
+ projectRoot,
281
+ 'PostCompact',
282
+ 'Prepared compact recovery packet for the next legal model-visible hook context.'
283
+ ).catch(() => {});
284
+ return next;
285
+ }
286
+
287
+ export async function consumeCompactRecoveryContext(projectRoot, payload) {
288
+ const recovery = await readCompactRecovery(projectRoot, payload);
289
+ if (!recovery) return '';
290
+ await clearCompactRecovery(projectRoot, payload);
291
+ return recovery.context || formatRecoveryContext(recovery);
292
+ }