Skip to content

Commit 0e08ae2

Browse files
duyetduyetbot
andauthored
feat(kb): add kb plugin with dream consolidation skill (#76)
* feat(kb): add kb plugin with dream consolidation skill - dream skill: consolidate a markdown KB — merge near-duplicates, flag contradictions, prune stale notes, ingest inbox, refresh from sources, split, rebuild the index. Diff-for-approval; --auto (lock-guarded, skips conflicts); forget (delete by query). KB-agnostic (path arg / $KB_DIR). - Registered in marketplace.json, .claude-plugin/marketplace.json, .agents/plugins/marketplace.json; Claude + Codex manifests in sync. Co-Authored-By: duyetbot <duyetbot@users.noreply.github.com> * feat(kb): add /dream command wrapping the dream skill Thin slash-command entry point: parses $ARGUMENTS (path / --auto / forget), resolves the KB via the argument or $KB_DIR, and delegates the full consolidation pass to the dream skill. Declares commands/ + Command capability in the Codex manifest. Co-Authored-By: duyetbot <duyetbot@users.noreply.github.com> * fix(kb): add languages to fenced code blocks (MD040) Super-linter markdownlint MD040 requires a language on fenced code blocks. The diff-report and forget-diff templates were bare; mark them as text. Co-Authored-By: duyetbot <duyetbot@users.noreply.github.com> --------- Co-authored-by: duyetbot <duyetbot@users.noreply.github.com>
1 parent c28a788 commit 0e08ae2

8 files changed

Lines changed: 317 additions & 0 deletions

File tree

.agents/plugins/marketplace.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,18 @@
255255
"authentication": "ON_INSTALL"
256256
},
257257
"category": "Automation"
258+
},
259+
{
260+
"name": "kb",
261+
"source": {
262+
"source": "local",
263+
"path": "./kb"
264+
},
265+
"policy": {
266+
"installation": "AVAILABLE",
267+
"authentication": "ON_INSTALL"
268+
},
269+
"category": "Productivity"
258270
}
259271
]
260272
}

.claude-plugin/marketplace.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@
103103
"name": "agent-loop",
104104
"source": "./agent-loop",
105105
"description": "Continuous agent loop for overnight/day repo maintenance. Triage, autoreview, browser automation, and parallel agent work. Wake every 5 min, dispatch to threads, land autonomously."
106+
},
107+
{
108+
"name": "kb",
109+
"source": "./kb",
110+
"description": "Knowledge base maintenance skills. Consolidate, dedupe, prune, refresh, and forget notes in a markdown KB."
106111
}
107112
]
108113
}

kb/.claude-plugin/plugin.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "kb",
3+
"version": "1.0.0",
4+
"description": "Knowledge base maintenance skills. Consolidate, dedupe, prune, refresh, and forget notes in a markdown KB.",
5+
"author": {
6+
"name": "duyet",
7+
"url": "https://github.com/duyet"
8+
},
9+
"homepage": "https://github.com/duyet/codex-claude-plugins",
10+
"repository": "https://github.com/duyet/codex-claude-plugins",
11+
"license": "MIT"
12+
}

kb/.codex-plugin/plugin.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "kb",
3+
"version": "1.0.0",
4+
"description": "Knowledge base maintenance skills. Consolidate, dedupe, prune, refresh, and forget notes in a markdown KB.",
5+
"author": {
6+
"name": "duyet"
7+
},
8+
"skills": "./skills/",
9+
"commands": "./commands/",
10+
"interface": {
11+
"displayName": "Knowledge Base",
12+
"shortDescription": "Maintain a markdown knowledge base: consolidate, dedupe, prune, and forget notes.",
13+
"developerName": "duyet",
14+
"category": "productivity",
15+
"capabilities": ["Skill", "Command"],
16+
"links": {
17+
"homepage": "https://github.com/duyet/codex-claude-plugins"
18+
}
19+
}
20+
}

