@evegoodevening/dsh-llmwiki 0.0.0-stage → 0.0.2
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/CHANGELOG.md +37 -0
- package/LICENSE +21 -0
- package/README.md +179 -2
- package/README.zh.md +180 -0
- package/THIRD_PARTY_NOTICES.md +40 -0
- package/cordis.patch.yml +1 -0
- package/lib/index.js +3281 -0
- package/lib/index.js.map +1 -0
- package/lib/types/atomic.d.ts +19 -0
- package/lib/types/atomic.d.ts.map +1 -0
- package/lib/types/command.d.ts +4 -0
- package/lib/types/command.d.ts.map +1 -0
- package/lib/types/config.d.ts +22 -0
- package/lib/types/config.d.ts.map +1 -0
- package/lib/types/errors.d.ts +16 -0
- package/lib/types/errors.d.ts.map +1 -0
- package/lib/types/ids.d.ts +8 -0
- package/lib/types/ids.d.ts.map +1 -0
- package/lib/types/index.d.ts +14 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/indexer.d.ts +69 -0
- package/lib/types/indexer.d.ts.map +1 -0
- package/lib/types/lint.d.ts +8 -0
- package/lib/types/lint.d.ts.map +1 -0
- package/lib/types/markdown.d.ts +17 -0
- package/lib/types/markdown.d.ts.map +1 -0
- package/lib/types/paths.d.ts +92 -0
- package/lib/types/paths.d.ts.map +1 -0
- package/lib/types/presentation.d.ts +5 -0
- package/lib/types/presentation.d.ts.map +1 -0
- package/lib/types/prompt.d.ts +6 -0
- package/lib/types/prompt.d.ts.map +1 -0
- package/lib/types/service.d.ts +39 -0
- package/lib/types/service.d.ts.map +1 -0
- package/lib/types/tokenizer.d.ts +9 -0
- package/lib/types/tokenizer.d.ts.map +1 -0
- package/lib/types/tools.d.ts +3 -0
- package/lib/types/tools.d.ts.map +1 -0
- package/lib/types/types.d.ts +123 -0
- package/lib/types/types.d.ts.map +1 -0
- package/package.json +96 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
## [0.0.2] - 2026-10-17
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Dependency-audit issue notifications: a separate least-privilege reporter assigns and mentions the maintainer on failure, deduplicates repeated failures, closes the alert after a completed successful audit, and reopens it on regression. Setup and registry failures remain alerts rather than being mistaken for recovery.
|
|
10
|
+
- Simplified Chinese README with installation, usage, and development guidance.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Standardized installation documentation on the automatically loaded profile `cordis.patch.yml`, retaining explicit activation and writable wiki roots. Documented preserving existing patches, migrating external overlays without duplicate insertion, and removing the profile entry on uninstall.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Added exact Cordis `4.0.5` peer support with DSH `0.2.0-rc.2`, retaining the previously supported versions and pinned legacy development dependencies. Latest-version compatibility hosts and strict consumers now apply the existing `@deepseek-ai/*` release-age exception so Cordis resolves with its required Loader/Include companions instead of mixing new core and older plugins; strict peer validation remains enabled.
|
|
19
|
+
|
|
20
|
+
## [0.0.1]
|
|
21
|
+
|
|
22
|
+
Initial release of `@evegoodevening/dsh-llmwiki`.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- Local-first Markdown wiki storage and retrieval as a DeepSeek Harness profile bundle, disabled by default and enabled through an operator-owned patch.
|
|
27
|
+
- Nine agent tools for status, immutable source capture and reads, paginated source/page catalogs, page reads and conditional writes, section search, and structural lint; `/wiki status`, `/wiki lint`, and `/wiki reindex` commands.
|
|
28
|
+
- SHA-256-addressed UTF-8 source records with preserved provenance, same-content deduplication, and narrow recovery of interrupted, uncommitted source writes.
|
|
29
|
+
- Source-linked Markdown pages with required `expectedSha256` write preconditions: `null` for creation or the current raw-Markdown hash for updates. Stale writes return `PAGE_CONFLICT`.
|
|
30
|
+
- Deterministic section-level lexical search with NFKC/lowercase tokenization, BM25 field weighting, bounded query-centered snippets, and automatic rebuilding of stale or semantically inconsistent indexes.
|
|
31
|
+
- Non-mutating status, catalogs, and structural lint covering storage integrity, links, and index freshness. Source/page reads and search may initialize storage; search may rebuild the index.
|
|
32
|
+
- Linux/procfs descriptor-contained filesystem operations with fail-closed capability checks and no pathname fallback. Concurrent writers across activations/processes and hostile root modification remain unsupported.
|
|
33
|
+
- Human-owned schema guidance and an agent workflow prompt separating structural lint from model-driven synthesis and semantic review. The plugin itself makes no model or network calls.
|
|
34
|
+
- Declared support for DSH `0.1.0-rc.6`, `0.1.1-rc.2`, `0.1.7-rc.2`, and `0.2.0-rc.2`, with the coherent service and Cordis families documented in the README.
|
|
35
|
+
- Packed-profile lifecycle and strict-consumer checks, deterministic filesystem race coverage, ordinary smoke, and a separately opted-in credentialed real-agent smoke harness.
|
|
36
|
+
- GitHub Actions workflows for npm Trusted Publishing, upstream compatibility monitoring, and an install-free dependency audit; a seven-day minimum dependency release age policy.
|
|
37
|
+
- Scoped third-party attribution and the complete retained upstream MIT notice for adapted workflow guidance, included in package artifacts.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 EveGoodEvening
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,180 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dsh-llmwiki
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
English | [简体中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
Third-party, local-first, source-linked Markdown wiki storage and retrieval plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH), inspired by [Karpathy's LLM Wiki](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f).
|
|
6
|
+
|
|
7
|
+
Maintained by EveGoodEvening, this is not an official DeepSeek or DeepSeek Harness project. References to DeepSeek Harness and Andrej Karpathy describe compatibility and inspiration only; they do not imply affiliation, sponsorship, or endorsement.
|
|
8
|
+
|
|
9
|
+
- Preserve immutable sources by SHA-256 and write Markdown pages that cite them.
|
|
10
|
+
- Search page sections with a deterministic lexical index; rebuild it when stale.
|
|
11
|
+
- Check structure, links, and integrity with model-free lint.
|
|
12
|
+
|
|
13
|
+
The plugin makes no model or network calls. The calling agent handles synthesis and semantic review; a source citation proves record existence, not claim support.
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
| DSH (`@deepseek-ai/dsh`) | Cordis (`@deepseek-ai/cordis`) | Status |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| **`0.2.0-rc.2`** | **`4.0.4` or `4.0.5`** | **Recommended** |
|
|
20
|
+
| `0.1.7-rc.2` | `4.0.4` | Supported |
|
|
21
|
+
| `0.1.1-rc.2` | `4.0.1` | Supported legacy |
|
|
22
|
+
| `0.1.0-rc.6` | `4.0.1` | Supported legacy |
|
|
23
|
+
|
|
24
|
+
- **Node.js:** `^22.19.0 || >=24`.
|
|
25
|
+
- **pnpm:** `11.7.0`, on `PATH` for `dsh plugin` and development.
|
|
26
|
+
- Use a coherent DSH service family, not mixed release candidates. The `0.1.0-rc.6` host resolves its five DSH service peers to `0.1.0-rc.8`; the other rows use same-version services.
|
|
27
|
+
- Cordis `4.0.5` requires Loader `~1.0.6` and Include `~1.0.10`; update the host's companion packages together rather than forcing Cordis onto older companions.
|
|
28
|
+
- Direct Cordis loading also needs DSH `tools`, `commands`, and `systemPrompt` services and one shared `@deepseek-ai/schemastery@^3.18.1` installation. See [exact peer ranges](package.json) and the [standalone example](examples/README.md).
|
|
29
|
+
|
|
30
|
+
The plugin's version in [package.json](package.json) is independent of the DSH and dependency versions above.
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
Use **`@evegoodevening/dsh-llmwiki`**. The unscoped `dsh-llmwiki` package belongs to a different project.
|
|
35
|
+
|
|
36
|
+
From this checkout, pack and install `0.0.2` with a supported DSH host on `PATH` (`web` is the example profile):
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
pnpm install --frozen-lockfile
|
|
40
|
+
pnpm pack
|
|
41
|
+
dsh plugin --profile web add ./evegoodevening-dsh-llmwiki-0.0.2.tgz
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
When the package is available on npm, the equivalent registry command is `dsh plugin --profile web add @evegoodevening/dsh-llmwiki@latest`.
|
|
45
|
+
|
|
46
|
+
Installation leaves the plugin **disabled**: its bundled patch is empty. To enable it, merge the following into the profile's `$DSH_HOME/profiles/web/cordis.patch.yml`. Preserve existing patches; if the file contains only `[]`, replace that empty list. Insert `llmwiki` only once, and replace the example `root` with your own writable absolute path. Plain YAML does not expand `$HOME`.
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
- insert:
|
|
50
|
+
- id: llmwiki
|
|
51
|
+
name: '@evegoodevening/dsh-llmwiki'
|
|
52
|
+
config:
|
|
53
|
+
root: /var/lib/dsh/llmwiki/web
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`insert` creates the plugin instance; a plain `- id: llmwiki` only overrides an existing instance. DSH automatically loads the profile patch. Inspect the composed configuration, then start:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
dsh --profile web --dump-config
|
|
60
|
+
dsh --profile web
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If migrating from an external `--patch` file, move its `llmwiki` entry here with the same root and remove that command-line argument. Do not load both copies. Restart a running profile after changes.
|
|
64
|
+
|
|
65
|
+
Use `/wiki status` to inspect the repository. Before changing the installed package, stop all writers and back up the root. Retain the same explicit root to reuse existing wiki data, and check the filesystem requirements below before enabling it.
|
|
66
|
+
|
|
67
|
+
To uninstall without deleting wiki data, first remove the `llmwiki` entry and any resulting empty `insert` block from the profile patch (use `[]` if no patches remain), then remove the package:
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
dsh plugin --profile web remove @evegoodevening/dsh-llmwiki
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
For local-tarball installation or standalone Cordis loading, use the [runnable example](examples/README.md).
|
|
74
|
+
|
|
75
|
+
## Usage
|
|
76
|
+
|
|
77
|
+
### Commands
|
|
78
|
+
|
|
79
|
+
| Command | Purpose |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| `/wiki status` | Report initialization, source/page counts, and index state; also the default `/wiki` action |
|
|
82
|
+
| `/wiki lint` | Report structural errors and warnings without repairing anything |
|
|
83
|
+
| `/wiki reindex` | Rebuild the derived search index |
|
|
84
|
+
|
|
85
|
+
### Agent tools
|
|
86
|
+
|
|
87
|
+
| Tool | Purpose |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| `llmwiki_status` | Inspect storage and read the human-owned schema |
|
|
90
|
+
| `llmwiki_add_source` | Preserve exact UTF-8 content; return its source ID |
|
|
91
|
+
| `llmwiki_list_sources` | Browse source metadata with pagination |
|
|
92
|
+
| `llmwiki_read_source` | Read preserved content and provenance |
|
|
93
|
+
| `llmwiki_search` | Find ranked page-section matches |
|
|
94
|
+
| `llmwiki_list_pages` | Browse page metadata and hashes with pagination |
|
|
95
|
+
| `llmwiki_read_page` | Read exact page Markdown and its SHA-256 by logical ID |
|
|
96
|
+
| `llmwiki_upsert_page` | Create or conditionally update a page citing existing source IDs |
|
|
97
|
+
| `llmwiki_lint` | Check structure, integrity, links, and index freshness |
|
|
98
|
+
|
|
99
|
+
Start with status and the schema. Preserve sources and maintain affected pages only with user authorization. Run structural lint **before semantic review**, even without writes, and again after any updates. Semantic findings are agent judgments, not lint results. Full workflow: [runtime prompt](src/prompt.ts); parameters: [tool schemas](src/tools.ts).
|
|
100
|
+
|
|
101
|
+
Search uses deterministic NFKC/lowercase tokens and BM25 field weighting; ties sort by page ID and section start line. Snippets show contiguous normalized body context around the earliest fitting scored query token (whole letter/number run or existing CJK two-code-point gram), with same-position ties resolved by UTF-16 lexical token order. They stay within `maxSnippetBytes` without splitting UTF-8 code points; no omission markers are added. Dispersed query terms need not all appear. Title/heading-only matches and body tokens too large for the cap use a bounded body prefix instead.
|
|
102
|
+
|
|
103
|
+
### Page-write preconditions
|
|
104
|
+
|
|
105
|
+
Every page write requires `expectedSha256`: use `null` to create an absent page, or the exact raw-Markdown `sha256` returned by a page read or catalog to update an existing page. On `PAGE_CONFLICT`, reread and reconcile the page before retrying; do not overwrite with a stale hash or blindly retry.
|
|
106
|
+
|
|
107
|
+
## Configuration
|
|
108
|
+
|
|
109
|
+
All keys are optional. Numeric values are integers; unknown keys are rejected.
|
|
110
|
+
|
|
111
|
+
| Key | Default | Meaning / limits |
|
|
112
|
+
| --- | --- | --- |
|
|
113
|
+
| `root` | `.llmwiki` | Non-empty path, resolved once from the host process cwd |
|
|
114
|
+
| `maxSourceBytes` | `2097152` | Source content limit: 2 MiB; minimum 1 byte |
|
|
115
|
+
| `maxPageBytes` | `524288` | Rendered page body limit: 512 KiB; minimum 1 byte |
|
|
116
|
+
| `maxResults` | `20` | Search and catalog page-size cap; `1..100` |
|
|
117
|
+
| `maxSnippetBytes` | `1200` | Search snippet limit; `64..16384` bytes |
|
|
118
|
+
| `commandDiagnosticLimit` | `20` | Diagnostics printed by `/wiki lint`; `1..100` |
|
|
119
|
+
|
|
120
|
+
## Storage and safety
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
<root>/
|
|
124
|
+
schema.md # human-owned guidance; created only if absent
|
|
125
|
+
sources/<sha256>/
|
|
126
|
+
content # immutable UTF-8 source
|
|
127
|
+
metadata.json # provenance and capture metadata
|
|
128
|
+
pages/<page-id>.md # Markdown with title, summary, and source IDs
|
|
129
|
+
.index/{search,state}.json # derived, rebuildable search data
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
- **Host storage, not a DSH sandbox.** Direct Node filesystem I/O bypasses `ctx.fs`, DSH permission modes, approval, read-before-edit, and remote/workspace providers. Do not enable this plugin where those controls are required; enforce boundaries with OS permissions and process isolation.
|
|
133
|
+
- **One fixed root per activation.** Session/workspace cwd changes do not switch storage. Use distinct roots for isolation; mutually untrusted tenants must not share a root or activation. Concurrent writers across activations/processes are unsupported. Do not let untrusted processes modify the root.
|
|
134
|
+
- **Filesystem backend.** Descriptor-contained storage requires Linux, numeric nofollow/directory-open flags, and a mounted, usable `/proc/self/fd`. Unsupported or unavailable capabilities fail closed with `UNSAFE_FILESYSTEM`; there is no pathname fallback. Non-Linux descriptor backends are not supported or claimed proven. Root and child directories are pinned per operation, final files are opened without following symlinks, and an initialized root's device/inode identity must remain unchanged.
|
|
135
|
+
- **Adversary limits.** Pinned traversal prevents symlink substitution from redirecting filesystem operations into an outside symlink target. It is not a whole-tree transaction or a compare-and-rename guarantee. An already-authorized directory can remain accessible after being renamed outside its former lexical root. Ordinary file/hardlink injection, privileged mount or process access, and hostile replacement of procfs are outside this guarantee; OS isolation and the no-untrusted-writers requirement still apply.
|
|
136
|
+
- **Some reads can write.** Status, catalog listings, and lint never write. Source/page reads and search may initialize storage; search may also rebuild the index. Read-only deployments need an initialized repository and a fresh index.
|
|
137
|
+
- Sources are never edited or deleted by the plugin. Existing `schema.md` is preserved; there is no schema-editing API.
|
|
138
|
+
|
|
139
|
+
### Interrupted source writes
|
|
140
|
+
|
|
141
|
+
Retry `llmwiki_add_source` (or `ctx.llmwiki.addSource`) with identical content after an interrupted source write. Recovery is limited to the final source directory with **no committed `metadata.json`**, containing only an empty state, matching durable `content`, and/or recognized regular writer temporary files. Matching durable content is preserved; metadata commits last using the retry's provenance. The recovered receipt has `deduplicated: false`; the next identical-content retry deduplicates.
|
|
142
|
+
|
|
143
|
+
A valid complete record always deduplicates without changing its first committed metadata/provenance bytes. Corrupt content or metadata, unknown children, and symlink/nonregular children are refused without changing the rejected record. Reads, catalogs, and lint do not repair partial records or treat them as valid; source/page reads can still initialize the storage layout as described above. This is narrow crash retry, not a generic repair/quarantine facility or a multi-page transaction.
|
|
144
|
+
|
|
145
|
+
## Development
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
pnpm install --frozen-lockfile
|
|
149
|
+
pnpm run build
|
|
150
|
+
pnpm run typecheck
|
|
151
|
+
pnpm run lint
|
|
152
|
+
pnpm test
|
|
153
|
+
pnpm run test:e2e
|
|
154
|
+
pnpm run check:determinism
|
|
155
|
+
pnpm run smoke
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The Linux unit suite's read-only tmpfs test requires root and mount-namespace capability. E2E builds first and exercises packed packages across the supported host matrix; run it separately from other builds because it temporarily hides shared checkout paths. Ordinary smoke uses the pinned legacy development dependencies, not the recommended host.
|
|
159
|
+
|
|
160
|
+
- **Upstream compatibility:** `pnpm run check:compatibility` probes latest DSH with native dependencies and, separately, forced latest Cordis. Disposable hosts and consumers apply the repository's `@deepseek-ai/*` release-age exception so fresh vendor companions can resolve together; other dependency age settings are unchanged. Networked, model-free; probes do not automatically extend the support table. See the [scheduled workflow](.github/workflows/compatibility.yml).
|
|
161
|
+
- **Real-agent smoke:** set `DEEPSEEK_API_KEY`, `LLMWIKI_AGENT_SMOKE_MODEL`, and `LLMWIKI_AGENT_SMOKE_NETWORK=allow`, then run `pnpm run smoke:agent`. This separate, credentialed check uses a pinned DSH `0.1.1-rc.2` runner; offline checks do not prove model behavior.
|
|
162
|
+
- **Publishing:** the [release workflow](.github/workflows/publish.yml) uses npm Trusted Publishing for a `v*` tag matching `package.json`.
|
|
163
|
+
|
|
164
|
+
## References / Acknowledgements
|
|
165
|
+
|
|
166
|
+
The design and integration work consulted these sources:
|
|
167
|
+
|
|
168
|
+
- [Andrej Karpathy's LLM Wiki idea file](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) — the primary conceptual inspiration: immutable raw sources, a persistent LLM-maintained Markdown wiki, schema guidance, and ingest/query/lint workflows. It describes a pattern, not a required implementation or API.
|
|
169
|
+
- [Astro-Han/karpathy-llm-wiki](https://github.com/Astro-Han/karpathy-llm-wiki) — the raw/wiki/schema separation, evidence requirements, and explicit ingest/query/lint workflows in its agent skill. The specific triage and cascade-update guidance is covered by the scoped attribution and retained MIT license in [Third-party notices](THIRD_PARTY_NOTICES.md).
|
|
170
|
+
- [ddsyasas/llm-wiki](https://github.com/ddsyasas/llm-wiki) — persisted source/page records, index-first navigation, and the separation of deterministic lint from model judgment. Its Next.js/SQLite/FTS application architecture is not adopted here.
|
|
171
|
+
- [Praney Behl's llm-wiki-plugin](https://github.com/praneybehl/llm-wiki-plugin) — section-level lexical retrieval and stable evidence output in its search tooling, plus surgical page updates, citations, and user-review boundaries in its ingest workflow. Its Python/uv/FastEmbed/sqlite-vec runtime is not adopted here.
|
|
172
|
+
- [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness/tree/fa7e9f5a) — Cordis plugin and service conventions, lifecycle ownership, tool/command/system-prompt registration, and profile bundle integration. The initial integration research used revision `fa7e9f5a`; supported runtime versions are listed above.
|
|
173
|
+
|
|
174
|
+
These acknowledgements identify design influences and integration references; they do not imply endorsement by the referenced authors or projects. This package's MIT license does not relicense the referenced works, which remain subject to their own copyright and licensing terms.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
[MIT](LICENSE) © EveGoodEvening.
|
|
179
|
+
|
|
180
|
+
See [Third-party notices](THIRD_PARTY_NOTICES.md) for the scope and complete upstream license retained for workflow guidance. The project's MIT license does not replace that notice.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# dsh-llmwiki
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 简体中文
|
|
4
|
+
|
|
5
|
+
面向 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)的第三方 Markdown wiki 存储与检索插件,采用本地优先设计,关联原始来源,灵感来自 [Karpathy 的 LLM Wiki](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f)。
|
|
6
|
+
|
|
7
|
+
本项目由 EveGoodEvening 维护,并非 DeepSeek 或 DeepSeek Harness 官方项目。提及 DeepSeek Harness 和 Andrej Karpathy 仅用于说明兼容性与灵感来源,不代表任何隶属、赞助或背书关系。
|
|
8
|
+
|
|
9
|
+
- 按 SHA-256 保存不可变来源,并编写引用这些来源的 Markdown 页面。
|
|
10
|
+
- 使用确定性的词法索引搜索页面章节;索引过期时重建。
|
|
11
|
+
- 通过不调用模型的 lint 检查结构、链接和完整性。
|
|
12
|
+
|
|
13
|
+
插件不会调用模型,也不会发起网络请求。内容综合与语义审查由调用它的智能体负责;引用来源只能证明对应记录存在,不能证明其支持相关主张。
|
|
14
|
+
|
|
15
|
+
## 环境要求
|
|
16
|
+
|
|
17
|
+
| DSH(`@deepseek-ai/dsh`) | Cordis(`@deepseek-ai/cordis`) | 状态 |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| **`0.2.0-rc.2`** | **`4.0.4` 或 `4.0.5`** | **推荐** |
|
|
20
|
+
| `0.1.7-rc.2` | `4.0.4` | 支持 |
|
|
21
|
+
| `0.1.1-rc.2` | `4.0.1` | 支持的旧版本 |
|
|
22
|
+
| `0.1.0-rc.6` | `4.0.1` | 支持的旧版本 |
|
|
23
|
+
|
|
24
|
+
- **Node.js:** `^22.19.0 || >=24`。
|
|
25
|
+
- **pnpm:** `11.7.0`,执行 `dsh plugin` 和开发时需确保其位于 `PATH` 中。
|
|
26
|
+
- 使用相互兼容的同一系列 DSH 服务,不要混用不同的候选发布版本。`0.1.0-rc.6` 宿主会将其五个 DSH 服务对等依赖解析为 `0.1.0-rc.8`;表中其他宿主使用与自身版本相同的服务。
|
|
27
|
+
- Cordis `4.0.5` 需要 Loader `~1.0.6` 和 Include `~1.0.10`;请一并更新宿主的配套依赖,不要将新版 Cordis 强行搭配旧版配套包。
|
|
28
|
+
- 直接通过 Cordis 加载时,还需要 DSH 的 `tools`、`commands` 和 `systemPrompt` 服务,以及一份共享的 `@deepseek-ai/schemastery@^3.18.1` 安装。参见[准确的对等依赖版本范围](package.json)和[独立加载示例](examples/README.md)。
|
|
29
|
+
|
|
30
|
+
[package.json](package.json) 中的插件版本独立于上表中的 DSH 和依赖版本。
|
|
31
|
+
|
|
32
|
+
## 安装
|
|
33
|
+
|
|
34
|
+
请使用 **`@evegoodevening/dsh-llmwiki`**。不带作用域的 `dsh-llmwiki` 包属于另一个项目。
|
|
35
|
+
|
|
36
|
+
在当前检出的仓库中打包并安装 `0.0.2`,同时确保受支持的 DSH 宿主位于 `PATH` 中(以下以 `web` profile 为例):
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
pnpm install --frozen-lockfile
|
|
40
|
+
pnpm pack
|
|
41
|
+
dsh plugin --profile web add ./evegoodevening-dsh-llmwiki-0.0.2.tgz
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
当该包在 npm 上可用时,等效的仓库安装命令为 `dsh plugin --profile web add @evegoodevening/dsh-llmwiki@latest`。
|
|
45
|
+
|
|
46
|
+
安装后插件仍处于**禁用**状态:随包补丁为空。启用时,将以下内容合并到 profile 的 `$DSH_HOME/profiles/web/cordis.patch.yml` 中。保留已有补丁;如果文件只有 `[]`,则用以下列表替换该空列表。只插入一次 `llmwiki`,并将示例 `root` 替换为自己的可写绝对路径。普通 YAML 不会展开 `$HOME`。
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
- insert:
|
|
50
|
+
- id: llmwiki
|
|
51
|
+
name: '@evegoodevening/dsh-llmwiki'
|
|
52
|
+
config:
|
|
53
|
+
root: /var/lib/dsh/llmwiki/web
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`insert` 用于创建插件实例;单独的 `- id: llmwiki` 只能修改已有实例。DSH 会自动加载 profile 补丁。先检查合成后的配置,再启动:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
dsh --profile web --dump-config
|
|
60
|
+
dsh --profile web
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
如果此前使用外置 `--patch` 文件,请将其中的 `llmwiki` 条目移到这里,保持原有根目录,并移除对应的命令行参数。不要重复加载两份配置。修改后请重启正在运行的 profile。
|
|
64
|
+
|
|
65
|
+
使用 `/wiki status` 检查仓库状态。更改已安装的包之前,先停止所有写入操作并备份根目录。保留同一个显式指定的根目录,即可复用已有 wiki 数据;启用前请检查下文的文件系统要求。
|
|
66
|
+
|
|
67
|
+
如需卸载插件但保留 wiki 数据,先从 profile 补丁中移除 `llmwiki` 条目以及因此变空的 `insert` 块(如果没有剩余补丁,则保留 `[]`),然后移除包:
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
dsh plugin --profile web remove @evegoodevening/dsh-llmwiki
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
本地 tarball 安装或独立 Cordis 加载方式,参见[可运行示例](examples/README.md)。
|
|
74
|
+
|
|
75
|
+
## 使用
|
|
76
|
+
|
|
77
|
+
### 命令
|
|
78
|
+
|
|
79
|
+
| 命令 | 用途 |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| `/wiki status` | 报告初始化状态、来源/页面数量及索引状态;也是 `/wiki` 的默认操作 |
|
|
82
|
+
| `/wiki lint` | 报告结构错误和警告,不进行任何修复 |
|
|
83
|
+
| `/wiki reindex` | 重建派生的搜索索引 |
|
|
84
|
+
|
|
85
|
+
### 智能体工具
|
|
86
|
+
|
|
87
|
+
| 工具 | 用途 |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| `llmwiki_status` | 检查存储并读取由人工维护的 schema |
|
|
90
|
+
| `llmwiki_add_source` | 原样保存 UTF-8 内容,返回来源 ID |
|
|
91
|
+
| `llmwiki_list_sources` | 分页浏览来源元数据 |
|
|
92
|
+
| `llmwiki_read_source` | 读取已保存的内容及来源信息 |
|
|
93
|
+
| `llmwiki_search` | 查找按相关性排序的页面章节匹配结果 |
|
|
94
|
+
| `llmwiki_list_pages` | 分页浏览页面元数据和哈希 |
|
|
95
|
+
| `llmwiki_read_page` | 按逻辑 ID 读取页面的原始 Markdown 及其 SHA-256 |
|
|
96
|
+
| `llmwiki_upsert_page` | 创建或有条件地更新引用已有来源 ID 的页面 |
|
|
97
|
+
| `llmwiki_lint` | 检查结构、完整性、链接及索引是否最新 |
|
|
98
|
+
|
|
99
|
+
先查看状态和 schema。仅在获得用户授权后保存来源并维护受影响的页面。即使没有写入,也要在**语义审查之前**运行结构 lint;发生任何更新后,再运行一次。语义层面的发现是智能体的判断,不是 lint 结果。完整工作流见[运行时提示词](src/prompt.ts);参数见[工具 schema](src/tools.ts)。
|
|
100
|
+
|
|
101
|
+
搜索使用经 NFKC 规范化和小写转换后得到的确定性词元,并采用 BM25 字段加权;分数相同时,按页面 ID 和章节起始行排序。片段围绕最早出现、能完整容纳且参与评分的查询词元,展示规范化正文中的连续上下文;词元为完整的字母/数字串,或现有的 CJK 双码点 n-gram,同一位置的候选按词元的 UTF-16 字典序打破平局。片段大小不超过 `maxSnippetBytes`,不会截断 UTF-8 码点,也不添加省略标记。分散的查询词不一定全部出现在片段中。仅标题/章节标题匹配,或正文词元过大而超出上限时,改用受长度限制的正文前缀。
|
|
102
|
+
|
|
103
|
+
### 页面写入前置条件
|
|
104
|
+
|
|
105
|
+
每次写入页面都必须提供 `expectedSha256`:创建尚不存在的页面时使用 `null`;更新已有页面时,使用读取页面或目录列表返回的、对原始 Markdown 计算出的精确 `sha256`。遇到 `PAGE_CONFLICT` 时,先重新读取页面并整合差异,再重试;不要使用过期哈希覆盖页面,也不要盲目重试。
|
|
106
|
+
|
|
107
|
+
## 配置
|
|
108
|
+
|
|
109
|
+
所有配置项均为可选。数值必须为整数;未知配置项会被拒绝。
|
|
110
|
+
|
|
111
|
+
| 配置项 | 默认值 | 含义 / 限制 |
|
|
112
|
+
| --- | --- | --- |
|
|
113
|
+
| `root` | `.llmwiki` | 非空路径;基于宿主进程的 cwd 一次性解析 |
|
|
114
|
+
| `maxSourceBytes` | `2097152` | 来源内容上限:2 MiB;最小为 1 字节 |
|
|
115
|
+
| `maxPageBytes` | `524288` | 渲染后的页面正文上限:512 KiB;最小为 1 字节 |
|
|
116
|
+
| `maxResults` | `20` | 搜索和目录列表的每页条目数上限;`1..100` |
|
|
117
|
+
| `maxSnippetBytes` | `1200` | 搜索片段上限;`64..16384` 字节 |
|
|
118
|
+
| `commandDiagnosticLimit` | `20` | `/wiki lint` 输出的诊断条目数;`1..100` |
|
|
119
|
+
|
|
120
|
+
## 存储与安全
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
<root>/
|
|
124
|
+
schema.md # 由人工维护的指引;仅在不存在时创建
|
|
125
|
+
sources/<sha256>/
|
|
126
|
+
content # 不可变的 UTF-8 来源
|
|
127
|
+
metadata.json # 来源信息与采集元数据
|
|
128
|
+
pages/<page-id>.md # 包含标题、摘要和来源 ID 的 Markdown
|
|
129
|
+
.index/{search,state}.json # 派生的、可重建的搜索数据
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
- **宿主机存储,而非 DSH 沙箱。** 直接使用 Node 文件系统 I/O,会绕过 `ctx.fs`、DSH 权限模式、审批、编辑前读取要求,以及远程/工作区提供器。如果必须依赖这些控制机制,请勿启用本插件;应通过操作系统权限和进程隔离来实施边界约束。
|
|
133
|
+
- **每次激活使用固定的根目录。** 会话/工作区的 cwd 发生变化时,不会切换存储位置。通过不同根目录实现隔离;互不信任的租户不得共用根目录或同一次插件激活实例。不支持跨激活实例/进程并发写入。不要允许不受信任的进程修改根目录。
|
|
134
|
+
- **文件系统后端。** 以文件描述符约束路径访问的存储后端需要 Linux、数值形式的 nofollow/目录打开标志,以及已挂载且可用的 `/proc/self/fd`。所需能力不受支持或不可用时,会以 `UNSAFE_FILESYSTEM` 拒绝操作;不会回退到基于路径名的访问方式。不支持非 Linux 的文件描述符后端,也不声称已证明其安全性。每次操作都会固定根目录和子目录的描述符,打开最终文件时不跟随符号链接;已初始化根目录的设备号/inode 标识必须保持不变。
|
|
135
|
+
- **对抗保证的边界。** 固定描述符的路径遍历可防止符号链接替换将文件系统操作重定向到根目录外的符号链接目标。但这并非整棵目录树的事务,也不提供 compare-and-rename(比较后重命名)保证。已授权访问的目录被重命名到原有路径名所定义的根目录之外后,仍可能保持可访问。普通文件/硬链接注入、借助特权进行挂载或访问进程,以及恶意替换 procfs,均不在此保证范围内;仍须依赖操作系统隔离,并禁止不受信任的写入者。
|
|
136
|
+
- **部分读取操作可能写入。** 状态查询、目录列表和 lint 从不写入。读取来源/页面以及搜索可能初始化存储;搜索还可能重建索引。只读部署需要已初始化的仓库及最新索引。
|
|
137
|
+
- 插件从不编辑或删除来源。已有的 `schema.md` 会被保留;不提供编辑 schema 的 API。
|
|
138
|
+
|
|
139
|
+
### 来源写入中断
|
|
140
|
+
|
|
141
|
+
来源写入中断后,以相同内容重试 `llmwiki_add_source`(或 `ctx.llmwiki.addSource`)。恢复仅限于**尚未提交 `metadata.json`** 的最终来源目录;该目录必须为空,或仅包含内容匹配的已持久化 `content` 和/或可识别为写入器产生的临时文件(必须为普通文件)。匹配的持久化内容会被保留;元数据使用重试时提供的来源信息,并在最后提交。恢复操作返回的回执带有 `deduplicated: false`;下一次使用相同内容重试时会去重。
|
|
142
|
+
|
|
143
|
+
有效且完整的记录始终会去重,不会更改首次提交的元数据/来源信息字节。内容或元数据损坏、包含未知子项,或子项为符号链接/非普通文件的记录,都会被拒绝,且被拒绝的记录保持不变。读取、目录列表和 lint 不会修复部分写入的记录,也不会将其视为有效记录;如上所述,读取来源/页面仍可能初始化存储布局。这只是针对崩溃后重试的有限恢复机制,并非通用修复/隔离设施,也不是多页面事务。
|
|
144
|
+
|
|
145
|
+
## 开发
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
pnpm install --frozen-lockfile
|
|
149
|
+
pnpm run build
|
|
150
|
+
pnpm run typecheck
|
|
151
|
+
pnpm run lint
|
|
152
|
+
pnpm test
|
|
153
|
+
pnpm run test:e2e
|
|
154
|
+
pnpm run check:determinism
|
|
155
|
+
pnpm run smoke
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Linux 单元测试套件中的只读 tmpfs 测试需要 root 权限和挂载命名空间能力。E2E 会先构建,再在受支持的宿主版本矩阵中测试打包后的包;请与其他构建分开运行,因为它会临时隐藏共享的仓库检出路径。常规 smoke 使用固定的旧版开发依赖,而非推荐宿主。
|
|
159
|
+
|
|
160
|
+
- **上游兼容性:** `pnpm run check:compatibility` 分别检查使用原生依赖的最新版 DSH,以及强制使用最新版 Cordis 的情况。临时宿主和消费者项目沿用仓库的 `@deepseek-ai/*` 最低发布年龄例外,使新发布的配套包能够一起解析;其他依赖的发布年龄设置保持不变。此检查需要联网,但不调用模型;检查结果不会自动扩展支持表。参见[定时工作流](.github/workflows/compatibility.yml)。
|
|
161
|
+
- **真实智能体 smoke:** 设置 `DEEPSEEK_API_KEY`、`LLMWIKI_AGENT_SMOKE_MODEL` 和 `LLMWIKI_AGENT_SMOKE_NETWORK=allow`,然后运行 `pnpm run smoke:agent`。这项独立且需要凭据的检查使用固定的 DSH `0.1.1-rc.2` 运行器;离线检查不能证明模型行为。
|
|
162
|
+
- **发布:** [发布工作流](.github/workflows/publish.yml)使用 npm Trusted Publishing,针对与 `package.json` 版本匹配的 `v*` 标签执行发布。
|
|
163
|
+
|
|
164
|
+
## 参考资料 / 致谢
|
|
165
|
+
|
|
166
|
+
设计与集成工作参考了以下来源:
|
|
167
|
+
|
|
168
|
+
- [Andrej Karpathy 的 LLM Wiki 构想文件](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f)——主要概念灵感:不可变的原始来源、由 LLM 维护的持久化 Markdown wiki、schema 指引,以及导入/查询/lint 工作流。它描述的是一种模式,而非必须遵循的实现或 API。
|
|
169
|
+
- [Astro-Han/karpathy-llm-wiki](https://github.com/Astro-Han/karpathy-llm-wiki)——其智能体技能中的 raw/wiki/schema 分离、证据要求,以及明确的导入/查询/lint 工作流。具体的分流处理与级联更新指引,其限定范围的归属说明及保留的 MIT 许可证见[第三方声明](THIRD_PARTY_NOTICES.md)。
|
|
170
|
+
- [ddsyasas/llm-wiki](https://github.com/ddsyasas/llm-wiki)——持久化来源/页面记录、索引优先导航,以及确定性 lint 与模型判断的分离。本项目未采用其 Next.js/SQLite/FTS 应用架构。
|
|
171
|
+
- [Praney Behl 的 llm-wiki-plugin](https://github.com/praneybehl/llm-wiki-plugin)——其搜索工具中的章节级词法检索与稳定的证据输出,以及导入工作流中的精准页面更新、引用和用户审查边界。本项目未采用其 Python/uv/FastEmbed/sqlite-vec 运行时。
|
|
172
|
+
- [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness/tree/fa7e9f5a)——Cordis 插件与服务约定、生命周期归属、工具/命令/系统提示词注册,以及 profile bundle 集成。最初的集成研究使用修订版本 `fa7e9f5a`;受支持的运行时版本见上表。
|
|
173
|
+
|
|
174
|
+
这些致谢用于说明设计影响和集成参考,并不意味着相关作者或项目为本项目背书。本包的 MIT 许可证不会改变所引用作品的许可;这些作品仍受各自的版权和许可条款约束。
|
|
175
|
+
|
|
176
|
+
## 许可证
|
|
177
|
+
|
|
178
|
+
[MIT](LICENSE) © EveGoodEvening。
|
|
179
|
+
|
|
180
|
+
有关工作流指引的归属范围及保留的完整上游许可证,请参见[第三方声明](THIRD_PARTY_NOTICES.md)。本项目的 MIT 许可证不能替代该声明。
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
This file preserves the upstream notice for the workflow guidance identified below. The project's own material remains licensed under [LICENSE](LICENSE). Referenced projects and separately installed dependencies retain their own copyrights and licenses; inclusion here does not imply endorsement.
|
|
4
|
+
|
|
5
|
+
## Astro-Han / karpathy-llm-wiki — workflow guidance
|
|
6
|
+
|
|
7
|
+
- Upstream project: https://github.com/Astro-Han/karpathy-llm-wiki
|
|
8
|
+
- Audited source: [`SKILL.md` at `eafcc77001e496cc43499e4923b663aec722c813`](https://github.com/Astro-Han/karpathy-llm-wiki/blob/eafcc77001e496cc43499e4923b663aec722c813/SKILL.md), particularly **Ingest / Triage** and **Cascade Updates**.
|
|
9
|
+
- Upstream license: [`LICENSE` at the same revision](https://github.com/Astro-Han/karpathy-llm-wiki/blob/eafcc77001e496cc43499e4923b663aec722c813/LICENSE).
|
|
10
|
+
- Local scope: the source-disposition, affected-page maintenance, and conflict/supersession guidance in `LLMWIKI_SYSTEM_PROMPT` (`src/prompt.ts`) and `DEFAULT_SCHEMA` (`src/service.ts`), their compiled representations, and corresponding workflow descriptions in the examples, maintenance fixtures, and planning/handoff documents.
|
|
11
|
+
|
|
12
|
+
The relevant guidance combines new/update/disputed/no-material source triage, maintenance of materially affected pages, and preservation of conflicting or superseded claims. This project reorganizes the guidance around its own APIs, retains some similar terminology and phrasing, calls the disputed case `contradiction`, and adds authorization and concurrency rules. The textual and procedural correspondences suggest a probable adaptation of this workflow guidance, although the original development-time use of the upstream material has not been confirmed. The upstream copyright and license notice is retained conservatively on that basis. This attribution does not extend to the plugin's storage, parser, search, or DSH integration implementation, and makes no determination about the copyrightability of an abstract workflow.
|
|
13
|
+
|
|
14
|
+
The audited revision identifies the material compared during the provenance review, not a recorded exact checkout used during the original development. Karpathy's separate LLM Wiki idea file remains a conceptual reference: no MIT license is asserted for that gist, and this notice does not relicense it.
|
|
15
|
+
|
|
16
|
+
### Upstream license text
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
MIT License
|
|
20
|
+
|
|
21
|
+
Copyright (c) 2026 Yuhan Lei
|
|
22
|
+
|
|
23
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
24
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
25
|
+
in the Software without restriction, including without limitation the rights
|
|
26
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
27
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
28
|
+
furnished to do so, subject to the following conditions:
|
|
29
|
+
|
|
30
|
+
The above copyright notice and this permission notice shall be included in all
|
|
31
|
+
copies or substantial portions of the Software.
|
|
32
|
+
|
|
33
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
34
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
35
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
36
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
37
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
38
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
39
|
+
SOFTWARE.
|
|
40
|
+
```
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[]
|