dsh-library 0.1.0

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +201 -0
  3. package/README.es.md +158 -0
  4. package/README.hi.md +158 -0
  5. package/README.md +158 -0
  6. package/README.pt.md +158 -0
  7. package/README.zh.md +158 -0
  8. package/SECURITY.md +38 -0
  9. package/THIRD_PARTY_NOTICES.md +27 -0
  10. package/cordis.patch.yml +79 -0
  11. package/lib/index.js +6074 -0
  12. package/lib/types/config.d.ts +208 -0
  13. package/lib/types/config.d.ts.map +1 -0
  14. package/lib/types/embedding.d.ts +56 -0
  15. package/lib/types/embedding.d.ts.map +1 -0
  16. package/lib/types/ids.d.ts +27 -0
  17. package/lib/types/ids.d.ts.map +1 -0
  18. package/lib/types/index.d.ts +248 -0
  19. package/lib/types/index.d.ts.map +1 -0
  20. package/lib/types/quality/chunk-visual.d.ts +93 -0
  21. package/lib/types/quality/chunk-visual.d.ts.map +1 -0
  22. package/lib/types/quality/citation.d.ts +76 -0
  23. package/lib/types/quality/citation.d.ts.map +1 -0
  24. package/lib/types/quality/diversity.d.ts +54 -0
  25. package/lib/types/quality/diversity.d.ts.map +1 -0
  26. package/lib/types/quality/few-shot.d.ts +54 -0
  27. package/lib/types/quality/few-shot.d.ts.map +1 -0
  28. package/lib/types/quality/lost-middle.d.ts +95 -0
  29. package/lib/types/quality/lost-middle.d.ts.map +1 -0
  30. package/lib/types/quality/purge.d.ts +55 -0
  31. package/lib/types/quality/purge.d.ts.map +1 -0
  32. package/lib/types/quality/reference.d.ts +75 -0
  33. package/lib/types/quality/reference.d.ts.map +1 -0
  34. package/lib/types/quality/relevance.d.ts +44 -0
  35. package/lib/types/quality/relevance.d.ts.map +1 -0
  36. package/lib/types/text.d.ts +51 -0
  37. package/lib/types/text.d.ts.map +1 -0
  38. package/package.json +149 -0
