create-np-skills 1.0.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 (137) hide show
  1. package/assets/skills/np-archive/SKILL.md +164 -0
  2. package/assets/skills/np-correct/SKILL.md +381 -0
  3. package/assets/skills/np-extract/SKILL.md +262 -0
  4. package/assets/skills/np-polish/SKILL.md +116 -0
  5. package/assets/skills/np-process/SKILL.md +140 -0
  6. package/assets/skills/np-synthesize/SKILL.md +152 -0
  7. package/assets/toolkit/dist/__tests__/disambiguate.test.d.ts +1 -0
  8. package/assets/toolkit/dist/__tests__/disambiguate.test.js +44 -0
  9. package/assets/toolkit/dist/__tests__/disambiguate.test.js.map +1 -0
  10. package/assets/toolkit/dist/__tests__/graph-validate.test.d.ts +1 -0
  11. package/assets/toolkit/dist/__tests__/graph-validate.test.js +99 -0
  12. package/assets/toolkit/dist/__tests__/graph-validate.test.js.map +1 -0
  13. package/assets/toolkit/dist/__tests__/hmm-smooth.test.d.ts +1 -0
  14. package/assets/toolkit/dist/__tests__/hmm-smooth.test.js +54 -0
  15. package/assets/toolkit/dist/__tests__/hmm-smooth.test.js.map +1 -0
  16. package/assets/toolkit/dist/src/disambiguate.d.ts +19 -0
  17. package/assets/toolkit/dist/src/disambiguate.js +187 -0
  18. package/assets/toolkit/dist/src/disambiguate.js.map +1 -0
  19. package/assets/toolkit/dist/src/graph-validate.d.ts +70 -0
  20. package/assets/toolkit/dist/src/graph-validate.js +217 -0
  21. package/assets/toolkit/dist/src/graph-validate.js.map +1 -0
  22. package/assets/toolkit/dist/src/hmm-smooth.d.ts +41 -0
  23. package/assets/toolkit/dist/src/hmm-smooth.js +173 -0
  24. package/assets/toolkit/dist/src/hmm-smooth.js.map +1 -0
  25. package/assets/toolkit/dist/src/tokenizer.d.ts +19 -0
  26. package/assets/toolkit/dist/src/tokenizer.js +70 -0
  27. package/assets/toolkit/dist/src/tokenizer.js.map +1 -0
  28. package/assets/toolkit/package.json +21 -0
  29. package/dist/bin/cli.d.ts +2 -0
  30. package/dist/bin/cli.js +7 -0
  31. package/dist/bin/cli.js.map +1 -0
  32. package/dist/src/commands/add.d.ts +3 -0
  33. package/dist/src/commands/add.js +52 -0
  34. package/dist/src/commands/add.js.map +1 -0
  35. package/dist/src/commands/init.d.ts +4 -0
  36. package/dist/src/commands/init.js +85 -0
  37. package/dist/src/commands/init.js.map +1 -0
  38. package/dist/src/commands/list.d.ts +3 -0
  39. package/dist/src/commands/list.js +26 -0
  40. package/dist/src/commands/list.js.map +1 -0
  41. package/dist/src/commands/remove.d.ts +4 -0
  42. package/dist/src/commands/remove.js +35 -0
  43. package/dist/src/commands/remove.js.map +1 -0
  44. package/dist/src/commands/status.d.ts +3 -0
  45. package/dist/src/commands/status.js +30 -0
  46. package/dist/src/commands/status.js.map +1 -0
  47. package/dist/src/index.d.ts +1 -0
  48. package/dist/src/index.js +52 -0
  49. package/dist/src/index.js.map +1 -0
  50. package/dist/src/installer/config.d.ts +9 -0
  51. package/dist/src/installer/config.js +44 -0
  52. package/dist/src/installer/config.js.map +1 -0
  53. package/dist/src/installer/skills.d.ts +9 -0
  54. package/dist/src/installer/skills.js +74 -0
  55. package/dist/src/installer/skills.js.map +1 -0
  56. package/dist/src/installer/toolkit.d.ts +4 -0
  57. package/dist/src/installer/toolkit.js +35 -0
  58. package/dist/src/installer/toolkit.js.map +1 -0
  59. package/dist/src/platforms/aider.d.ts +2 -0
  60. package/dist/src/platforms/aider.js +22 -0
  61. package/dist/src/platforms/aider.js.map +1 -0
  62. package/dist/src/platforms/all-platforms.d.ts +4 -0
  63. package/dist/src/platforms/all-platforms.js +28 -0
  64. package/dist/src/platforms/all-platforms.js.map +1 -0
  65. package/dist/src/platforms/amazon-q.d.ts +1 -0
  66. package/dist/src/platforms/amazon-q.js +3 -0
  67. package/dist/src/platforms/amazon-q.js.map +1 -0
  68. package/dist/src/platforms/antigravity.d.ts +1 -0
  69. package/dist/src/platforms/antigravity.js +3 -0
  70. package/dist/src/platforms/antigravity.js.map +1 -0
  71. package/dist/src/platforms/claude-code.d.ts +1 -0
  72. package/dist/src/platforms/claude-code.js +3 -0
  73. package/dist/src/platforms/claude-code.js.map +1 -0
  74. package/dist/src/platforms/cline.d.ts +1 -0
  75. package/dist/src/platforms/cline.js +15 -0
  76. package/dist/src/platforms/cline.js.map +1 -0
  77. package/dist/src/platforms/codex.d.ts +1 -0
  78. package/dist/src/platforms/codex.js +3 -0
  79. package/dist/src/platforms/codex.js.map +1 -0
  80. package/dist/src/platforms/copilot-cli.d.ts +1 -0
  81. package/dist/src/platforms/copilot-cli.js +3 -0
  82. package/dist/src/platforms/copilot-cli.js.map +1 -0
  83. package/dist/src/platforms/cursor.d.ts +2 -0
  84. package/dist/src/platforms/cursor.js +19 -0
  85. package/dist/src/platforms/cursor.js.map +1 -0
  86. package/dist/src/platforms/gemini-cli.d.ts +1 -0
  87. package/dist/src/platforms/gemini-cli.js +3 -0
  88. package/dist/src/platforms/gemini-cli.js.map +1 -0
  89. package/dist/src/platforms/hermes.d.ts +1 -0
  90. package/dist/src/platforms/hermes.js +3 -0
  91. package/dist/src/platforms/hermes.js.map +1 -0
  92. package/dist/src/platforms/opencode.d.ts +1 -0
  93. package/dist/src/platforms/opencode.js +3 -0
  94. package/dist/src/platforms/opencode.js.map +1 -0
  95. package/dist/src/platforms/reasonix.d.ts +1 -0
  96. package/dist/src/platforms/reasonix.js +3 -0
  97. package/dist/src/platforms/reasonix.js.map +1 -0
  98. package/dist/src/platforms/registry.d.ts +3 -0
  99. package/dist/src/platforms/registry.js +44 -0
  100. package/dist/src/platforms/registry.js.map +1 -0
  101. package/dist/src/platforms/windsurf.d.ts +2 -0
  102. package/dist/src/platforms/windsurf.js +19 -0
  103. package/dist/src/platforms/windsurf.js.map +1 -0
  104. package/dist/src/types.d.ts +34 -0
  105. package/dist/src/types.js +13 -0
  106. package/dist/src/types.js.map +1 -0
  107. package/dist/src/utils/fs.d.ts +8 -0
  108. package/dist/src/utils/fs.js +37 -0
  109. package/dist/src/utils/fs.js.map +1 -0
  110. package/dist/src/utils/logger.d.ts +11 -0
  111. package/dist/src/utils/logger.js +22 -0
  112. package/dist/src/utils/logger.js.map +1 -0
  113. package/dist/src/utils/shell.d.ts +6 -0
  114. package/dist/src/utils/shell.js +34 -0
  115. package/dist/src/utils/shell.js.map +1 -0
  116. package/dist/src/verify.d.ts +12 -0
  117. package/dist/src/verify.js +56 -0
  118. package/dist/src/verify.js.map +1 -0
  119. package/dist/src/wizard/confirm.d.ts +5 -0
  120. package/dist/src/wizard/confirm.js +23 -0
  121. package/dist/src/wizard/confirm.js.map +1 -0
  122. package/dist/src/wizard/detect.d.ts +8 -0
  123. package/dist/src/wizard/detect.js +31 -0
  124. package/dist/src/wizard/detect.js.map +1 -0
  125. package/dist/src/wizard/select-location.d.ts +1 -0
  126. package/dist/src/wizard/select-location.js +20 -0
  127. package/dist/src/wizard/select-location.js.map +1 -0
  128. package/dist/src/wizard/select-platforms.d.ts +1 -0
  129. package/dist/src/wizard/select-platforms.js +26 -0
  130. package/dist/src/wizard/select-platforms.js.map +1 -0
  131. package/dist/src/wizard/select-skills.d.ts +1 -0
  132. package/dist/src/wizard/select-skills.js +22 -0
  133. package/dist/src/wizard/select-skills.js.map +1 -0
  134. package/dist/src/wizard/welcome.d.ts +1 -0
  135. package/dist/src/wizard/welcome.js +6 -0
  136. package/dist/src/wizard/welcome.js.map +1 -0
  137. package/package.json +35 -0