kb/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# kb
2+
3+
Knowledge base maintenance skills for markdown KBs. KB-agnostic: point each skill at any
4+
markdown knowledge base via a path argument or the `$KB_DIR` environment variable.
5+
6+
## Skills
7+
8+
- **dream** — the consolidation pass. Merges near-duplicate notes, flags contradictions,
9+
prunes stale/low-value notes, ingests inbox captures, refreshes notes from their
10+
source URLs, splits multi-fact notes, relinks/retags, and rebuilds the index. Shows a
11+
diff for approval before changing anything. Supports `--auto` (non-interactive, lock
12+
guarded) and `forget` (delete specific notes).
13+
14+
## Install
15+
16+
```bash
17+
/plugin install kb@duyet-claude-plugins
18+
```
19+
20+
## Usage
21+
22+
```bash
23+
dream ./docs/kb # consolidate a KB (interactive, diff-for-approval)
24+
dream $KB_DIR --auto # non-interactive; merges/prunes, skips contradictions
25+
dream forget "old server" # propose deleting notes matching a query
26+
```
27+
28+
The KB is any directory of `*.md` notes with YAML frontmatter (`name`, `type`, `tags`,
29+
`created`, `updated`, optional `pinned`/`confidence`/`sources`), optionally with a
30+
`MEMORY.md` index, a `raw/inbox/` of captures, and `raw/` source docs.

kb/commands/dream.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# /dream
2+
3+
Consolidate a markdown knowledge base: merge near-duplicates, flag contradictions, prune
4+
stale notes, ingest inbox captures, refresh notes from sources, split, and rebuild the
5+
index. Delegate to the `dream` skill for the full pass. Nothing changes until the user
6+
approves the diff (unless `--auto`).
7+
8+
## Arguments
9+
10+
- `path`: KB directory (optional; defaults to `$KB_DIR`; ask if unset)
11+
- `--auto`: non-interactive run (apply merges/prunes, skip contradictions, lock-guarded)
12+
- `forget "<query>"`: delete notes matching a query (diff-for-approval)
13+
14+
Pass the rest of the line as `$ARGUMENTS`. Examples: `/dream ./docs/kb`,
15+
`/dream $KB_DIR --auto`, `/dream forget "old server"`.
16+
17+
## Workflow
18+
19+
1. Parse `$ARGUMENTS`: detect `--auto`, a `forget "<query>"` subcommand, and a path.
20+
Resolve the KB path from the argument or `$KB_DIR`; ask if neither is set.
21+
2. Invoke the `dream` skill and follow its pass exactly. The skill owns the consolidation
22+
logic, the diff format, the apply order, and the safety rules.
23+
3. In interactive mode, print the diff, collect A/B/skip for each conflict, confirm, then
24+
apply in the skill's prescribed order.
25+
4. In `--auto`, honor the lock file, apply merges and prunes silently, skip conflicts, and
26+
leave a reminder if conflicts still need review.
27+
5. For `forget`, list matches and apply only approved deletions (and their index lines).
28+
29+
## Guardrails
30+
31+
- Never assume a fixed KB location; use the argument or `$KB_DIR`.
32+
- Never auto-push or auto-sync; the user confirms before any write outside the KB.
33+
- Never delete or merge `pinned` notes without explicit per-note confirmation.
34+
- Keep this command thin — all consolidation logic lives in the `dream` skill.