package/README.md ADDED
@@ -0,0 +1,158 @@
1
+ <div align="center">
2
+
3
+ # 📚 dsh-library
4
+
5
+ **Local document knowledge base for DeepSeek Harness.**
6
+
7
+ *Import, retrieve, verify — hybrid search with citations your agent can check.*
8
+
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-library/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-library/actions)
13
+ [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-library?label=version)](https://github.com/PerryLink/dsh-library/releases)
14
+ [![npm version](https://img.shields.io/npm/v/dsh-library)](https://www.npmjs.com/package/dsh-library)
15
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-library)](https://www.npmjs.com/package/dsh-library)
16
+
17
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
18
+
19
+ </div>
20
+
21
+ ---
22
+
23
+ ## Compatibility
24
+
25
+ | Surface | Status |
26
+ |---|---|
27
+ | Harness | DeepSeek Harness `0.1.0-rc.6` (compat declared for `0.1.0-rc.5`–`0.1.0-rc.6`) |
28
+ | Node | `^22.19.0 \|\| >=24.0.0` |
29
+ | Storage | Any storage-domain backend (JSON or SQLite); the index lives in the host's storage domain |
30
+ | Models | None required — the built-in embedder is deterministic hashing (zero downloads) |
31
+
32
+ ## What you get
33
+
34
+ `dsh-library` turns local md/txt documents into a queryable knowledge base with a quality pipeline your agent can trust:
35
+
36
+ - **`library_add` / `library_remove` / `library_list`** — import a document by path (chunked and embedded), remove one with **purge verification** (signatures of the removed content are probed against the remaining index and any residue is reported), and list document metadata.
37
+ - **`library_search`** — hybrid semantic + keyword ranking, maximal-marginal-relevance diversity re-rank, relevance filtering, and **lost-in-the-middle avoidance** (strongest chunks pinned to head and tail). With `inject: true` the result page is injected into the calling agent; every hit carries a `[n]` source marker and the injection is reconstructable from the `library/inject` session event.
38
+ - **`library_cite_check`** — verify the `[n]` citations in an answer against the search result page with a fuzzy token match AND a semantic similarity check.
39
+ - **`library_diagnose`** — chunk-size histogram, near-duplicate chunk pairs, a self-retrieval probe, and the middle-penalty signal.
40
+ - **`/library`** — one-line index summaries per library.
41
+
42
+ ```text
43
+ document ── library_add ─▶ chunk (sliding window) ─▶ embed (hash / external cmd)
44
+
45
+ storage domain (documents / chunks / purges)
46
+
47
+ query ── library_search ─▶ hybrid score ─▶ MMR re-rank ─▶ relevance filter
48
+ │ ─▶ lost-in-middle order
49
+
50
+ result page with [n] markers ── inject: true ─▶ agent + library/inject event
51
+ ```
52
+
53
+ ## Quick start
54
+
55
+ ```sh
56
+ # 1. install the bundle into your profile
57
+ dsh plugin --profile web add "github:PerryLink/dsh-library#main"
58
+
59
+ # or from npm (published releases)
60
+ dsh plugin --profile web add dsh-library
61
+
62
+ # 2. restart and verify the row
63
+ dsh --profile web --dump-config | grep -A2 'id: dsh-library'
64
+ ```
65
+
66
+ Then ask the agent to import and use a document:
67
+
68
+ ```
69
+ > Add ./docs/spec.md to library docs, then answer: what does the spec say about retries? Cite [n] markers.
70
+ ```
71
+
72
+ ## Install & uninstall
73
+
74
+ - **git channel** (latest `main`): `dsh plugin --profile web add "github:PerryLink/dsh-library#main"` — the `prepare` script builds with production dependencies only.
75
+ - **npm channel** (published releases): `dsh plugin --profile web add dsh-library`.
76
+ - **tarball channel**: `pnpm pack` in this repo, then `dsh plugin --profile web add ./dsh-library-<version>.tgz`.
77
+ - **uninstall**: `dsh plugin --profile web remove dsh-library` (or remove the row from the profile patch).
78
+
79
+ > If pnpm reports `ERR_PNPM_IGNORED_BUILDS` for this package (esbuild's harmless platform-binary validation), add `allowBuilds: { esbuild: true }` to your `pnpm-workspace.yaml` — the `dsh` CLI prints the exact snippet.
80
+
81
+ ## Configuration
82
+
83
+ All tunables are Schemastery `Config` fields (changeable from cordis.yml). An id-targeted override replaces the whole row — restate every key you need. `cordis.patch.yml` documents each key inline.
84
+
85
+ | Key | Default | Meaning |
86
+ |---|---|---|
87
+ | `chunkSize` | `900` | Sliding-window chunk size in characters (≤ 4000) |
88
+ | `chunkOverlap` | `120` | Overlap between consecutive windows; must be smaller than `chunkSize` |
89
+ | `maxFileBytes` | `5242880` | Files larger than this are rejected on `library_add` |
90
+ | `embedding.dims` | `256` | Hash-embedding dimensionality (≥ 8) |
91
+ | `embedding.command` | `''` | Optional external embedder command (space-separated argv, no shell) over `ctx.subprocess`; `''` = built-in hash embedder |
92
+ | `embedding.timeoutMs` / `graceMs` / `maxOutputBytes` / `maxBatchItems` | `30000` / `1000` / `1048576` / `64` | Embedder subprocess budget |
93
+ | `search.topK` | `8` | Results returned after the full pipeline |
94
+ | `search.hybridWeight` | `0.6` | 0 = keyword-only, 1 = semantic-only |
95
+ | `search.minRelevance` | `0.15` | Chunks below this relevance threshold are filtered out |
96
+ | `search.diversityLambda` | `0.5` | MMR trade-off: 1 = pure relevance, 0 = pure diversity |
97
+ | `search.lostMiddleHead` / `lostMiddleTail` | `1` / `1` | Strongest chunks pinned to head / tail |
98
+ | `search.maxResultChars` | `16000` | Character budget of the model-facing result page |
99
+ | `injection.enabled` / `maxChars` | `true` / `12000` | `library_search` inject behavior and budget |
100
+ | `citation.windowChars` / `minScore` / `minSemantic` | `150` / `40` / `0.1` | `library_cite_check` thresholds |
101
+ | `purge.signatureLength` / `maxProbes` | `4` / `24` | Purge verification signatures and probe budget |
102
+ | `diagnose.maxDuplicatePairs` / `sampleCap` / `positionBins` | `24` / `200` / `5` | `library_diagnose` budget caps |
103
+
104
+ ## Tools & surfaces
105
+
106
+ | Tool | Notes |
107
+ |---|---|
108
+ | `library_add` | `{ path, library, name? }` → document id; file read through the harness filesystem service |
109
+ | `library_remove` | `{ library, documentId }` → removal summary + purge verdict (residue reported) |
110
+ | `library_list` | `{ library? }` → document metadata (never text) |
111
+ | `library_search` | `{ query, library, topK?, inject? }` → ranked hits with `[n]` markers; `inject: true` seeds the calling agent |
112
+ | `library_cite_check` | `{ library, query, answer }` → per-citation valid/invalid verdicts (fuzzy + semantic) |
113
+ | `library_diagnose` | `{ library }` → chunk stats, duplicates, self-retrieval, middle penalty |
114
+ | `/library [name]` | Command: per-library document/chunk summaries |
115
+
116
+ ## Permissions & data
117
+
118
+ - **Permissions**: the plugin only reads files you point `library_add` at (through the harness filesystem service and its policy) and writes into its own `dsh_library` storage domain. No network requests; an optional external embedder runs through `ctx.subprocess` without shell interpretation.
119
+ - **Data**: chunk text and embeddings live in the host's storage backend (same trust as the deployment's other durable data); the plugin adds no encryption. Document paths and embeddings never enter the session log.
120
+ - **Session log**: `library/inject` (id, query, chunk ids, page size) and `library/purge` (verdict) are log-only audit events — the model-visible injected page is reconstructable from them.
121
+
122
+ ## Security boundaries
123
+
124
+ - **Local by default.** Zero model downloads, zero network calls — scoring is deterministic hashing and token math. Only an explicitly configured embedder command runs code, and its protocol is completeness-checked and output-capped.
125
+ - **No fabrication.** Citation checks report what the pipeline can verify; failed repairs and suspicious citations are surfaced honestly, never guessed.
126
+ - **Purge is verified.** `library_remove` probes the remaining index with deterministic signatures of the removed content and reports residue instead of assuming success.
127
+ - **Fail loud.** Invalid library names, oversized documents, unreadable files, and a configured-but-absent embedder seam all fail the call with a clear error.
128
+
129
+ ## Known limitations
130
+
131
+ - **Lexical-grade embeddings.** The built-in hash embedder scores surface similarity, not meaning; retrieval quality on paraphrases is lower than a real embedding model — configure `embedding.command` for stronger semantics.
132
+ - **Local citation model.** `library_cite_check` validates against the search result page (the `[n]` numbering), not against free-form source names; the fuzzy score is a bounded token-sequence partial ratio.
133
+ - **No ingestion pipeline.** Documents must be imported by path (`md`/`txt`); PDF/docx extraction is out of scope for v0.1.0.
134
+
135
+ ## Development
136
+
137
+ ```sh
138
+ pnpm install # node ^22.19 || >=24
139
+ pnpm run typecheck # tsc: src + tests against the local harness checkout
140
+ pnpm run typecheck:ci # tsc against the published 0.1.0-rc.6 types (no paths)
141
+ pnpm test # vitest: quality ports, core vocabulary, real-stack assembly
142
+ pnpm run build # tsdown bundle + tsc declarations (lib/)
143
+ pnpm run verify:self-contained # dependency specs resolve from the registry
144
+ pnpm run verify:artifacts # built ESM face + bundle patch present
145
+ pnpm pack # the published tarball
146
+ ```
147
+
148
+ ## Topics
149
+
150
+ `dsh`, `dsh-plugin`, `deepseek-harness`, `deepseek`, `cordis`, `rag`, `knowledge-base`, `retrieval`, `embedding`, `vector-search`, `citation-validation`, `document-library`
151
+
152
+ ## Contributors
153
+
154
+ - [@PerryLink](https://github.com/PerryLink) — creator and maintainer: the eight quality ports, storage-domain index, hybrid retrieval pipeline, citation/purge verification, and the five-language docs.
155
+
156
+ ## License
157
+
158
+ [Apache License 2.0](LICENSE) © 2026 dsh-library contributors
package/README.pt.md ADDED
@@ -0,0 +1,158 @@
1
+ <div align="center">
2
+
3
+ # 📚 dsh-library
4
+
5
+ **Base de conhecimento local de documentos para o DeepSeek Harness.**
6
+
7
+ *Importe, recupere, verifique — busca híbrida com citações que seu agente pode conferir.*
8
+
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-library/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-library/actions)
13
+ [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-library?label=version)](https://github.com/PerryLink/dsh-library/releases)
14
+ [![npm version](https://img.shields.io/npm/v/dsh-library)](https://www.npmjs.com/package/dsh-library)
15
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-library)](https://www.npmjs.com/package/dsh-library)
16
+
17
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
18
+
19
+ </div>
20
+
21
+ ---
22
+
23
+ ## Compatibilidade
24
+
25
+ | Superfície | Status |
26
+ |---|---|
27
+ | Harness | DeepSeek Harness `0.1.0-rc.6` (compatibilidade declarada para `0.1.0-rc.5`–`0.1.0-rc.6`) |
28
+ | Node | `^22.19.0 \|\| >=24.0.0` |
29
+ | Armazenamento | Qualquer backend de storage-domain (JSON ou SQLite); o índice vive no domínio de armazenamento do host |
30
+ | Modelos | Nenhum necessário — o embedder integrado é hash determinístico (zero downloads) |
31
+
32
+ ## O que você ganha
33
+
34
+ O `dsh-library` transforma documentos md/txt locais em uma base de conhecimento consultável com um pipeline de qualidade em que seu agente pode confiar:
35
+
36
+ - **`library_add` / `library_remove` / `library_list`** — importa um documento por caminho (dividido em chunks e embutido), remove um com **verificação de expurgo** (assinaturas do conteúdo removido são sondadas contra o índice restante e qualquer resíduo é reportado) e lista os metadados dos documentos.
37
+ - **`library_search`** — ranking híbrido semântico + palavras-chave, re-ranking por diversidade de máxima relevância marginal, filtragem por relevância e **evitação do lost-in-the-middle** (os chunks mais fortes são fixados na cabeça e na cauda). Com `inject: true` a página de resultados é injetada no agente chamador; cada resultado carrega um marcador `[n]` e a injeção é reconstruível a partir do evento de sessão `library/inject`.
38
+ - **`library_cite_check`** — verifica as citações `[n]` de uma resposta contra a página de resultados com correspondência difusa de tokens E uma checagem de similaridade semântica.
39
+ - **`library_diagnose`** — histograma de tamanhos de chunk, pares de chunks quase duplicados, uma sonda de auto-recuperação e o sinal de penalidade do meio.
40
+ - **`/library`** — resumos do índice por biblioteca em uma linha.
41
+
42
+ ```text
43
+ documento ── library_add ─▶ chunk (janela deslizante) ─▶ embed (hash / comando externo)
44
+
45
+ domínio de armazenamento (documents / chunks / purges)
46
+
47
+ consulta ── library_search ─▶ pontuação híbrida ─▶ re-rank MMR ─▶ filtro de relevância
48
+ │ ─▶ ordem lost-in-middle
49
+
50
+ página de resultados com marcadores [n] ── inject: true ─▶ agente + evento library/inject
51
+ ```
52
+
53
+ ## Início rápido
54
+
55
+ ```sh
56
+ # 1. instale o bundle no seu perfil
57
+ dsh plugin --profile web add "github:PerryLink/dsh-library#main"
58
+
59
+ # ou pelo npm (versões publicadas)
60
+ dsh plugin --profile web add dsh-library
61
+
62
+ # 2. reinicie e verifique a linha
63
+ dsh --profile web --dump-config | grep -A2 'id: dsh-library'
64
+ ```
65
+
66
+ Depois peça ao agente para importar e usar um documento:
67
+
68
+ ```
69
+ > Adicione ./docs/spec.md à biblioteca docs e responda: o que a spec diz sobre retries? Cite com marcadores [n].
70
+ ```
71
+
72
+ ## Instalação e desinstalação
73
+
74
+ - **Canal git** (último `main`): `dsh plugin --profile web add "github:PerryLink/dsh-library#main"` — o script `prepare` compila apenas com dependências de produção.
75
+ - **Canal npm** (versões publicadas): `dsh plugin --profile web add dsh-library`.
76
+ - **Canal tarball**: `pnpm pack` neste repositório e então `dsh plugin --profile web add ./dsh-library-<version>.tgz`.
77
+ - **Desinstalar**: `dsh plugin --profile web remove dsh-library` (ou remova a linha do patch do perfil).
78
+
79
+ > Se o pnpm reportar `ERR_PNPM_IGNORED_BUILDS` para este pacote (a validação inofensiva do binário do esbuild), adicione `allowBuilds: { esbuild: true }` ao seu `pnpm-workspace.yaml` — o CLI `dsh` imprime o trecho exato.
80
+
81
+ ## Configuração
82
+
83
+ Todos os ajustes são campos `Config` do Schemastery (alteráveis pelo cordis.yml). Uma sobrescrita direcionada por id substitui a linha inteira — redeclare cada chave que precisar. O `cordis.patch.yml` documenta cada chave em linha.
84
+
85
+ | Chave | Padrão | Significado |
86
+ |---|---|---|
87
+ | `chunkSize` | `900` | Tamanho do chunk em caracteres (janela deslizante, ≤ 4000) |
88
+ | `chunkOverlap` | `120` | Sobreposição entre janelas; deve ser menor que `chunkSize` |
89
+ | `maxFileBytes` | `5242880` | Arquivos maiores são rejeitados no `library_add` |
90
+ | `embedding.dims` | `256` | Dimensionalidade do hash embedding (≥ 8) |
91
+ | `embedding.command` | `''` | Comando de embedder externo opcional (argv separado por espaços, sem shell) via `ctx.subprocess`; `''` = embedder hash integrado |
92
+ | `embedding.timeoutMs` / `graceMs` / `maxOutputBytes` / `maxBatchItems` | `30000` / `1000` / `1048576` / `64` | Orçamento do subprocesso do embedder |
93
+ | `search.topK` | `8` | Resultados devolvidos após o pipeline completo |
94
+ | `search.hybridWeight` | `0.6` | 0 = só palavras-chave, 1 = só semântica |
95
+ | `search.minRelevance` | `0.15` | Chunks abaixo deste limiar de relevância são filtrados |
96
+ | `search.diversityLambda` | `0.5` | Compensação MMR: 1 = relevância pura, 0 = diversidade pura |
97
+ | `search.lostMiddleHead` / `lostMiddleTail` | `1` / `1` | Chunks mais fortes fixados na cabeça / cauda |
98
+ | `search.maxResultChars` | `16000` | Orçamento de caracteres da página de resultados |
99
+ | `injection.enabled` / `maxChars` | `true` / `12000` | Comportamento e orçamento de injeção do `library_search` |
100
+ | `citation.windowChars` / `minScore` / `minSemantic` | `150` / `40` / `0.1` | Limiares do `library_cite_check` |
101
+ | `purge.signatureLength` / `maxProbes` | `4` / `24` | Assinaturas e orçamento de sondas da verificação de expurgo |
102
+ | `diagnose.maxDuplicatePairs` / `sampleCap` / `positionBins` | `24` / `200` / `5` | Limites do `library_diagnose` |
103
+
104
+ ## Ferramentas e superfícies
105
+
106
+ | Ferramenta | Notas |
107
+ |---|---|
108
+ | `library_add` | `{ path, library, name? }` → id do documento; leitura pelo serviço de arquivos do harness |
109
+ | `library_remove` | `{ library, documentId }` → resumo da remoção + veredicto de expurgo (resíduo reportado) |
110
+ | `library_list` | `{ library? }` → metadados dos documentos (nunca texto) |
111
+ | `library_search` | `{ query, library, topK?, inject? }` → resultados ordenados com marcadores `[n]`; `inject: true` semeia o agente chamador |
112
+ | `library_cite_check` | `{ library, query, answer }` → veredictos por citação válida/inválida (difuso + semântico) |
113
+ | `library_diagnose` | `{ library }` → estatísticas de chunks, duplicados, auto-recuperação, penalidade do meio |
114
+ | `/library [name]` | Comando: resumos de documentos/chunks por biblioteca |
115
+
116
+ ## Permissões e dados
117
+
118
+ - **Permissões**: o plugin só lê os arquivos apontados pelo `library_add` (pelo serviço de arquivos do harness e sua política) e escreve no seu próprio domínio de armazenamento `dsh_library`. Sem requisições de rede; um embedder externo opcional executa via `ctx.subprocess` sem interpretação de shell.
119
+ - **Dados**: o texto dos chunks e os embeddings vivem no backend de armazenamento do host (a mesma confiança do restante dos dados duráveis da implantação); o plugin não adiciona criptografia. Caminhos de documentos e embeddings nunca entram no registro de sessão.
120
+ - **Registro de sessão**: `library/inject` (id, consulta, ids de chunks, tamanho da página) e `library/purge` (veredicto) são eventos de auditoria somente-registro — a página injetada visível ao modelo é reconstruível a partir deles.
121
+
122
+ ## Limites de segurança
123
+
124
+ - **Local por padrão.** Zero downloads de modelos, zero chamadas de rede — a pontuação é hash determinístico e matemática de tokens. Apenas um comando de embedder configurado explicitamente executa código, e seu protocolo é verificado por completude e limitado em saída.
125
+ - **Sem fabricação.** As checagens de citações informam o que o pipeline pode verificar; citações suspeitas são exibidas com honestidade, nunca adivinhadas.
126
+ - **O expurgo é verificado.** O `library_remove` sonda o índice restante com assinaturas determinísticas do conteúdo removido e reporta o resíduo em vez de assumir sucesso.
127
+ - **Falha ruidosa.** Nomes de biblioteca inválidos, documentos grandes demais, arquivos ilegíveis e um seam de embedder configurado mas ausente falham com erro claro.
128
+
129
+ ## Limitações conhecidas
130
+
131
+ - **Embeddings de grau léxico.** O embedder hash integrado pontua similaridade superficial, não significado; a qualidade de recuperação em paráfrases é menor que com um modelo real — configure `embedding.command` para semântica mais forte.
132
+ - **Modelo de citação local.** O `library_cite_check` valida contra a página de resultados (a numeração `[n]`), não contra nomes de fonte livres; a pontuação difusa é uma razão parcial de sequências de tokens limitada.
133
+ - **Sem pipeline de ingestão.** Os documentos devem ser importados por caminho (`md`/`txt`); a extração de PDF/docx fica fora da v0.1.0.
134
+
135
+ ## Desenvolvimento
136
+
137
+ ```sh
138
+ pnpm install # node ^22.19 || >=24
139
+ pnpm run typecheck # tsc: src + tests contra o checkout local do harness
140
+ pnpm run typecheck:ci # tsc contra os tipos publicados 0.1.0-rc.6 (sem paths)
141
+ pnpm test # vitest: portas de qualidade, vocabulário núcleo, montagem com pilha real
142
+ pnpm run build # bundle tsdown + declarações tsc (lib/)
143
+ pnpm run verify:self-contained # especificações de dependências resolvem pelo registry
144
+ pnpm run verify:artifacts # face ESM construída + bundle patch presente
145
+ pnpm pack # o tarball publicado
146
+ ```
147
+
148
+ ## Topics
149
+
150
+ `dsh`, `dsh-plugin`, `deepseek-harness`, `deepseek`, `cordis`, `rag`, `knowledge-base`, `retrieval`, `embedding`, `vector-search`, `citation-validation`, `document-library`
151
+
152
+ ## Contributors
153
+
154
+ - [@PerryLink](https://github.com/PerryLink) — criador e mantenedor: os oito portes de qualidade, o índice de domínio de armazenamento, o pipeline de recuperação híbrido, a verificação de citações/expurgo e a documentação em cinco idiomas.
155
+
156
+ ## License
157
+
158
+ [Apache License 2.0](LICENSE) © 2026 dsh-library contributors
package/README.zh.md ADDED
@@ -0,0 +1,158 @@
1
+ <div align="center">
2
+
3
+ # 📚 dsh-library
4
+
5
+ **DeepSeek Harness 的本地文档知识库。**
6
+
7
+ *导入、检索、核验 —— 带引用标记的混合检索,agent 可以自证引用。*
8
+
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-library/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-library/actions)
13
+ [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-library?label=version)](https://github.com/PerryLink/dsh-library/releases)
14
+ [![npm version](https://img.shields.io/npm/v/dsh-library)](https://www.npmjs.com/package/dsh-library)
15
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-library)](https://www.npmjs.com/package/dsh-library)
16
+
17
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
18
+
19
+ </div>
20
+
21
+ ---
22
+
23
+ ## 兼容性
24
+
25
+ | 方面 | 状态 |
26
+ |---|---|
27
+ | Harness | DeepSeek Harness `0.1.0-rc.6`(声明兼容 `0.1.0-rc.5`–`0.1.0-rc.6`) |
28
+ | Node | `^22.19.0 \|\| >=24.0.0` |
29
+ | 存储 | 任意 storage-domain 后端(JSON 或 SQLite);索引存放在宿主的存储域中 |
30
+ | 模型 | 无需任何模型 —— 内置嵌入为确定性哈希(零下载) |
31
+
32
+ ## 你能得到什么
33
+
34
+ `dsh-library` 把本地 md/txt 文档变成可查询的知识库,并带一套 agent 可信任的质量管线:
35
+
36
+ - **`library_add` / `library_remove` / `library_list`** —— 按路径导入文档(分块 + 嵌入)、删除文档并做**清除验证**(用被删内容的签名探测剩余索引,残留即报告)、列出文档元数据。
37
+ - **`library_search`** —— 语义 + 关键词混合排序、最大边际相关多样性重排、相关性过滤与**中段丢失规避**(最强切片钉在首尾)。`inject: true` 时结果页注入调用 agent;每条命中带 `[n]` 来源标记,注入可从 `library/inject` 会话事件重建。
38
+ - **`library_cite_check`** —— 用模糊词面匹配 + 语义相似度双重校验答案中的 `[n]` 引用。
39
+ - **`library_diagnose`** —— 切片大小直方图、近似重复切片对、自检索探针与中段惩罚信号。
40
+ - **`/library`** —— 每个知识库一行索引摘要。
41
+
42
+ ```text
43
+ 文档 ── library_add ─▶ 切片(滑窗) ─▶ 嵌入(哈希 / 外部命令)
44
+
45
+ 存储域(documents / chunks / purges)
46
+
47
+ 查询 ── library_search ─▶ 混合打分 ─▶ MMR 重排 ─▶ 相关性过滤
48
+ │ ─▶ 中段规避排序
49
+
50
+ 带 [n] 标记的结果页 ── inject: true ─▶ agent + library/inject 事件
51
+ ```
52
+
53
+ ## 快速开始
54
+
55
+ ```sh
56
+ # 1. 把 bundle 装进你的 profile
57
+ dsh plugin --profile web add "github:PerryLink/dsh-library#main"
58
+
59
+ # 或从 npm 安装(正式发布版)
60
+ dsh plugin --profile web add dsh-library
61
+
62
+ # 2. 重启并核实行
63
+ dsh --profile web --dump-config | grep -A2 'id: dsh-library'
64
+ ```
65
+
66
+ 然后让 agent 导入并使用文档:
67
+
68
+ ```
69
+ > 把 ./docs/spec.md 加入 docs 知识库,然后回答:规范里关于重试是怎么说的?用 [n] 标记引用。
70
+ ```
71
+
72
+ ## 安装与卸载
73
+
74
+ - **git 通道**(最新 `main`):`dsh plugin --profile web add "github:PerryLink/dsh-library#main"` —— `prepare` 脚本仅用生产依赖构建。
75
+ - **npm 通道**(正式发布版):`dsh plugin --profile web add dsh-library`。
76
+ - **tarball 通道**:在本仓库执行 `pnpm pack`,然后 `dsh plugin --profile web add ./dsh-library-<version>.tgz`。
77
+ - **卸载**:`dsh plugin --profile web remove dsh-library`(或从 profile patch 中删除该行)。
78
+
79
+ > 如果 pnpm 对本包报 `ERR_PNPM_IGNORED_BUILDS`(esbuild 的平台二进制无害校验),在你的 `pnpm-workspace.yaml` 中加入 `allowBuilds: { esbuild: true }` —— `dsh` CLI 会打印确切片段。
80
+
81
+ ## 配置
82
+
83
+ 所有可调项都是 Schemastery `Config` 字段(可在 cordis.yml 中修改)。按 id 定向覆盖会替换整行 —— 需要重新声明每个键。`cordis.patch.yml` 内联说明了每个键。
84
+
85
+ | 键 | 默认值 | 含义 |
86
+ |---|---|---|
87
+ | `chunkSize` | `900` | 滑窗切片大小(字符,≤ 4000) |
88
+ | `chunkOverlap` | `120` | 相邻窗口重叠;必须小于 `chunkSize` |
89
+ | `maxFileBytes` | `5242880` | 超过该大小的文件在 `library_add` 被拒绝 |
90
+ | `embedding.dims` | `256` | 哈希嵌入维度(≥ 8) |
91
+ | `embedding.command` | `''` | 可选外部嵌入命令(空格分隔 argv、无 shell)走 `ctx.subprocess`;`''` = 内置哈希嵌入 |
92
+ | `embedding.timeoutMs` / `graceMs` / `maxOutputBytes` / `maxBatchItems` | `30000` / `1000` / `1048576` / `64` | 嵌入子进程预算 |
93
+ | `search.topK` | `8` | 完整管线后返回的结果数 |
94
+ | `search.hybridWeight` | `0.6` | 0 = 仅关键词,1 = 仅语义 |
95
+ | `search.minRelevance` | `0.15` | 低于该相关性阈值的切片被过滤 |
96
+ | `search.diversityLambda` | `0.5` | MMR 权衡:1 = 纯相关,0 = 纯多样 |
97
+ | `search.lostMiddleHead` / `lostMiddleTail` | `1` / `1` | 最强切片钉在首 / 尾 |
98
+ | `search.maxResultChars` | `16000` | 模型可见结果页字符预算 |
99
+ | `injection.enabled` / `maxChars` | `true` / `12000` | `library_search` 注入行为与预算 |
100
+ | `citation.windowChars` / `minScore` / `minSemantic` | `150` / `40` / `0.1` | `library_cite_check` 阈值 |
101
+ | `purge.signatureLength` / `maxProbes` | `4` / `24` | 清除验证签名与探测预算 |
102
+ | `diagnose.maxDuplicatePairs` / `sampleCap` / `positionBins` | `24` / `200` / `5` | `library_diagnose` 预算上限 |
103
+
104
+ ## 工具与界面
105
+
106
+ | 工具 | 说明 |
107
+ |---|---|
108
+ | `library_add` | `{ path, library, name? }` → 文档 id;文件经 harness 文件系统服务读取 |
109
+ | `library_remove` | `{ library, documentId }` → 删除摘要 + 清除判定(残留即报告) |
110
+ | `library_list` | `{ library? }` → 文档元数据(绝不含正文) |
111
+ | `library_search` | `{ query, library, topK?, inject? }` → 带 `[n]` 标记的排序命中;`inject: true` 注入调用 agent |
112
+ | `library_cite_check` | `{ library, query, answer }` → 逐条引用有效/无效判定(模糊 + 语义) |
113
+ | `library_diagnose` | `{ library }` → 切片统计、重复、自检索、中段惩罚 |
114
+ | `/library [name]` | 命令:每个知识库的文档/切片摘要 |
115
+
116
+ ## 权限与数据
117
+
118
+ - **权限**:插件只读取你让 `library_add` 指向的文件(经 harness 文件系统服务及其策略),并只写入自己的 `dsh_library` 存储域。无网络请求;可选外部嵌入命令经 `ctx.subprocess` 执行、无 shell 解释。
119
+ - **数据**:切片文本与嵌入存放在宿主的存储后端(与部署的其他持久数据同级信任);插件不额外加密。文档路径与嵌入向量绝不进入会话日志。
120
+ - **会话日志**:`library/inject`(id、查询、切片 id、页大小)与 `library/purge`(判定)是仅日志审计事件 —— 模型可见的注入页可从中重建。
121
+
122
+ ## 安全边界
123
+
124
+ - **默认本地。** 零模型下载、零网络调用 —— 打分是确定性哈希与词法数学。只有显式配置的嵌入命令会执行代码,且其协议做完整性检查与输出上限。
125
+ - **不伪造。** 引用检查只报告管线能验证的结论;可疑引用如实呈现,绝不猜测。
126
+ - **清除即验证。** `library_remove` 用被删内容的确定性签名探测剩余索引并报告残留,而不是假定成功。
127
+ - **失败大声。** 非法知识库名、超大文档、不可读文件、配置了却缺失的嵌入接缝,都以明确错误失败。
128
+
129
+ ## 已知限制
130
+
131
+ - **词法级嵌入。** 内置哈希嵌入打分的是表面相似而非语义;对改写表达的检索质量低于真实嵌入模型 —— 配置 `embedding.command` 可获得更强语义。
132
+ - **本地引用模型。** `library_cite_check` 针对搜索结果页(`[n]` 编号)验证,不支持自由形式的来源名;模糊分数是有界的词序列部分匹配率。
133
+ - **无摄取管线。** 文档须按路径导入(`md`/`txt`);PDF/docx 抽取不在 v0.1.0 范围。
134
+
135
+ ## 开发
136
+
137
+ ```sh
138
+ pnpm install # node ^22.19 || >=24
139
+ pnpm run typecheck # tsc:src + tests 对照本地 harness checkout
140
+ pnpm run typecheck:ci # tsc:对照已发布的 0.1.0-rc.6 类型(无 paths)
141
+ pnpm test # vitest:八移植回归、核心词汇、真实栈装配
142
+ pnpm run build # tsdown bundle + tsc 声明(lib/)
143
+ pnpm run verify:self-contained # 依赖声明全部来自 registry
144
+ pnpm run verify:artifacts # 构建产物 ESM 面 + bundle patch 齐全
145
+ pnpm pack # 发布用 tarball
146
+ ```
147
+
148
+ ## Topics
149
+
150
+ `dsh`, `dsh-plugin`, `deepseek-harness`, `deepseek`, `cordis`, `rag`, `knowledge-base`, `retrieval`, `embedding`, `vector-search`, `citation-validation`, `document-library`
151
+
152
+ ## Contributors
153
+
154
+ - [@PerryLink](https://github.com/PerryLink) —— 创建者与维护者:八项质量移植、存储域索引、混合检索管线、引用/清除验证与五语文档。
155
+
156
+ ## License
157
+
158
+ [Apache License 2.0](LICENSE) © 2026 dsh-library contributors
package/SECURITY.md ADDED
@@ -0,0 +1,38 @@
1
+ # Security policy
2
+
3
+ ## Reporting a vulnerability
4
+
5
+ Please **do not** open a public issue for security vulnerabilities.
6
+
7
+ Report privately through GitHub's private vulnerability reporting:
8
+
9
+ **https://github.com/PerryLink/dsh-library/security/advisories/new**
10
+
11
+ That flow keeps the report confidential while we triage, and it is the channel we watch first.
12
+
13
+ ## Before you report
14
+
15
+ - **Redact sensitive data** from any logs, indexed documents, or session excerpts you attach: tokens, API keys, secrets, Authorization/request headers, personal paths, and account identifiers. Trimmed stack traces are usually enough.
16
+ - Include, when possible: the plugin version, the harness (`dsh`) version, Node and OS versions, and the minimal steps to reproduce.
17
+
18
+ ## What to expect
19
+
20
+ - **Acknowledgment**: within 5 business days.
21
+ - **Triage**: within 10 business days we confirm the issue and assess severity, or ask for more details.
22
+ - **Fix**: security fixes are prepared in a private fork, released as a patch version, and announced in the release notes.
23
+
24
+ ## Disclosure and credit
25
+
26
+ - We follow coordinated disclosure: a public advisory (and CVE request where appropriate) is published once a fix ships.
27
+ - Reporters are credited in the advisory unless they ask to remain anonymous. There is no bug bounty program at this time.
28
+
29
+ ## Scope
30
+
31
+ This plugin builds a local document index: it reads files you point it at through the harness filesystem service, stores chunk text and embeddings in the host's storage domain, and injects retrieved text into the calling agent. Its own guarantees:
32
+
33
+ - Document paths and embedding vectors are never written to the session log; only chunk ids and lengths appear in audit events.
34
+ - Retrieval and citation checks are deterministic local computations — the plugin makes no network requests and downloads no models unless you configure an external embedder command.
35
+ - The configured embedder command runs through `ctx.subprocess` without shell interpretation, bounded by timeout and output caps; a misbehaving command fails the batch loudly.
36
+ - Indexed documents inherit the deployment's storage backend access control; the plugin itself adds no encryption — treat the index medium as sensitive when the documents are.
37
+
38
+ Vulnerabilities in the harness itself should be reported to the official harness maintainers instead.
@@ -0,0 +1,27 @@
1
+ # Third-party notices
2
+
3
+ `src/quality/` ports eight upstream projects by the same author (PerryLink,
4
+ Apache-2.0 each, as verified in their `upstream/<name>/LICENSE` files). The
5
+ port keeps the upstream algorithm and vocabulary but replaces every
6
+ model-download dependency with local-rules equivalents — no upstream code is
7
+ bundled verbatim, and no model or index binary ships with this package.
8
+
9
+ | Upstream project | Ported into | Substitution |
10
+ |---|---|---|
11
+ | Few-Shot-Selector | `src/quality/few-shot.ts` | ChromaDB + SentenceTransformer → deterministic hash embedding |
12
+ | Context-Relevance-Scorer | `src/quality/relevance.ts` | cross-encoder model → weighted token-overlap scorer |
13
+ | Lost-in-Middle-Tester | `src/quality/lost-middle.ts` | probe LLM trials → deterministic position strategy + bin report |
14
+ | RAG-Reference-Checker | `src/quality/reference.ts` | SentenceTransformer (`download_model.py`) → hash embedding |
15
+ | RAG-Chunk-Visualizer | `src/quality/chunk-visual.ts` | pure sliding-window chunking + diagnostics |
16
+ | Retrieval-Diversity-Check | `src/quality/diversity.ts` | numpy/sklearn TF-IDF → shared token vocabulary |
17
+ | Citation-Validator-Lite | `src/quality/citation.ts` | `fuzzywuzzy.partial_ratio` → bounded token-sequence partial ratio |
18
+ | RAG-Purge-Verify | `src/quality/purge.ts` | vector-store engine probes → token n-gram signature probes |
19
+
20
+ The upstream sources remain in `upstream/` for reference only: the directory
21
+ is gitignored and excluded from the published package.
22
+
23
+ Runtime dependencies (peerDependencies) are the official
24
+ `@deepseek-ai/dsh-*` packages; build-time dependencies are `typescript` and
25
+ `tsdown` (regular dependencies so the git-install channel's `prepare` can
26
+ build), and `zod` (the storage-domain record schemas). The plugin performs no
27
+ network requests of its own and downloads nothing at install or run time.
@@ -0,0 +1,79 @@
1
+ # dsh-library bundle patch: mount the local knowledge-base plugin.
2
+ #
3
+ # Every key below is a Config field (Schemastery schema); invalid values fail
4
+ # the profile load loudly. See README.md "Configuration" for the full table.
5
+ - insert:
6
+ - id: dsh-library
7
+ name: dsh-library
8
+ config:
9
+ # Sliding-window chunk size in characters (chunks are the retrieval
10
+ # unit). Must not exceed 4000.
11
+ chunkSize: 900
12
+ # Sliding-window overlap in characters; must be smaller than
13
+ # chunkSize so consecutive windows share context.
14
+ chunkOverlap: 120
15
+ # Files larger than this (UTF-8 bytes) are rejected on library_add.
16
+ maxFileBytes: 5242880
17
+ embedding:
18
+ # Hash-embedding dimensionality (built-in embedder; >= 8). Larger
19
+ # values trade memory for fewer bucket collisions.
20
+ dims: 256
21
+ # Optional external embedder command (space-separated argv, NO shell
22
+ # interpretation) executed through ctx.subprocess: reads one
23
+ # {"index":n,"text":"..."} JSON object per stdin line and writes one
24
+ # {"index":n,"vector":[...]} JSON object per stdout line. Leave
25
+ # unset for the built-in deterministic hash embedder (zero downloads).
26
+ command: ''
27
+ # Cooperative timeout for one embedder invocation (ms).
28
+ timeoutMs: 30000
29
+ # Terminate-escalation grace handed to the subprocess seam (ms).
30
+ graceMs: 1000
31
+ # Max bytes of one embedder stdout before the batch fails.
32
+ maxOutputBytes: 1048576
33
+ # Max texts embedded per subprocess invocation; larger batches split.
34
+ maxBatchItems: 64
35
+ search:
36
+ # How many chunks one search returns after the full pipeline.
37
+ topK: 8
38
+ # Hybrid weight: 0 = keyword-only, 1 = semantic-only.
39
+ hybridWeight: 0.6
40
+ # Chunks scoring below this relevance threshold are filtered out.
41
+ minRelevance: 0.15
42
+ # Diversity re-rank weight: 1 = pure relevance, 0 = pure diversity.
43
+ diversityLambda: 0.5
44
+ # Strongest chunks pinned to the head of the context
45
+ # (lost-in-the-middle avoidance).
46
+ lostMiddleHead: 1
47
+ # Next-strongest chunks pinned to the tail of the context.
48
+ lostMiddleTail: 1
49
+ # Character budget for the model-facing result page.
50
+ maxResultChars: 16000
51
+ injection:
52
+ # Whether library_search with inject: true injects into the calling
53
+ # agent (the injected text carries [n] source markers).
54
+ enabled: true
55
+ # Character budget of one injected context message.
56
+ maxChars: 12000
57
+ citation:
58
+ # Context window (chars) around each citation marker that forms the
59
+ # claim in library_cite_check.
60
+ windowChars: 150
61
+ # Minimum fuzzy token-match score (0-100) for a citation to be valid.
62
+ minScore: 40
63
+ # Minimum semantic similarity (0-1) for a citation to be valid.
64
+ minSemantic: 0.1
65
+ purge:
66
+ # Token n-gram width of the removed-content signatures scanned for
67
+ # residue after library_remove.
68
+ signatureLength: 4
69
+ # How many signatures are probed per removal; longer documents
70
+ # sample deterministically.
71
+ maxProbes: 24
72
+ diagnose:
73
+ # Cap on reported near-duplicate chunk pairs in library_diagnose.
74
+ maxDuplicatePairs: 24
75
+ # Chunks sampled into the duplicate scan (the pair check is
76
+ # quadratic).
77
+ sampleCap: 200
78
+ # How many position bins the lost-in-the-middle report uses.
79
+ positionBins: 5