@@ -0,0 +1,217 @@
1
+ /**
2
+ * graph-validate.ts
3
+ *
4
+ * Ontology validation tool — validates a knowledge graph against 5 ontology
5
+ * dimensions: completeness, consistency, correctness, clarity, traceability.
6
+ *
7
+ * This is a pure TypeScript tool with NO external dependencies.
8
+ * It handles quantifiable checks only; semantic judgment is left to
9
+ * downstream LLM-based validators (P4-C).
10
+ *
11
+ * Scoring: each dimension 0–1, composite = average of 5 dimensions.
12
+ */
13
+ /* ------------------------------------------------------------------ */
14
+ /* Constants */
15
+ /* ------------------------------------------------------------------ */
16
+ /** Relations where A→B + B→A is logically contradictory. */
17
+ const SYMMETRIC_CONTRADICTIONS = new Set(['is-a', 'same-as', 'equivalent-to']);
18
+ /** Relations that should never appear bidirectionally. */
19
+ const ASYMMETRIC_ONLY = new Set(['contains', 'is-prerequisite-of', 'depends-on', 'is-implemented-by']);
20
+ /* ------------------------------------------------------------------ */
21
+ /* Validation */
22
+ /* ------------------------------------------------------------------ */
23
+ /**
24
+ * Validate a knowledge graph against a concept dictionary and a reference
25
+ * framework.
26
+ *
27
+ * @param graph The knowledge graph to validate.
28
+ * @param conceptDict The canonical concept dictionary.
29
+ * @param framework The reference framework (expected relations).
30
+ * @returns A `ValidateResult` with composite score, dimension scores, gaps, and summary.
31
+ */
32
+ export function validateOntology(graph, conceptDict, framework) {
33
+ const gaps = [];
34
+ const nodeIds = new Set(graph.nodes.map(n => n.id));
35
+ const conceptNames = new Set(conceptDict.concepts.map(c => c.name));
36
+ /* ---- completeness ---- */
37
+ const completeness = checkCompleteness(graph, conceptDict, framework, nodeIds, conceptNames, gaps);
38
+ /* ---- consistency ---- */
39
+ const consistency = checkConsistency(graph, gaps);
40
+ /* ---- correctness ---- */
41
+ const correctness = checkCorrectness(graph, nodeIds, gaps);
42
+ /* ---- clarity ---- */
43
+ const clarity = checkClarity(conceptDict, gaps);
44
+ /* ---- traceability ---- */
45
+ const traceability = checkTraceability(graph, conceptNames, nodeIds, gaps);
46
+ /* ---- composite ---- */
47
+ const dimensions = {
48
+ completeness,
49
+ consistency,
50
+ correctness,
51
+ clarity,
52
+ traceability,
53
+ };
54
+ const score = +(Object.values(dimensions).reduce((s, v) => s + v, 0) / 5).toFixed(4);
55
+ /* ---- summary ---- */
56
+ const criticalCount = gaps.filter(g => g.severity === 'critical').length;
57
+ const warnInfoCount = gaps.filter(g => g.severity === 'warning' || g.severity === 'info').length;
58
+ let summary;
59
+ if (score === 1) {
60
+ summary = '5 维度全部通过,图谱质量合格';
61
+ }
62
+ else {
63
+ summary = `${criticalCount} 个严重问题,${warnInfoCount} 个警告/提示。综合评分: ${score}`;
64
+ }
65
+ return { score, dimensions, gaps, summary };
66
+ }
67
+ /* ------------------------------------------------------------------ */
68
+ /* Dimension helpers */
69
+ /* ------------------------------------------------------------------ */
70
+ function checkCompleteness(graph, conceptDict, framework, nodeIds, _conceptNames, gaps) {
71
+ const totalConcepts = conceptDict.concepts.length;
72
+ let missingCount = 0;
73
+ for (const concept of conceptDict.concepts) {
74
+ if (!nodeIds.has(concept.name)) {
75
+ missingCount++;
76
+ gaps.push({
77
+ dimension: 'completeness',
78
+ severity: 'critical',
79
+ detail: `缺失概念节点: ${concept.name}`,
80
+ autoFixable: true,
81
+ fixDescription: `添加节点 { id: "${concept.name}", type: "concept" }`,
82
+ });
83
+ }
84
+ }
85
+ // Check framework relations against graph edges
86
+ const edgeKeys = new Set(graph.edges.map(e => `${e.from}|${e.to}|${e.relation}`));
87
+ for (const rel of framework.relations) {
88
+ const relKey = `${rel.from}|${rel.to}|${rel.type}`;
89
+ if (!edgeKeys.has(relKey)) {
90
+ gaps.push({
91
+ dimension: 'completeness',
92
+ severity: 'warning',
93
+ detail: `缺失框架关系: ${rel.from} --[${rel.type}]--> ${rel.to}`,
94
+ autoFixable: true,
95
+ fixDescription: `添加边 { from: "${rel.from}", to: "${rel.to}", relation: "${rel.type}" }`,
96
+ });
97
+ }
98
+ }
99
+ return totalConcepts > 0
100
+ ? 1 - missingCount / totalConcepts
101
+ : 1;
102
+ }
103
+ function checkConsistency(graph, gaps) {
104
+ let contradictionCount = 0;
105
+ // Build edge lookup: for each from→to, collect relations
106
+ const edgeMap = new Map();
107
+ for (const e of graph.edges) {
108
+ if (!edgeMap.has(e.from))
109
+ edgeMap.set(e.from, new Map());
110
+ const toMap = edgeMap.get(e.from);
111
+ if (!toMap.has(e.to))
112
+ toMap.set(e.to, []);
113
+ toMap.get(e.to).push(e.relation);
114
+ }
115
+ const seen = new Set();
116
+ for (const e of graph.edges) {
117
+ // Dedup: only check each unordered pair once
118
+ const pairKey = [e.from, e.to].sort().join('||');
119
+ if (seen.has(pairKey))
120
+ continue;
121
+ seen.add(pairKey);
122
+ // Check symmetric contradiction: B→A has a symmetric relation when A→B also has it
123
+ const reverseRelations = edgeMap.get(e.to)?.get(e.from);
124
+ if (reverseRelations) {
125
+ for (const revRel of reverseRelations) {
126
+ if (SYMMETRIC_CONTRADICTIONS.has(e.relation) && e.relation === revRel) {
127
+ contradictionCount++;
128
+ gaps.push({
129
+ dimension: 'consistency',
130
+ severity: 'critical',
131
+ detail: `对称矛盾: ${e.from} --[${e.relation}]--> ${e.to} 且反向也存在`,
132
+ autoFixable: false,
133
+ });
134
+ }
135
+ if (ASYMMETRIC_ONLY.has(e.relation) && e.relation === revRel) {
136
+ contradictionCount++;
137
+ gaps.push({
138
+ dimension: 'consistency',
139
+ severity: 'warning',
140
+ detail: `非对称关系双向使用: ${e.from} <--[${e.relation}]--> ${e.to}`,
141
+ autoFixable: false,
142
+ });
143
+ }
144
+ }
145
+ }
146
+ }
147
+ return Math.max(0, 1 - contradictionCount * 0.3);
148
+ }
149
+ function checkCorrectness(graph, nodeIds, gaps) {
150
+ let danglingCount = 0;
151
+ for (const edge of graph.edges) {
152
+ if (!nodeIds.has(edge.from)) {
153
+ danglingCount++;
154
+ gaps.push({
155
+ dimension: 'correctness',
156
+ severity: 'critical',
157
+ detail: `悬挂边起点不存在: "${edge.from}" (边 ${edge.from} -> ${edge.to})`,
158
+ autoFixable: false,
159
+ });
160
+ }
161
+ if (!nodeIds.has(edge.to)) {
162
+ danglingCount++;
163
+ gaps.push({
164
+ dimension: 'correctness',
165
+ severity: 'critical',
166
+ detail: `悬挂边终点不存在: "${edge.to}" (边 ${edge.from} -> ${edge.to})`,
167
+ autoFixable: false,
168
+ });
169
+ }
170
+ }
171
+ return Math.max(0, 1 - danglingCount * 0.2);
172
+ }
173
+ function checkClarity(conceptDict, gaps) {
174
+ let clarityIssueCount = 0;
175
+ for (const concept of conceptDict.concepts) {
176
+ // Circular definition: definition contains the concept name
177
+ if (concept.definition.includes(concept.name)) {
178
+ clarityIssueCount++;
179
+ gaps.push({
180
+ dimension: 'clarity',
181
+ severity: 'warning',
182
+ detail: `循环定义: "${concept.name}" 的定义包含其自身`,
183
+ autoFixable: false,
184
+ });
185
+ }
186
+ // Overly short definition
187
+ if (concept.definition.trim().length < 5) {
188
+ clarityIssueCount++;
189
+ gaps.push({
190
+ dimension: 'clarity',
191
+ severity: 'info',
192
+ detail: `定义过短: "${concept.name}" 的定义长度不足 5 个字符`,
193
+ autoFixable: false,
194
+ });
195
+ }
196
+ }
197
+ return Math.max(0, 1 - clarityIssueCount * 0.1);
198
+ }
199
+ function checkTraceability(graph, conceptNames, _nodeIds, gaps) {
200
+ const totalNodes = graph.nodes.length;
201
+ let untraceableCount = 0;
202
+ if (totalNodes === 0)
203
+ return 1;
204
+ for (const node of graph.nodes) {
205
+ if (!conceptNames.has(node.id)) {
206
+ untraceableCount++;
207
+ gaps.push({
208
+ dimension: 'traceability',
209
+ severity: 'warning',
210
+ detail: `节点无法追溯到词典: "${node.id}"`,
211
+ autoFixable: false,
212
+ });
213
+ }
214
+ }
215
+ return 1 - untraceableCount / totalNodes;
216
+ }
217
+ //# sourceMappingURL=graph-validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-validate.js","sourceRoot":"","sources":["../../src/graph-validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /** Multi-language text smoothing analysis for note-processing pipeline. */
2
+ import { type Language } from './tokenizer.js';
3
+ export interface CoherenceResult {
4
+ average: number;
5
+ scores: Array<{
6
+ index: number;
7
+ score: number;
8
+ issue?: string;
9
+ }>;
10
+ }
11
+ export interface NgramResult {
12
+ transitions: Array<{
13
+ from: string;
14
+ to: string;
15
+ novel: boolean;
16
+ }>;
17
+ repeatedNgrams: string[];
18
+ diversityScore: number;
19
+ }
20
+ export interface WordFreqResult {
21
+ overused: Array<{
22
+ word: string;
23
+ count: number;
24
+ suggestion: string;
25
+ }>;
26
+ distribution: {
27
+ short: number;
28
+ medium: number;
29
+ long: number;
30
+ };
31
+ }
32
+ export interface SmoothSuggestions {
33
+ coherence: CoherenceResult;
34
+ ngram: NgramResult;
35
+ wordFrequency: WordFreqResult;
36
+ summary: string[];
37
+ }
38
+ export declare function analyzeCoherence(sentences: string[], language?: Language | null): CoherenceResult;
39
+ export declare function analyzeNgram(sentences: string[], n?: number, language?: Language | null): NgramResult;
40
+ export declare function analyzeWordFrequency(text: string, language?: Language | null): WordFreqResult;
41
+ export declare function generateSmoothSuggestions(text: string, language?: Language | null): SmoothSuggestions;
@@ -0,0 +1,173 @@
1
+ /** Multi-language text smoothing analysis for note-processing pipeline. */
2
+ import { getTokenizer } from './tokenizer.js';
3
+ // ── Constants ──
4
+ const COHERENCE_LOW_THRESHOLD = 0.15;
5
+ const COHERENCE_SUMMARY_THRESHOLD = 0.3;
6
+ const DIVERSITY_SUMMARY_THRESHOLD = 0.4;
7
+ const OVERUSED_FREQ_RATIO = 0.03;
8
+ const OVERUSED_WORD_MAX_LENGTH = 2;
9
+ const OVERUSED_MAX_COUNT = 10;
10
+ const SENTENCE_SHORT_MAX = 15;
11
+ const SENTENCE_MEDIUM_MAX = 40;
12
+ const SHORT_SENTENCE_RATIO_WARN = 0.5;
13
+ const LONG_SENTENCE_RATIO_WARN = 0.4;
14
+ const OVERUSED_WORD_COUNT_WARN = 5;
15
+ // ── Suggestions (language-aware) ──
16
+ const MSG = {
17
+ zh: {
18
+ coherenceLow: '全文连贯度偏低,建议增加过渡句或连接词',
19
+ diversityLow: '句式多样性偏低,建议调整句式结构',
20
+ overusedMany: (n) => `高频词偏多 (${n} 个),建议替换部分重复词汇`,
21
+ shortSentences: '短句占比超过 50%,建议合并部分短句以提升阅读流畅度',
22
+ longSentences: '长句占比超过 40%,建议拆分部分长句以降低阅读负担',
23
+ },
24
+ en: {
25
+ coherenceLow: 'Text coherence is low; consider adding transition sentences or connectors',
26
+ diversityLow: 'Sentence variety is low; consider varying sentence openers',
27
+ overusedMany: (n) => `${n} overused words detected; consider replacing some with synonyms`,
28
+ shortSentences: 'Short sentences exceed 50% of total; consider combining for better flow',
29
+ longSentences: 'Long sentences exceed 40% of total; consider splitting for readability',
30
+ },
31
+ };
32
+ // ── Coherence Analysis ──
33
+ export function analyzeCoherence(sentences, language) {
34
+ if (sentences.length === 0)
35
+ return { average: 0, scores: [] };
36
+ const tokenizer = getTokenizer(language, sentences[0]);
37
+ const tokenized = sentences.map(s => new Set(tokenizer.tokenize(s)));
38
+ const scores = [];
39
+ for (let i = 0; i < tokenized.length; i++) {
40
+ const current = tokenized[i];
41
+ const prev = i > 0 ? tokenized[i - 1] : null;
42
+ const next = i < tokenized.length - 1 ? tokenized[i + 1] : null;
43
+ let overlapCount = 0;
44
+ const neighbors = [prev, next].filter(Boolean);
45
+ for (const token of current) {
46
+ if (neighbors.some(n => n.has(token)))
47
+ overlapCount++;
48
+ }
49
+ const score = current.size > 0
50
+ ? overlapCount / current.size
51
+ : 0.5;
52
+ const issue = score < COHERENCE_LOW_THRESHOLD
53
+ ? `sentence ${i + 1} coherence score is low (${score.toFixed(2)})`
54
+ : undefined;
55
+ scores.push({ index: i, score: Math.round(score * 100) / 100, issue });
56
+ }
57
+ const average = scores.reduce((sum, s) => sum + s.score, 0) / scores.length;
58
+ return { average: Math.round(average * 100) / 100, scores };
59
+ }
60
+ // ── N-gram Analysis ──
61
+ export function analyzeNgram(sentences, n = 2, language) {
62
+ if (sentences.length < 2) {
63
+ return { transitions: [], repeatedNgrams: [], diversityScore: 1 };
64
+ }
65
+ const tokenizer = getTokenizer(language, sentences[0]);
66
+ const transitions = [];
67
+ const ngramCounts = new Map();
68
+ for (let i = 0; i < sentences.length - 1; i++) {
69
+ const tokensA = tokenizer.tokenize(sentences[i]);
70
+ const tokensB = tokenizer.tokenize(sentences[i + 1]);
71
+ const lastN = tokensA.slice(-n).join(' ');
72
+ const firstN = tokensB.slice(0, n).join(' ');
73
+ transitions.push({ from: lastN, to: firstN, novel: true });
74
+ const key = `${lastN}|${firstN}`;
75
+ ngramCounts.set(key, (ngramCounts.get(key) || 0) + 1);
76
+ }
77
+ // Mark repeat patterns as not novel
78
+ const seenKeys = new Set();
79
+ for (const t of transitions) {
80
+ const key = `${t.from}|${t.to}`;
81
+ if (seenKeys.has(key))
82
+ t.novel = false;
83
+ else
84
+ seenKeys.add(key);
85
+ }
86
+ const repeatedNgrams = [...ngramCounts.entries()]
87
+ .filter(([, count]) => count > 1)
88
+ .map(([bg]) => bg);
89
+ const uniqueCount = ngramCounts.size;
90
+ const diversityScore = transitions.length > 0
91
+ ? Math.min(1, uniqueCount / transitions.length)
92
+ : 1;
93
+ return { transitions, repeatedNgrams, diversityScore: Math.round(diversityScore * 100) / 100 };
94
+ }
95
+ // ── Word Frequency Analysis ──
96
+ export function analyzeWordFrequency(text, language) {
97
+ const tokenizer = getTokenizer(language, text);
98
+ const lang = language ?? 'en';
99
+ const sentences = tokenizer.splitSentences(text);
100
+ const allTokens = tokenizer.tokenize(text);
101
+ // Word frequency
102
+ const freq = new Map();
103
+ for (const token of allTokens) {
104
+ const t = token.toLowerCase();
105
+ // Skip very short tokens and pure punctuation
106
+ if (t.length <= 1 && !/[a-z0-9一-鿿]/i.test(t))
107
+ continue;
108
+ freq.set(t, (freq.get(t) || 0) + 1);
109
+ }
110
+ const totalContentTokens = [...freq.values()].reduce((a, b) => a + b, 0);
111
+ // Overused words (>3% frequency, max length 2 for CJK or short English words)
112
+ const overused = totalContentTokens > 0
113
+ ? [...freq.entries()]
114
+ .filter(([word, count]) => {
115
+ const ratio = count / totalContentTokens;
116
+ const maxLen = lang === 'zh' ? OVERUSED_WORD_MAX_LENGTH : 4;
117
+ return ratio > OVERUSED_FREQ_RATIO && word.length <= maxLen;
118
+ })
119
+ .map(([word, count]) => {
120
+ const pct = ((count / totalContentTokens) * 100).toFixed(1);
121
+ return {
122
+ word,
123
+ count,
124
+ suggestion: lang === 'zh'
125
+ ? `"${word}" 出现 ${count} 次 (${pct}%),建议替换部分为同义词`
126
+ : `"${word}" appears ${count} times (${pct}%); consider synonyms`,
127
+ };
128
+ })
129
+ .sort((a, b) => b.count - a.count)
130
+ .slice(0, OVERUSED_MAX_COUNT)
131
+ : [];
132
+ // Sentence length distribution
133
+ const dist = { short: 0, medium: 0, long: 0 };
134
+ for (const s of sentences) {
135
+ const len = s.length;
136
+ if (len <= SENTENCE_SHORT_MAX)
137
+ dist.short++;
138
+ else if (len <= SENTENCE_MEDIUM_MAX)
139
+ dist.medium++;
140
+ else
141
+ dist.long++;
142
+ }
143
+ return { overused, distribution: dist };
144
+ }
145
+ // ── Main Entry ──
146
+ export function generateSmoothSuggestions(text, language) {
147
+ const tokenizer = getTokenizer(language, text);
148
+ const lang = language ?? 'en';
149
+ const m = MSG[lang] ?? MSG.en;
150
+ const sentences = tokenizer.splitSentences(text);
151
+ const coherence = analyzeCoherence(sentences, lang);
152
+ const ngram = analyzeNgram(sentences, 2, lang);
153
+ const wordFrequency = analyzeWordFrequency(text, lang);
154
+ const summary = [];
155
+ if (coherence.average < COHERENCE_SUMMARY_THRESHOLD) {
156
+ summary.push(m.coherenceLow);
157
+ }
158
+ if (ngram.diversityScore < DIVERSITY_SUMMARY_THRESHOLD) {
159
+ summary.push(m.diversityLow);
160
+ }
161
+ if (wordFrequency.overused.length > OVERUSED_WORD_COUNT_WARN) {
162
+ summary.push(m.overusedMany(wordFrequency.overused.length));
163
+ }
164
+ const totalSentences = wordFrequency.distribution.short + wordFrequency.distribution.medium + wordFrequency.distribution.long;
165
+ if (totalSentences > 0 && wordFrequency.distribution.short / totalSentences > SHORT_SENTENCE_RATIO_WARN) {
166
+ summary.push(m.shortSentences);
167
+ }
168
+ if (totalSentences > 0 && wordFrequency.distribution.long / totalSentences > LONG_SENTENCE_RATIO_WARN) {
169
+ summary.push(m.longSentences);
170
+ }
171
+ return { coherence, ngram, wordFrequency, summary };
172
+ }
173
+ //# sourceMappingURL=hmm-smooth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmm-smooth.js","sourceRoot":"","sources":["../../src/hmm-smooth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /** Tokenizer abstraction for multi-language NLP support. */
2
+ export type Language = 'zh' | 'en';
3
+ export interface Tokenizer {
4
+ /** Split text into word tokens */
5
+ tokenize(text: string): string[];
6
+ /** Split text into sentences */
7
+ splitSentences(text: string): string[];
8
+ }
9
+ /** Detect language by counting CJK characters. Threshold: >20% CJK = Chinese. */
10
+ export declare function detectLanguage(text: string): Language;
11
+ export declare class ChineseTokenizer implements Tokenizer {
12
+ tokenize(text: string): string[];
13
+ splitSentences(text: string): string[];
14
+ }
15
+ export declare class EnglishTokenizer implements Tokenizer {
16
+ tokenize(text: string): string[];
17
+ splitSentences(text: string): string[];
18
+ }
19
+ export declare function getTokenizer(language?: Language | null, text?: string): Tokenizer;
@@ -0,0 +1,70 @@
1
+ /** Tokenizer abstraction for multi-language NLP support. */
2
+ import { Jieba } from '@node-rs/jieba';
3
+ import { dict } from '@node-rs/jieba/dict.js';
4
+ // ── Language Detection ──
5
+ /** Detect language by counting CJK characters. Threshold: >20% CJK = Chinese. */
6
+ export function detectLanguage(text) {
7
+ const cjkCount = [...text].filter(c => /\p{Script=Han}/u.test(c)).length;
8
+ return cjkCount / Math.max(text.length, 1) > 0.2 ? 'zh' : 'en';
9
+ }
10
+ // ── Chinese Tokenizer ──
11
+ const jiebaInstance = Jieba.withDict(dict);
12
+ export class ChineseTokenizer {
13
+ tokenize(text) {
14
+ return jiebaInstance.cut(text, true).filter(t => t.trim().length > 0);
15
+ }
16
+ splitSentences(text) {
17
+ return text.split(/[。!?\n]+/).filter(s => s.trim().length > 0);
18
+ }
19
+ }
20
+ // ── English Tokenizer ──
21
+ /** Common abbreviations that don't end sentences */
22
+ const ABBREVIATIONS = new Set([
23
+ 'mr', 'mrs', 'ms', 'dr', 'prof', 'sr', 'jr',
24
+ 'vs', 'etc', 'inc', 'ltd', 'co', 'corp',
25
+ 'eg', 'ie', 'al', 'approx', 'dept', 'est',
26
+ 'us', 'uk', 'eu', 'un',
27
+ ]);
28
+ export class EnglishTokenizer {
29
+ tokenize(text) {
30
+ // Split on whitespace and strip punctuation from edges
31
+ return text
32
+ .split(/\s+/)
33
+ .map(t => t.replace(/^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$/g, ''))
34
+ .filter(t => t.length > 0);
35
+ }
36
+ splitSentences(text) {
37
+ const sentences = [];
38
+ let current = '';
39
+ const words = text.split(/\s+/);
40
+ for (const word of words) {
41
+ current += (current ? ' ' : '') + word;
42
+ // Check if word ends with sentence-ending punctuation
43
+ const match = word.match(/([.!?])$/);
44
+ if (match) {
45
+ // Don't split on abbreviations
46
+ const prevWord = word.slice(0, -1).toLowerCase().replace(/[^a-z]/g, '');
47
+ if (!ABBREVIATIONS.has(prevWord)) {
48
+ sentences.push(current.trim());
49
+ current = '';
50
+ }
51
+ }
52
+ }
53
+ if (current.trim())
54
+ sentences.push(current.trim());
55
+ return sentences;
56
+ }
57
+ }
58
+ // ── Factory ──
59
+ let zhInstance = null;
60
+ let enInstance = null;
61
+ export function getTokenizer(language, text) {
62
+ const lang = language ?? (text ? detectLanguage(text) : 'en');
63
+ if (lang === 'zh') {
64
+ zhInstance ??= new ChineseTokenizer();
65
+ return zhInstance;
66
+ }
67
+ enInstance ??= new EnglishTokenizer();
68
+ return enInstance;
69
+ }
70
+ //# sourceMappingURL=tokenizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../src/tokenizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "note-nlp",
3
+ "version": "1.0.0",
4
+ "description": "NLP tools for note-processing pipeline: disambiguation, HMM smoothing, ontology validation",
5
+ "private": true,
6
+ "type": "module",
7
+ "scripts": {
8
+ "test": "vitest run",
9
+ "test:watch": "vitest",
10
+ "build": "tsc",
11
+ "typecheck": "tsc --noEmit"
12
+ },
13
+ "dependencies": {
14
+ "@node-rs/jieba": "^2.0.1",
15
+ "xlsx": "^0.18.5"
16
+ },
17
+ "devDependencies": {
18
+ "typescript": "^5.5.0",
19
+ "vitest": "^1.6.0"
20
+ }
21
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../src/index.js';
3
+ main().catch((err) => {
4
+ console.error('Fatal error:', err);
5
+ process.exit(1);
6
+ });
7
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IAC1B,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function runAdd(name?: string, options?: {
2
+ config?: string;
3
+ }): Promise<void>;
@@ -0,0 +1,52 @@
1
+ import { checkbox } from '@inquirer/prompts';
2
+ import { loadConfig, saveConfig, getAvailableSkills, addSkillToConfig } from '../installer/config.js';
3
+ import { installSkill } from '../installer/skills.js';
4
+ import { SKILL_NAMES } from '../types.js';
5
+ import { log } from '../utils/logger.js';
6
+ const VALID_SKILLS = new Set(SKILL_NAMES);
7
+ export async function runAdd(name, options) {
8
+ const config = await loadConfig(options?.config);
9
+ if (!config) {
10
+ log.error('未找到配置文件,请先运行 npx create-np-skills init');
11
+ process.exit(1);
12
+ }
13
+ if (name && !VALID_SKILLS.has(name)) {
14
+ log.error(`未知 Skill: ${name}。可用: ${SKILL_NAMES.join(', ')}`);
15
+ process.exit(1);
16
+ }
17
+ let skills;
18
+ if (name) {
19
+ if (name in config.skills) {
20
+ log.warn(`${name} 已经安装`);
21
+ process.exit(0);
22
+ }
23
+ skills = [name];
24
+ }
25
+ else {
26
+ const available = getAvailableSkills(config);
27
+ if (available.length === 0) {
28
+ log.info('所有 Skill 已安装');
29
+ process.exit(0);
30
+ }
31
+ skills = await checkbox({
32
+ message: '选择要安装的 Skill',
33
+ choices: available.map(s => ({ name: s, value: s, checked: true })),
34
+ });
35
+ if (skills.length === 0) {
36
+ log.info('未选择任何 Skill');
37
+ process.exit(0);
38
+ }
39
+ }
40
+ for (const skill of skills) {
41
+ const result = await installSkill(skill, config.platforms, config.location, config.projectPath ?? undefined);
42
+ if (result.success) {
43
+ addSkillToConfig(config, skill);
44
+ log.success(`${skill} 安装完成`);
45
+ }
46
+ else {
47
+ log.error(`${skill} 安装失败: ${result.errors.join(', ')}`);
48
+ }
49
+ }
50
+ await saveConfig(config, options?.config);
51
+ }
52
+ //# sourceMappingURL=add.js.map