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 +7 -6
- package/docs/concepts.md +4 -3
- package/docs/integrations/claude-code.md +2 -2
- package/docs/integrations/codex.md +3 -3
- package/docs/manual.md +23 -7
- package/docs/operations.md +23 -4
- package/package.json +1 -1
- package/src/cli.js +4 -2
- package/src/compact-capture.js +107 -29
- package/src/consolidate.js +62 -29
- package/src/hook.js +25 -9
- package/src/maintenance.js +97 -2
- package/src/state.js +16 -0
- package/src/templates.js +13 -4
- package/src/wiki-lint.js +47 -9
- package/src/wiki-search.js +84 -19
- package/src/wiki-visibility.js +76 -0
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
45
|
-
- `
|
|
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
|
|
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=
|
|
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
|
|
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=
|
|
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,
|
|
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
|
|
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
|
|
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 보존은
|
|
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
|
|
package/docs/operations.md
CHANGED
|
@@ -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
|
|
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
|
|
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
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
|
|
package/src/compact-capture.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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
|
+
}
|