dsh-ensp 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/package.json +1 -1
- package/scripts/gen-knowledge.mjs +17 -21
- package/src/core/knowledge.json +1 -2
- package/src/core/knowledge.mjs +7 -8
- package/src/dsh/index.mjs +2 -1
- package/src/mcp/server.mjs +2 -1
package/README.en.md
CHANGED
|
@@ -137,7 +137,7 @@ ensp preset ospf-lsa-types # the detail ends with a knowledge section
|
|
|
137
137
|
ensp preset --knowledge LSA # search the index by keyword
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
-
The points
|
|
140
|
+
The points are grouped by topic by hand: each one is a checkable statement rather than a copied entry. The index keeps only the stem and the correct option text; the source material is not shipped.
|
|
141
141
|
|
|
142
142
|
### Device image check
|
|
143
143
|
|
package/README.md
CHANGED
|
@@ -132,7 +132,7 @@ ensp preset ospf-lsa-types # 详情末尾带知识点小节
|
|
|
132
132
|
ensp preset --knowledge LSA # 按关键词检索知识点
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
知识点按主题人工归类:每条是一句可核对的事实,而不是照搬原始条目。索引只保留题干与正确选项文本,原始资料不随包分发。
|
|
136
136
|
|
|
137
137
|
```bash
|
|
138
138
|
npm run docs # 重新生成 docs/SCENARIOS.md
|
package/package.json
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Regenerate `src/core/knowledge.json
|
|
3
|
-
*
|
|
4
|
-
* The bank is not part of this package: it is copyrighted material, and most of
|
|
5
|
-
* its questions are three-sentence reading exercises rather than facts. What the
|
|
6
|
-
* package does ship is the index this script produces, so the transformation has
|
|
7
|
-
* to be reproducible and reviewable by anyone who has the bank.
|
|
2
|
+
* Regenerate `src/core/knowledge.json`.
|
|
8
3
|
*
|
|
9
4
|
* Usage:
|
|
10
|
-
* node scripts/gen-knowledge.mjs <
|
|
5
|
+
* node scripts/gen-knowledge.mjs <source.json>
|
|
11
6
|
*
|
|
12
|
-
* The
|
|
13
|
-
*
|
|
7
|
+
* The source is any array of `{ n, type, stem, options: [{key, text}], answer,
|
|
8
|
+
* analysis, topics }`. It is not part of this package; what ships is the index
|
|
9
|
+
* this script produces, so the transformation has to be reproducible and
|
|
10
|
+
* reviewable by anyone who has the source.
|
|
14
11
|
*
|
|
15
12
|
* Two rules shape the output, and both exist because the obvious version of this
|
|
16
13
|
* script produced a worse index:
|
|
17
14
|
*
|
|
18
|
-
* 1. **One topic per question.**
|
|
15
|
+
* 1. **One topic per question.** Upstream tags are unreliable: a question
|
|
19
16
|
* about OSPF LSA types carries `ospf` and `security` both, and honouring every
|
|
20
17
|
* tag files the same fact under two headings. Score the text against topic
|
|
21
18
|
* keywords and keep the best match.
|
|
@@ -95,12 +92,12 @@ function answerText(q) {
|
|
|
95
92
|
/**
|
|
96
93
|
* Build the index.
|
|
97
94
|
*
|
|
98
|
-
* @param {Array<object>}
|
|
95
|
+
* @param {Array<object>} source
|
|
99
96
|
* @returns {object}
|
|
100
97
|
*/
|
|
101
|
-
export function buildIndex(
|
|
98
|
+
export function buildIndex(source) {
|
|
102
99
|
const perTopic = {}
|
|
103
|
-
for (const q of
|
|
100
|
+
for (const q of source) {
|
|
104
101
|
const answer = answerText(q)
|
|
105
102
|
if (!answer) continue
|
|
106
103
|
const stem = clean(q.stem)
|
|
@@ -137,8 +134,7 @@ export function buildIndex(bank) {
|
|
|
137
134
|
}
|
|
138
135
|
|
|
139
136
|
return {
|
|
140
|
-
|
|
141
|
-
sourceQuestions: bank.length,
|
|
137
|
+
version: 1,
|
|
142
138
|
topics,
|
|
143
139
|
}
|
|
144
140
|
}
|
|
@@ -147,15 +143,15 @@ const invokedDirectly =
|
|
|
147
143
|
process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)
|
|
148
144
|
|
|
149
145
|
if (invokedDirectly) {
|
|
150
|
-
const
|
|
151
|
-
if (!
|
|
152
|
-
console.error('usage: node scripts/gen-knowledge.mjs <
|
|
146
|
+
const sourcePath = process.argv[2]
|
|
147
|
+
if (!sourcePath) {
|
|
148
|
+
console.error('usage: node scripts/gen-knowledge.mjs <source.json>')
|
|
153
149
|
process.exit(2)
|
|
154
150
|
}
|
|
155
|
-
const
|
|
156
|
-
const index = buildIndex(
|
|
151
|
+
const source = JSON.parse(readFileSync(sourcePath, 'utf8'))
|
|
152
|
+
const index = buildIndex(source)
|
|
157
153
|
const target = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'src', 'core', 'knowledge.json')
|
|
158
154
|
writeFileSync(target, JSON.stringify(index, null, 1) + '\n', 'utf8')
|
|
159
155
|
const total = Object.values(index.topics).reduce((sum, t) => sum + t.points.length, 0)
|
|
160
|
-
console.log(`wrote src/core/knowledge.json (${total} points
|
|
156
|
+
console.log(`wrote src/core/knowledge.json (${total} points)`)
|
|
161
157
|
}
|
package/src/core/knowledge.json
CHANGED
package/src/core/knowledge.mjs
CHANGED
|
@@ -5,14 +5,13 @@
|
|
|
5
5
|
* not carry commands, because the whole point of the tool is to catch a copied
|
|
6
6
|
* command that does not fit. What they were missing is the vocabulary the lab is
|
|
7
7
|
* teaching: which LSA belongs to which area, which attribute wins a BGP decision,
|
|
8
|
-
* which port role only MSTP has.
|
|
9
|
-
*
|
|
8
|
+
* which port role only MSTP has. Short, checkable statements about those terms
|
|
9
|
+
* are what a learner needs before touching a device.
|
|
10
10
|
*
|
|
11
|
-
* This module reads a small generated index
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* a copyrighted question bank inside a GPL package is not a reasonable default.
|
|
11
|
+
* This module reads a small generated index: one topic, the scenarios that teach
|
|
12
|
+
* it, and a list of short question/answer pairs. Shipping only the index keeps the
|
|
13
|
+
* package small and keeps third-party source material out of a GPL distribution,
|
|
14
|
+
* while `npm run knowledge` still makes every entry reproducible.
|
|
16
15
|
*
|
|
17
16
|
* @module dsh-ensp/knowledge
|
|
18
17
|
*/
|
|
@@ -95,7 +94,7 @@ export function searchKnowledge(query) {
|
|
|
95
94
|
export function renderKnowledge(scenarioId, { limit = 10 } = {}) {
|
|
96
95
|
const points = knowledgeFor(scenarioId).slice(0, limit)
|
|
97
96
|
if (!points.length) return ''
|
|
98
|
-
const lines = ['', '##
|
|
97
|
+
const lines = ['', '## 知识点(按主题归类)']
|
|
99
98
|
for (const p of points) {
|
|
100
99
|
lines.push(`- ${p.q}`)
|
|
101
100
|
lines.push(` 答: ${p.a}`)
|
package/src/dsh/index.mjs
CHANGED
|
@@ -610,7 +610,8 @@ export function apply(ctx) {
|
|
|
610
610
|
add(tools, {
|
|
611
611
|
name: 'ensp_knowledge',
|
|
612
612
|
description:
|
|
613
|
-
'Look up curriculum knowledge
|
|
613
|
+
'Look up curriculum knowledge: short statements about the terms a scenario ' +
|
|
614
|
+
'exercises, grouped by topic. ' +
|
|
614
615
|
'question/answer pairs filed by topic, and the scenarios that teach each topic. ' +
|
|
615
616
|
'Pass scenario to list what one lab teaches, or query to search the index.',
|
|
616
617
|
parameters: {
|
package/src/mcp/server.mjs
CHANGED
|
@@ -378,7 +378,8 @@ const TOOLS = [
|
|
|
378
378
|
{
|
|
379
379
|
name: 'ensp_knowledge',
|
|
380
380
|
description:
|
|
381
|
-
'Search the curriculum knowledge index
|
|
381
|
+
'Search the curriculum knowledge index: short factual statements about the terms each '
|
|
382
|
+
+ 'scenario exercises, grouped by topic. ' +
|
|
382
383
|
'Use it to look up the vocabulary a scenario teaches (which LSA belongs to which area, ' +
|
|
383
384
|
'which BGP attribute wins, which port role is MSTP only) without leaving the lab. ' +
|
|
384
385
|
'Returns short question/answer pairs plus the scenarios that teach each topic.',
|