kb/skills/dream/SKILL.md

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
---
2+
name: dream
3+
description: Consolidate a markdown knowledge base — merge near-duplicates, flag contradictions, prune stale notes, ingest inbox, refresh from sources, split, and rebuild the index. Use when a KB is noisy or stale, on a schedule, or to forget notes. Diff-for-approval; supports --auto.
4+
---
5+
6+
# dream — KB memory consolidation
7+
8+
## Overview
9+
10+
Dream is the maintenance pass that keeps a markdown knowledge base compact and
11+
retrievable — the agent equivalent of sleep consolidating the day's memories. Run it when
12+
the KB feels noisy (duplicates, contradictions, sprawl, stale facts), on a schedule, or
13+
to forget specific notes. Everything is proposed as a diff first; nothing changes until
14+
you approve (or you run `--auto`).
15+
16+
Dream is KB-agnostic and generic. It never assumes a fixed location.
17+
18+
## Invocation
19+
20+
- `dream [<path>]` — consolidate the KB at `<path>`. If omitted, use `$KB_DIR`; if that
21+
is unset, ask for the path. Examples: `dream ./docs/kb`, `dream $KB_DIR`.
22+
- `dream --auto [<path>]` — non-interactive: apply merges and prunes silently, skip
23+
contradictions (they need human judgment), guarded by a lock file.
24+
- `dream forget "<query>" [<path>]` — find notes matching a query and propose deletion
25+
(same diff-for-approval flow as consolidation).
26+
27+
A note is any `*.md` file with YAML frontmatter. Map missing fields gracefully:
28+
29+
```yaml
30+
---
31+
name: type-short-slug # equals the filename stem
32+
description: one line, keyword-front-loaded
33+
type: tech # user | feedback | project | reference | tech | ...
34+
tags: [topic, topic]
35+
sources: ["https://example.com/llms.txt"]
36+
created: 2026-06-01
37+
updated: 2026-06-13
38+
pinned: false # optional — pinned notes are never pruned or merged
39+
confidence: 0.8 # optional — 0..1; low + generic => prune candidate
40+
---
41+
```
42+
43+
- No `type` => `unknown`. No `created`/`updated` => use file mtime. No `confidence` =>
44+
neutral. No `pinned` => false.
45+
46+
## The pass (run strictly in order)
47+
48+
Work in memory until the apply step; modify nothing early.
49+
50+
1. **Resolve the KB.** Confirm `<path>` holds `memory/` (notes) and ideally `MEMORY.md`
51+
(index), `raw/inbox/` (captures), `raw/` (source docs), and a state file. If the
52+
layout differs, operate on whatever `*.md` files exist and adapt.
53+
2. **Load.** Read the index, every note, `raw/inbox/*`, source docs, and state.
54+
3. **Ingest inbox.** Promote durable, general facts from `raw/inbox/*` into `memory/`
55+
(create or merge notes). Delete inbox files once distilled (they are ephemeral). Keep
56+
`raw/` source docs (immutable ground truth); record processed ones in state.
57+
4. **Dedupe and merge (near-duplicates).** Group notes by `type`. Two notes are
58+
near-duplicates when: same `type`; significant-noun overlap above ~60% (a proxy for
59+
cosine similarity > 0.9); neither is `pinned`. Draft a merged note that is more
60+
complete and specific than either, keeping the clearest, most recent phrasing.
61+
Lossless of meaning, not of words.
62+
5. **Contradictions.** Two notes assert opposing facts on the same topic (for example
63+
"deploy to ECS" vs "deploy to Vercel"). Proposed winner: more recent with higher
64+
confidence. Present both for A/B/skip (interactive); skip in `--auto`.
65+
6. **Split.** If a note holds multiple distinct facts, split into atomic notes (one fact
66+
per file), renamed to `<type>-<slug>.md`.
67+
7. **Validate frontmatter.** Every note has `name` (equals filename stem), `description`,
68+
`type`, `tags`, `created`, `updated`. Fix the `<type>-` filename prefix if the type
69+
changed. No nested `metadata:` blocks.
70+
8. **Refresh from sources.** For notes with a `sources:` URL whose `updated:` is stale
71+
(older than ~30 days) or whose facts look outdated, fetch the source (prefer
72+
`llms.txt`), update the note, bump `updated:`. Skip silently when offline.
73+
9. **Compact.** Trim each note to essential facts; drop filler. Aim for ~25 lines or
74+
fewer.
75+
10. **Prune candidates.** A note is a prune candidate when any holds:
76+
- its `type` has a retention policy and it is older than the policy's days (compare
77+
`created`/`updated` to today);
78+
- `confidence` is below 0.3 AND it has no project-unique info (no paths,
79+
identifiers, or domain nouns);
80+
- it is wrong, obsolete, or out of scope.
81+
Never prune `pinned: true`. Prefer refreshing (step 8) over deleting merely because
82+
a note is old.
83+
11. **Relink and retag.** Fix `[[slug]]` references; ensure no orphans (each note links
84+
at least one other); merge tag sprawl into the controlled vocabulary; drop links to
85+
deleted notes.
86+
12. **Rebuild index.** Regenerate `MEMORY.md` from surviving notes, grouped by `type`,
87+
one line each: `[Title](file) — hook`.
88+
13. **Verify scope.** Confirm no secrets, hosts, or confidential facts slipped in;
89+
remove any that did.
90+
14. **Stamp.** Set `state.last_dream` to today.
91+
92+
## Retention policies (load in step 1)
93+
94+
Default per-type retention, in days (`null` means keep forever). Override via a
95+
`retention:` map in the KB's state or config file.
96+
97+
- `feedback`: 180
98+
- `project`: null
99+
- `reference`: null
100+
- `tech`: 365
101+
- `user`: null
102+
- `unknown`: 90
103+
104+
## Diff report (interactive)
105+
106+
Print exactly this before any change. Omit any section that has zero items.
107+
108+
```text
109+
## dream — consolidation report
110+
111+
Merges (<N>):
112+
[note:<file1>] + [note:<file2>] -> "<merged summary, ~80 chars>"
113+
114+
Conflicts (<N>):
115+
[note:<fileA>] vs [note:<fileB>] — "<topic>" [A/B/skip]
116+
117+
Prune (<N>):
118+
[note:<file>] — <type>, <age>d old
119+
120+
Inbox ingested (<N>), refreshed (<N>), split (<N>), relinked (<N>).
121+
122+
Proposed: <N> merges, <N> prunes, <N> conflicts. Apply? [Y/n]
123+
```
124+
125+
If there are zero proposals, print `Dream complete. No duplicate, contradictory, or stale
126+
notes found.` and stop.
127+
128+
## Resolve and apply (interactive)
129+
130+
- For each conflict, collect `A`, `B`, or `skip` (empty input = skip).
131+
- Final confirm: `Apply? [Y/n]`. `n` or `no` prints `Cancelled. No changes made.` and
132+
stops.
133+
- On confirm, apply in this order:
134+
1. **Merges** — write the merged note (`<type>-<slug>.md`; `type` and `updated` = today;
135+
`confidence` = the higher of the two originals; a `source: dream` marker), delete
136+
both originals, and rewrite inbound links to point at the merged slug.
137+
2. **Contradictions** — delete the loser of each resolved A/B pair; skipped pairs stay
138+
untouched.
139+
3. **Prunes** — delete the note and its index line.
140+
4. **Split, refresh, compact, relink, index rebuild** — apply the file writes.
141+
5. **Stamp** state, and run the KB's sync step only if one exists and only after the
142+
user confirms — never auto-push.
143+
144+
## Auto mode (`--auto`)
145+
146+
- **Concurrency guard.** Before working, check `${TMPDIR:-/tmp}/dream_auto.lock`. If it
147+
exists and is less than 10 minutes old, print
148+
`[dream --auto] another run in progress — skipping.` and stop. Otherwise write the lock
149+
(current timestamp); delete it on every exit path.
150+
- Run load and analyze (steps 1–3). Apply merges and prunes silently (no diff, no
151+
prompt). Skip contradictions (human judgment). Apply split, refresh, compact, relink,
152+
index rebuild, and stamp.
153+
- Print: `[dream --auto] kb=<path> merged=<N> pruned=<N> conflicts_skipped=<N>`.
154+
- If contradictions were skipped, leave a single reminder note so the human runs
155+
interactive `dream` to resolve them. First search for an existing `dream-auto` reminder
156+
(by `source: dream-auto`); skip storing if one already exists.
157+
158+
## forget
159+
160+
`dream forget "<query>" [<path>]` searches notes by keyword and semantic match, lists
161+
them, and proposes deletion as a diff:
162+
163+
```text
164+
[note:<file>] — "<title>" [Y/n]
165+
```
166+
167+
Apply only approved deletions (and their index lines). Pinned notes are listed but not
168+
deleted unless explicitly confirmed per note.
169+
170+
## Principles
171+
172+
- **Lossless of meaning** — compaction removes words and redundancy, never facts.
173+
- **Atomic** — one fact per file after the pass.
174+
- **Retrieval-first** — every `description` lets an agent judge relevance from the index
175+
alone; every note is reachable via tags and `[[links]]`.
176+
- **Conservative deletes** — prune only what is wrong, redundant, or out of scope; refresh
177+
rather than delete just because old.
178+
- **Idempotent** — running twice in a row changes nothing the second time.
179+
- **No surprises** — diff before write; never auto-push or auto-sync without approval.
180+
181+
## Checklist
182+
183+
- [ ] Resolved KB path from the argument or `$KB_DIR`; never assumed a fixed location.
184+
- [ ] Held everything in memory; no writes before the diff.
185+
- [ ] Inbox ingested and deleted; source docs kept.
186+
- [ ] Near-duplicates merged (same type, >60% noun overlap, not pinned).
187+
- [ ] Contradictions resolved (A/B) or skipped (`--auto`).
188+
- [ ] Stale notes refreshed from sources before pruning; pinned notes untouched.
189+
- [ ] Index rebuilt; no orphans; no broken `[[links]]`.
190+
- [ ] Scope verified (no secrets, hosts, or confidential facts).
191+
- [ ] State stamped; lock removed (`--auto`).
192+
193+
## Resources
194+
195+
- If the KB ships its own `DREAM.md` or `AGENTS.md`, read it first and align with its note
196+
format, controlled vocabulary, and sync steps.

marketplace.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,14 @@
178178
"version": "0.2.0",
179179
"type": "skill",
180180
"category": "automation"
181+
},
182+
{
183+
"name": "kb",
184+
"id": "kb@duyet-claude-plugins",
185+
"description": "Knowledge base maintenance skills. Consolidate, dedupe, prune, refresh, and forget notes in a markdown KB.",
186+
"version": "1.0.0",
187+
"type": "skill",
188+
"category": "productivity"
181189
}
182190
],
183191
"metadata": {

0 commit comments

Comments
 (0)