dsh-plugin-wiki-tools 0.2.0 → 0.3.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.
- package/index.js +64 -6
- package/lib/search.js +3 -2
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -76,9 +76,7 @@ export function createTools(vault, options = {}) {
|
|
|
76
76
|
},
|
|
77
77
|
render: (_args, value) => [{
|
|
78
78
|
type: 'text',
|
|
79
|
-
text:
|
|
80
|
-
? `wiki_query: ${value.results.length} of ${value.totalMatches} matching pages`
|
|
81
|
-
: 'wiki_query: returned hot cache and master index',
|
|
79
|
+
text: renderQueryResult(value),
|
|
82
80
|
}],
|
|
83
81
|
},
|
|
84
82
|
async execute(args) {
|
|
@@ -181,9 +179,7 @@ export function createTools(vault, options = {}) {
|
|
|
181
179
|
},
|
|
182
180
|
render: (_args, value) => [{
|
|
183
181
|
type: 'text',
|
|
184
|
-
text:
|
|
185
|
-
? `wiki_lint: ${value.summary.issues} issues across ${value.summary.pagesScanned} pages; report at ${value.reportPath ?? '(not written)'}`
|
|
186
|
-
: 'wiki_lint: failed',
|
|
182
|
+
text: renderLintResult(value),
|
|
187
183
|
}],
|
|
188
184
|
},
|
|
189
185
|
async execute() {
|
|
@@ -195,6 +191,68 @@ export function createTools(vault, options = {}) {
|
|
|
195
191
|
return [wikiQuery, wikiWrite, wikiLint]
|
|
196
192
|
}
|
|
197
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Render a wiki_query result as the model-facing text. The render output is the
|
|
196
|
+
* ONLY content the model sees, so it carries the full payload — hot cache and
|
|
197
|
+
* index verbatim in quick mode, every result with path, snippets, and link
|
|
198
|
+
* context in standard mode — not a summary line.
|
|
199
|
+
* @param {unknown} value - the execute return value.
|
|
200
|
+
* @returns {string} the model-facing result text.
|
|
201
|
+
*/
|
|
202
|
+
function renderQueryResult(value) {
|
|
203
|
+
if (typeof value !== 'object' || value === null) return 'wiki_query: no result'
|
|
204
|
+
const result = value
|
|
205
|
+
if (result.mode === 'quick') {
|
|
206
|
+
const parts = []
|
|
207
|
+
if (typeof result.hot === 'string' && result.hot.length > 0) {
|
|
208
|
+
parts.push(`--- wiki/hot.md (recent context cache) ---\n${capText(result.hot, 6000)}`)
|
|
209
|
+
}
|
|
210
|
+
if (typeof result.index === 'string' && result.index.length > 0) {
|
|
211
|
+
parts.push(`--- wiki/index.md (master catalog) ---\n${capText(result.index, 8000)}`)
|
|
212
|
+
}
|
|
213
|
+
if (parts.length === 0) return 'wiki_query (quick): the vault has no hot.md or index.md yet'
|
|
214
|
+
return `wiki_query (quick): hot cache and master index follow. Read these before any page.\n\n${parts.join('\n\n')}`
|
|
215
|
+
}
|
|
216
|
+
if (!Array.isArray(result.results)) return 'wiki_query: no result'
|
|
217
|
+
const lines = [`wiki_query: ${result.results.length} of ${result.totalMatches} matching pages. Open a page with the fs read tool for full content.`]
|
|
218
|
+
for (const hit of result.results) {
|
|
219
|
+
lines.push(`\n### ${hit.name}`)
|
|
220
|
+
lines.push(`path: ${hit.path} · score ${hit.score} · inbound ${hit.inbound.length}${hit.inbound.length > 0 ? ` (${hit.inbound.slice(0, 5).join(', ')})` : ''} · outbound ${hit.outbound}`)
|
|
221
|
+
for (const snippet of hit.snippets) lines.push(`> ${snippet}`)
|
|
222
|
+
}
|
|
223
|
+
return capText(lines.join('\n'), 12000)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Render a wiki_lint result: every issue with page, severity, and suggestion.
|
|
228
|
+
* @param {unknown} value - the execute return value.
|
|
229
|
+
* @returns {string} the model-facing result text.
|
|
230
|
+
*/
|
|
231
|
+
function renderLintResult(value) {
|
|
232
|
+
if (typeof value !== 'object' || value === null || !('summary' in value)) return 'wiki_lint: failed'
|
|
233
|
+
const result = value
|
|
234
|
+
const lines = [
|
|
235
|
+
`wiki_lint: ${result.summary.issues} issues across ${result.summary.pagesScanned} pages.`,
|
|
236
|
+
`checks: ${Object.entries(result.summary.byCheck ?? {}).map(([check, count]) => `${check}×${count}`).join(', ') || 'none'}`,
|
|
237
|
+
`full report: ${typeof result.reportPath === 'string' ? result.reportPath : '(not written)'}`,
|
|
238
|
+
]
|
|
239
|
+
for (const issue of (result.issues ?? []).slice(0, 60)) {
|
|
240
|
+
lines.push(`- [${issue.severity}] ${issue.check} · ${issue.page}: ${issue.detail} → ${issue.suggestion}`)
|
|
241
|
+
}
|
|
242
|
+
if ((result.issues ?? []).length > 60) lines.push(`… and ${result.issues.length - 60} more (see the report file)`)
|
|
243
|
+
return lines.join('\n')
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Cap one text block, marking the cut.
|
|
248
|
+
* @param {string} text - full text.
|
|
249
|
+
* @param {number} max - maximum characters kept.
|
|
250
|
+
* @returns {string} the capped text.
|
|
251
|
+
*/
|
|
252
|
+
function capText(text, max) {
|
|
253
|
+
return text.length <= max ? text : `${text.slice(0, max)}\n… (truncated at ${max} characters)`
|
|
254
|
+
}
|
|
255
|
+
|
|
198
256
|
/**
|
|
199
257
|
* Validate the deployment config and register the three wiki tools.
|
|
200
258
|
* @param {import('@deepseek-ai/cordis').Context} ctx - registrant context carrying the tool registry.
|
package/lib/search.js
CHANGED
|
@@ -45,7 +45,8 @@ export async function searchVault(root, { query, limit = 10 }) {
|
|
|
45
45
|
!META_FILENAMES.has(page.name.toLowerCase()) && !page.name.startsWith('_'))
|
|
46
46
|
const inbound = new Map(pages.map(page => [page.name, []]))
|
|
47
47
|
for (const page of searchable) {
|
|
48
|
-
|
|
48
|
+
// One inbound record per source page, however many times it links.
|
|
49
|
+
for (const target of new Set(page.links)) {
|
|
49
50
|
inbound.get(target)?.push(page.name)
|
|
50
51
|
}
|
|
51
52
|
}
|
|
@@ -68,7 +69,7 @@ export async function searchVault(root, { query, limit = 10 }) {
|
|
|
68
69
|
score,
|
|
69
70
|
snippets: matchLines(page.content, needle).slice(0, 2),
|
|
70
71
|
inbound: inbound.get(page.name) ?? [],
|
|
71
|
-
outbound: page.links.
|
|
72
|
+
outbound: new Set(page.links).size,
|
|
72
73
|
})
|
|
73
74
|
}
|
|
74
75
|
results.sort((left, right) => right.score - left.score || left.name.localeCompare(right.name))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-wiki-tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Native DeepSeek Harness tools for an Obsidian wiki vault: wiki_query, wiki_write, and wiki_lint implement the mechanical core (path routing, delta tracking, index/log bookkeeping, health checks) of the wiki skill suite.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|