@aaronsb/kg-cli 0.6.6 → 0.7.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 (96) hide show
  1. package/dist/api/client.d.ts +127 -1
  2. package/dist/api/client.d.ts.map +1 -1
  3. package/dist/api/client.js +147 -0
  4. package/dist/api/client.js.map +1 -1
  5. package/dist/cli/batch.d.ts +8 -0
  6. package/dist/cli/batch.d.ts.map +1 -0
  7. package/dist/cli/batch.js +225 -0
  8. package/dist/cli/batch.js.map +1 -0
  9. package/dist/cli/commands.d.ts.map +1 -1
  10. package/dist/cli/commands.js +8 -0
  11. package/dist/cli/commands.js.map +1 -1
  12. package/dist/cli/concept.d.ts +9 -0
  13. package/dist/cli/concept.d.ts.map +1 -0
  14. package/dist/cli/concept.js +336 -0
  15. package/dist/cli/concept.js.map +1 -0
  16. package/dist/cli/edge.d.ts +9 -0
  17. package/dist/cli/edge.d.ts.map +1 -0
  18. package/dist/cli/edge.js +364 -0
  19. package/dist/cli/edge.js.map +1 -0
  20. package/dist/cli/jobs.js +111 -3
  21. package/dist/cli/jobs.js.map +1 -1
  22. package/dist/cli/storage.d.ts +10 -0
  23. package/dist/cli/storage.d.ts.map +1 -0
  24. package/dist/cli/storage.js +260 -0
  25. package/dist/cli/storage.js.map +1 -0
  26. package/dist/cli/vocabulary/index.d.ts.map +1 -1
  27. package/dist/cli/vocabulary/index.js +1 -0
  28. package/dist/cli/vocabulary/index.js.map +1 -1
  29. package/dist/cli/vocabulary/similarity.d.ts +1 -0
  30. package/dist/cli/vocabulary/similarity.d.ts.map +1 -1
  31. package/dist/cli/vocabulary/similarity.js +60 -9
  32. package/dist/cli/vocabulary/similarity.js.map +1 -1
  33. package/dist/lib/interactive.d.ts +84 -0
  34. package/dist/lib/interactive.d.ts.map +1 -0
  35. package/dist/lib/interactive.js +296 -0
  36. package/dist/lib/interactive.js.map +1 -0
  37. package/dist/lib/validation.d.ts +106 -0
  38. package/dist/lib/validation.d.ts.map +1 -0
  39. package/dist/lib/validation.js +354 -0
  40. package/dist/lib/validation.js.map +1 -0
  41. package/dist/mcp/formatters/concept.d.ts +24 -0
  42. package/dist/mcp/formatters/concept.d.ts.map +1 -0
  43. package/dist/mcp/formatters/concept.js +243 -0
  44. package/dist/mcp/formatters/concept.js.map +1 -0
  45. package/dist/mcp/formatters/document.d.ts +25 -0
  46. package/dist/mcp/formatters/document.d.ts.map +1 -0
  47. package/dist/mcp/formatters/document.js +178 -0
  48. package/dist/mcp/formatters/document.js.map +1 -0
  49. package/dist/mcp/formatters/epistemic.d.ts +16 -0
  50. package/dist/mcp/formatters/epistemic.d.ts.map +1 -0
  51. package/dist/mcp/formatters/epistemic.js +269 -0
  52. package/dist/mcp/formatters/epistemic.js.map +1 -0
  53. package/dist/mcp/formatters/graph.d.ts +63 -0
  54. package/dist/mcp/formatters/graph.d.ts.map +1 -0
  55. package/dist/mcp/formatters/graph.js +220 -0
  56. package/dist/mcp/formatters/graph.js.map +1 -0
  57. package/dist/mcp/formatters/index.d.ts +18 -0
  58. package/dist/mcp/formatters/index.d.ts.map +1 -0
  59. package/dist/mcp/formatters/index.js +63 -0
  60. package/dist/mcp/formatters/index.js.map +1 -0
  61. package/dist/mcp/formatters/ingest.d.ts +16 -0
  62. package/dist/mcp/formatters/ingest.d.ts.map +1 -0
  63. package/dist/mcp/formatters/ingest.js +169 -0
  64. package/dist/mcp/formatters/ingest.js.map +1 -0
  65. package/dist/mcp/formatters/job.d.ts +13 -0
  66. package/dist/mcp/formatters/job.d.ts.map +1 -0
  67. package/dist/mcp/formatters/job.js +204 -0
  68. package/dist/mcp/formatters/job.js.map +1 -0
  69. package/dist/mcp/formatters/source.d.ts +19 -0
  70. package/dist/mcp/formatters/source.d.ts.map +1 -0
  71. package/dist/mcp/formatters/source.js +182 -0
  72. package/dist/mcp/formatters/source.js.map +1 -0
  73. package/dist/mcp/formatters/system.d.ts +10 -0
  74. package/dist/mcp/formatters/system.d.ts.map +1 -0
  75. package/dist/mcp/formatters/system.js +152 -0
  76. package/dist/mcp/formatters/system.js.map +1 -0
  77. package/dist/mcp/formatters/utils.d.ts +17 -0
  78. package/dist/mcp/formatters/utils.d.ts.map +1 -0
  79. package/dist/mcp/formatters/utils.js +55 -0
  80. package/dist/mcp/formatters/utils.js.map +1 -0
  81. package/dist/mcp/graph-operations.d.ts +242 -0
  82. package/dist/mcp/graph-operations.d.ts.map +1 -0
  83. package/dist/mcp/graph-operations.js +532 -0
  84. package/dist/mcp/graph-operations.js.map +1 -0
  85. package/dist/mcp-server.js +460 -32
  86. package/dist/mcp-server.js.map +1 -1
  87. package/dist/types/index.d.ts +153 -0
  88. package/dist/types/index.d.ts.map +1 -1
  89. package/dist/version.d.ts +3 -3
  90. package/dist/version.js +3 -3
  91. package/dist/version.js.map +1 -1
  92. package/package.json +1 -1
  93. package/dist/mcp/formatters.d.ts +0 -100
  94. package/dist/mcp/formatters.d.ts.map +0 -1
  95. package/dist/mcp/formatters.js +0 -1411
  96. package/dist/mcp/formatters.js.map +0 -1
@@ -0,0 +1,354 @@
1
+ "use strict";
2
+ /**
3
+ * Shared validation module for concept/edge CRUD (ADR-089 Phase 2).
4
+ *
5
+ * These validators are used by both interactive wizard and non-interactive
6
+ * flag-based creation. They ensure graph integrity at all control levels
7
+ * (envelope protection).
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.validateOntology = validateOntology;
11
+ exports.validateConceptId = validateConceptId;
12
+ exports.validateVocabTerm = validateVocabTerm;
13
+ exports.searchVocabTerms = searchVocabTerms;
14
+ exports.searchConceptsByLabel = searchConceptsByLabel;
15
+ exports.matchConceptByDescription = matchConceptByDescription;
16
+ exports.validateEdgeCreation = validateEdgeCreation;
17
+ exports.resolveConceptByLabel = resolveConceptByLabel;
18
+ /**
19
+ * Validate that an ontology exists.
20
+ */
21
+ async function validateOntology(client, ontologyName) {
22
+ try {
23
+ const ontologies = await client.listOntologies();
24
+ const exists = ontologies.ontologies.some((o) => o.ontology.toLowerCase() === ontologyName.toLowerCase());
25
+ if (exists) {
26
+ // Find exact case match
27
+ const match = ontologies.ontologies.find((o) => o.ontology.toLowerCase() === ontologyName.toLowerCase());
28
+ return {
29
+ valid: true,
30
+ data: { ontology: match.ontology },
31
+ };
32
+ }
33
+ return {
34
+ valid: false,
35
+ error: `Ontology '${ontologyName}' not found. Use 'kg ontology list' to see available ontologies.`,
36
+ };
37
+ }
38
+ catch (error) {
39
+ return {
40
+ valid: false,
41
+ error: `Failed to validate ontology: ${error.message}`,
42
+ };
43
+ }
44
+ }
45
+ /**
46
+ * Validate that a concept ID exists.
47
+ */
48
+ async function validateConceptId(client, conceptId) {
49
+ try {
50
+ const concept = await client.getConceptById(conceptId);
51
+ return {
52
+ valid: true,
53
+ data: {
54
+ concept_id: concept.concept_id,
55
+ label: concept.label,
56
+ },
57
+ };
58
+ }
59
+ catch (error) {
60
+ if (error.response?.status === 404) {
61
+ return {
62
+ valid: false,
63
+ error: `Concept '${conceptId}' not found.`,
64
+ };
65
+ }
66
+ return {
67
+ valid: false,
68
+ error: `Failed to validate concept: ${error.response?.data?.detail || error.message}`,
69
+ };
70
+ }
71
+ }
72
+ /**
73
+ * Validate a vocabulary term exists, optionally creating it.
74
+ */
75
+ async function validateVocabTerm(client, term, createIfMissing = false) {
76
+ try {
77
+ // Normalize the term (uppercase, underscores)
78
+ const normalizedTerm = term.toUpperCase().replace(/\s+/g, '_').replace(/[^A-Z0-9_]/g, '');
79
+ if (!normalizedTerm) {
80
+ return {
81
+ valid: false,
82
+ error: 'Vocabulary term cannot be empty after normalization.',
83
+ };
84
+ }
85
+ // Try to get similar terms - if the API succeeds, the term exists
86
+ // (API returns 404 if term not found)
87
+ try {
88
+ const similar = await client.getSimilarTypes(normalizedTerm, 5);
89
+ // API succeeded, term exists
90
+ return {
91
+ valid: true,
92
+ data: {
93
+ exists: true,
94
+ term: similar.relationship_type || normalizedTerm,
95
+ similar_terms: similar.similar_types?.slice(0, 3).map((t) => ({
96
+ term: t.relationship_type,
97
+ similarity: t.similarity,
98
+ })),
99
+ },
100
+ };
101
+ }
102
+ catch (apiError) {
103
+ // 404 means term doesn't exist, other errors are actual failures
104
+ if (apiError.response?.status !== 404) {
105
+ throw apiError;
106
+ }
107
+ }
108
+ // Term doesn't exist (got 404)
109
+ if (!createIfMissing) {
110
+ return {
111
+ valid: false,
112
+ error: `Vocabulary term '${normalizedTerm}' not found. Use --create-vocab to create it.`,
113
+ data: {
114
+ exists: false,
115
+ term: normalizedTerm,
116
+ similar_terms: [], // Can't get similar terms for non-existent type
117
+ },
118
+ };
119
+ }
120
+ // Create the new vocab term
121
+ try {
122
+ await client.addEdgeType({
123
+ relationship_type: normalizedTerm,
124
+ category: 'structural', // Default category
125
+ description: `User-created vocabulary term: ${normalizedTerm}`,
126
+ is_builtin: false,
127
+ });
128
+ return {
129
+ valid: true,
130
+ warning: `Created new vocabulary term '${normalizedTerm}'.`,
131
+ data: {
132
+ exists: false,
133
+ created: true,
134
+ term: normalizedTerm,
135
+ },
136
+ };
137
+ }
138
+ catch (createError) {
139
+ return {
140
+ valid: false,
141
+ error: `Failed to create vocabulary term: ${createError.response?.data?.detail || createError.message}`,
142
+ };
143
+ }
144
+ }
145
+ catch (error) {
146
+ return {
147
+ valid: false,
148
+ error: `Failed to validate vocabulary term: ${error.response?.data?.detail || error.message}`,
149
+ };
150
+ }
151
+ }
152
+ /**
153
+ * Search for vocabulary terms by similarity.
154
+ */
155
+ async function searchVocabTerms(client, query, limit = 5) {
156
+ try {
157
+ const similar = await client.getSimilarTypes(query, limit);
158
+ if (!similar.similar_types || similar.similar_types.length === 0) {
159
+ return {
160
+ valid: true,
161
+ data: [],
162
+ };
163
+ }
164
+ return {
165
+ valid: true,
166
+ data: similar.similar_types.map((t) => ({
167
+ term: t.relationship_type,
168
+ similarity: t.similarity,
169
+ })),
170
+ };
171
+ }
172
+ catch (error) {
173
+ return {
174
+ valid: false,
175
+ error: `Failed to search vocabulary: ${error.response?.data?.detail || error.message}`,
176
+ };
177
+ }
178
+ }
179
+ /**
180
+ * Search for concepts by label similarity.
181
+ */
182
+ async function searchConceptsByLabel(client, query, ontology, limit = 5) {
183
+ try {
184
+ const results = await client.searchConcepts({
185
+ query,
186
+ limit,
187
+ min_similarity: 0.5, // Lower threshold for search
188
+ ontology, // Filter by ontology if specified
189
+ });
190
+ return {
191
+ valid: true,
192
+ data: results.results.map((r) => ({
193
+ concept_id: r.concept_id,
194
+ label: r.label,
195
+ similarity: r.score,
196
+ })),
197
+ };
198
+ }
199
+ catch (error) {
200
+ return {
201
+ valid: false,
202
+ error: `Failed to search concepts: ${error.response?.data?.detail || error.message}`,
203
+ };
204
+ }
205
+ }
206
+ /**
207
+ * Match a concept description against existing concepts.
208
+ * Uses the same similarity matching as automatic ingestion.
209
+ *
210
+ * @param description Description to match
211
+ * @param ontology Target ontology
212
+ * @param matchingMode How to handle matches: auto, force_create, match_only
213
+ */
214
+ async function matchConceptByDescription(client, description, ontology, matchingMode = 'auto') {
215
+ if (matchingMode === 'force_create') {
216
+ // Skip matching entirely
217
+ return {
218
+ valid: true,
219
+ data: {
220
+ matched: false,
221
+ created: false,
222
+ },
223
+ };
224
+ }
225
+ try {
226
+ // Search for similar concepts using the description
227
+ const results = await client.searchConcepts({
228
+ query: description,
229
+ limit: 3,
230
+ min_similarity: 0.85, // High threshold for matching
231
+ });
232
+ if (results.results.length > 0) {
233
+ const best = results.results[0];
234
+ return {
235
+ valid: true,
236
+ data: {
237
+ matched: true,
238
+ concept_id: best.concept_id,
239
+ label: best.label,
240
+ similarity: best.score,
241
+ },
242
+ };
243
+ }
244
+ // No match found
245
+ if (matchingMode === 'match_only') {
246
+ return {
247
+ valid: false,
248
+ error: 'No matching concept found and matching_mode is match_only.',
249
+ };
250
+ }
251
+ return {
252
+ valid: true,
253
+ data: {
254
+ matched: false,
255
+ },
256
+ };
257
+ }
258
+ catch (error) {
259
+ return {
260
+ valid: false,
261
+ error: `Failed to match concept: ${error.response?.data?.detail || error.message}`,
262
+ };
263
+ }
264
+ }
265
+ /**
266
+ * Validate all components of an edge creation request.
267
+ */
268
+ async function validateEdgeCreation(client, fromConceptId, toConceptId, relationshipType, options = {}) {
269
+ const errors = [];
270
+ // Validate from concept
271
+ const fromResult = await validateConceptId(client, fromConceptId);
272
+ if (!fromResult.valid) {
273
+ errors.push(`From concept: ${fromResult.error}`);
274
+ }
275
+ // Validate to concept
276
+ const toResult = await validateConceptId(client, toConceptId);
277
+ if (!toResult.valid) {
278
+ errors.push(`To concept: ${toResult.error}`);
279
+ }
280
+ // Validate vocab term
281
+ const vocabResult = await validateVocabTerm(client, relationshipType, options.createVocab);
282
+ if (!vocabResult.valid) {
283
+ errors.push(`Relationship type: ${vocabResult.error}`);
284
+ }
285
+ if (errors.length > 0) {
286
+ return {
287
+ valid: false,
288
+ error: errors.join('\n'),
289
+ };
290
+ }
291
+ return {
292
+ valid: true,
293
+ warning: vocabResult.warning,
294
+ data: {
295
+ from: fromResult.data,
296
+ to: toResult.data,
297
+ type: vocabResult.data.term,
298
+ },
299
+ };
300
+ }
301
+ /**
302
+ * Resolve a concept by label (semantic lookup).
303
+ * Searches for the best matching concept by label.
304
+ */
305
+ async function resolveConceptByLabel(client, label, ontology) {
306
+ try {
307
+ // First try exact label match via list
308
+ const listResult = await client.listConceptsCRUD({
309
+ label_contains: label,
310
+ ontology,
311
+ limit: 10,
312
+ });
313
+ // Check for exact match
314
+ const exactMatch = listResult.concepts.find((c) => c.label.toLowerCase() === label.toLowerCase());
315
+ if (exactMatch) {
316
+ return {
317
+ valid: true,
318
+ data: {
319
+ concept_id: exactMatch.concept_id,
320
+ label: exactMatch.label,
321
+ similarity: 1.0,
322
+ },
323
+ };
324
+ }
325
+ // Fall back to semantic search
326
+ const searchResult = await client.searchConcepts({
327
+ query: label,
328
+ limit: 1,
329
+ min_similarity: 0.7,
330
+ });
331
+ if (searchResult.results.length > 0) {
332
+ const best = searchResult.results[0];
333
+ return {
334
+ valid: true,
335
+ data: {
336
+ concept_id: best.concept_id,
337
+ label: best.label,
338
+ similarity: best.score,
339
+ },
340
+ };
341
+ }
342
+ return {
343
+ valid: false,
344
+ error: `No concept found matching label '${label}'.`,
345
+ };
346
+ }
347
+ catch (error) {
348
+ return {
349
+ valid: false,
350
+ error: `Failed to resolve concept: ${error.response?.data?.detail || error.message}`,
351
+ };
352
+ }
353
+ }
354
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Concept and search result formatters
3
+ */
4
+ import type { SearchResponse, ConceptDetailsResponse, FindConnectionBySearchResponse, RelatedConceptsResponse } from '../../types/index.js';
5
+ /**
6
+ * Format search results as markdown
7
+ */
8
+ export declare function formatSearchResults(result: SearchResponse): string;
9
+ /**
10
+ * Format concept details as markdown
11
+ * @param concept - The concept details to format
12
+ * @param truncateEvidence - Whether to truncate full_text context to 200 chars (default: true)
13
+ */
14
+ export declare function formatConceptDetails(concept: ConceptDetailsResponse, truncateEvidence?: boolean): string;
15
+ /**
16
+ * Format connection paths as markdown
17
+ * Enhanced to match CLI output with full concept details, evidence samples, and path visualization
18
+ */
19
+ export declare function formatConnectionPaths(result: FindConnectionBySearchResponse): string;
20
+ /**
21
+ * Format related concepts as markdown
22
+ */
23
+ export declare function formatRelatedConcepts(result: RelatedConceptsResponse): string;
24
+ //# sourceMappingURL=concept.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concept.d.ts","sourceRoot":"","sources":["../../../src/mcp/formatters/concept.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,8BAA8B,EAC9B,uBAAuB,EACxB,MAAM,sBAAsB,CAAC;AAG9B;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CA6DlE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,GAAE,OAAc,GAAG,MAAM,CAuE9G;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,8BAA8B,GAAG,MAAM,CA8FpF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,uBAAuB,GAAG,MAAM,CAuB7E"}
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ /**
3
+ * Concept and search result formatters
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.formatSearchResults = formatSearchResults;
7
+ exports.formatConceptDetails = formatConceptDetails;
8
+ exports.formatConnectionPaths = formatConnectionPaths;
9
+ exports.formatRelatedConcepts = formatRelatedConcepts;
10
+ const utils_js_1 = require("./utils.js");
11
+ /**
12
+ * Format search results as markdown
13
+ */
14
+ function formatSearchResults(result) {
15
+ let output = `# Search: "${result.query}"\n\n`;
16
+ output += `Found ${result.count} concepts (threshold: ${(result.threshold_used || 0.7) * 100}%)\n\n`;
17
+ if (result.count === 0) {
18
+ output += 'No concepts found matching this query.\n';
19
+ return output;
20
+ }
21
+ result.results.forEach((concept, i) => {
22
+ output += `## ${i + 1}. ${concept.label}\n`;
23
+ if (concept.description) {
24
+ output += `${concept.description}\n\n`;
25
+ }
26
+ output += `ID: ${concept.concept_id}\n`;
27
+ output += `Similarity: ${(concept.score * 100).toFixed(1)}%\n`;
28
+ output += `Documents: ${concept.documents.join(', ')}\n`;
29
+ output += `Evidence: ${concept.evidence_count} instances\n`;
30
+ if (concept.grounding_strength !== undefined || concept.grounding_display) {
31
+ output += `Grounding: ${(0, utils_js_1.formatGroundingWithConfidence)(concept.grounding_strength, concept.grounding_display, concept.confidence_score)}\n`;
32
+ }
33
+ if (concept.diversity_score !== undefined && concept.diversity_score !== null && concept.diversity_related_count !== undefined) {
34
+ output += `Diversity: ${(concept.diversity_score * 100).toFixed(1)}% (${concept.diversity_related_count} related concepts)\n`;
35
+ }
36
+ if (concept.authenticated_diversity !== undefined && concept.authenticated_diversity !== null) {
37
+ const authDiv = concept.authenticated_diversity;
38
+ const sign = authDiv >= 0 ? '+' : '';
39
+ // Near-zero values (|authDiv| < 0.05) are "unclear" - grounding too weak to authenticate
40
+ const status = Math.abs(authDiv) < 0.05 ? 'unclear ◯' :
41
+ authDiv > 0.3 ? 'diverse support ✅' :
42
+ authDiv > 0 ? 'some support ✓' :
43
+ authDiv > -0.3 ? 'weak contradiction ⚠' :
44
+ 'diverse contradiction ❌';
45
+ output += `Authenticated: ${sign}${(Math.abs(authDiv) * 100).toFixed(1)}% (${status})\n`;
46
+ }
47
+ if (concept.sample_evidence && concept.sample_evidence.length > 0) {
48
+ output += `\nSample Evidence (${concept.sample_evidence.length} of ${concept.evidence_count}):\n`;
49
+ concept.sample_evidence.forEach((inst, idx) => {
50
+ const truncated = inst.quote.length > 120 ? inst.quote.substring(0, 120) + '...' : inst.quote;
51
+ output += `${idx + 1}. ${inst.document} (para ${inst.paragraph}): "${truncated}"\n`;
52
+ // ADR-057: Indicate if this evidence has an image
53
+ if (inst.has_image && inst.source_id) {
54
+ output += ` [IMAGE] Use get_source_image("${inst.source_id}") to view original image\n`;
55
+ }
56
+ });
57
+ output += `Tip: Use get_concept_details("${concept.concept_id}") for all evidence\n`;
58
+ }
59
+ output += '\n';
60
+ });
61
+ if (result.below_threshold_count && result.below_threshold_count > 0 && result.suggested_threshold) {
62
+ const thresholdPercent = (result.suggested_threshold * 100).toFixed(0);
63
+ output += `Note: ${result.below_threshold_count} additional concepts available at ${thresholdPercent}% threshold\n`;
64
+ }
65
+ return output;
66
+ }
67
+ /**
68
+ * Format concept details as markdown
69
+ * @param concept - The concept details to format
70
+ * @param truncateEvidence - Whether to truncate full_text context to 200 chars (default: true)
71
+ */
72
+ function formatConceptDetails(concept, truncateEvidence = true) {
73
+ let output = `# Concept: ${concept.label}\n\n`;
74
+ if (concept.description) {
75
+ output += `${concept.description}\n\n`;
76
+ }
77
+ output += `ID: ${concept.concept_id}\n`;
78
+ output += `Search Terms: ${concept.search_terms.join(', ')}\n`;
79
+ output += `Documents: ${concept.documents.join(', ')}\n`;
80
+ if (concept.grounding_strength !== undefined || concept.grounding_display) {
81
+ output += `Grounding: ${(0, utils_js_1.formatGroundingWithConfidence)(concept.grounding_strength, concept.grounding_display, concept.confidence_score)}\n`;
82
+ }
83
+ if (concept.diversity_score !== undefined && concept.diversity_score !== null && concept.diversity_related_count !== undefined) {
84
+ output += `Diversity: ${(concept.diversity_score * 100).toFixed(1)}% (${concept.diversity_related_count} related concepts)\n`;
85
+ }
86
+ if (concept.authenticated_diversity !== undefined && concept.authenticated_diversity !== null) {
87
+ const authDiv = concept.authenticated_diversity;
88
+ const sign = authDiv >= 0 ? '+' : '';
89
+ // Near-zero values (|authDiv| < 0.05) are "unclear" - grounding too weak to authenticate
90
+ const status = Math.abs(authDiv) < 0.05 ? 'unclear ◯' :
91
+ authDiv > 0.3 ? 'diverse support ✅' :
92
+ authDiv > 0 ? 'some support ✓' :
93
+ authDiv > -0.3 ? 'weak contradiction ⚠' :
94
+ 'diverse contradiction ❌';
95
+ output += `Authenticated: ${sign}${(Math.abs(authDiv) * 100).toFixed(1)}% (${status})\n`;
96
+ }
97
+ output += `\n## Evidence (${concept.instances.length} instances)\n\n`;
98
+ concept.instances.forEach((inst, i) => {
99
+ output += `${i + 1}. ${inst.document} (para ${inst.paragraph}): "${inst.quote}"\n`;
100
+ // Include full context for chapter/verse citation if available
101
+ if (inst.full_text) {
102
+ // Extract chapter/verse from full_text (e.g., "# Chapter 46\n\n1. So Israel...")
103
+ const chapterMatch = inst.full_text.match(/^#\s*Chapter\s+(\d+)/i);
104
+ if (chapterMatch) {
105
+ output += ` Context: Chapter ${chapterMatch[1]}\n`;
106
+ }
107
+ // Show full context or truncated based on parameter
108
+ const cleanedContext = inst.full_text.replace(/^#[^\n]*\n+/, '');
109
+ if (cleanedContext && cleanedContext !== inst.quote) {
110
+ if (truncateEvidence && cleanedContext.length > 200) {
111
+ // Truncate to 200 chars for token efficiency
112
+ output += ` Full context: ${cleanedContext.substring(0, 200)}...\n`;
113
+ }
114
+ else {
115
+ // Show complete context
116
+ output += ` Full context: ${cleanedContext}\n`;
117
+ }
118
+ }
119
+ }
120
+ // ADR-057: Indicate if this evidence has an image
121
+ if (inst.has_image && inst.source_id) {
122
+ output += ` Source: ${inst.source_id} [IMAGE AVAILABLE]\n`;
123
+ output += ` Use get_source_image("${inst.source_id}") to view and verify the original image\n`;
124
+ }
125
+ });
126
+ if (concept.relationships.length > 0) {
127
+ output += `\n## Relationships (${concept.relationships.length})\n\n`;
128
+ concept.relationships.forEach(rel => {
129
+ const confidence = rel.confidence ? ` (${(rel.confidence * 100).toFixed(0)}%)` : '';
130
+ output += `${rel.rel_type} -> ${rel.to_label}${confidence}\n`;
131
+ });
132
+ }
133
+ else {
134
+ output += '\nNo outgoing relationships\n';
135
+ }
136
+ return output;
137
+ }
138
+ /**
139
+ * Format connection paths as markdown
140
+ * Enhanced to match CLI output with full concept details, evidence samples, and path visualization
141
+ */
142
+ function formatConnectionPaths(result) {
143
+ let output = `# Connection: ${result.from_concept?.label || result.from_query} -> ${result.to_concept?.label || result.to_query}\n\n`;
144
+ output += `From Match: ${(result.from_similarity * 100).toFixed(1)}%\n`;
145
+ output += `To Match: ${(result.to_similarity * 100).toFixed(1)}%\n`;
146
+ output += `Max Hops: ${result.max_hops}\n\n`;
147
+ if (result.count === 0) {
148
+ output += `No connection found within ${result.max_hops} hops\n`;
149
+ return output;
150
+ }
151
+ output += `Found ${result.count} path(s):\n\n`;
152
+ result.paths.forEach((path, pathIdx) => {
153
+ output += `## Path ${pathIdx + 1} (${path.hops} hop${path.hops !== 1 ? 's' : ''})\n\n`;
154
+ // Full path visualization with arrows
155
+ output += '### Path Overview\n\n';
156
+ const pathSegments = [];
157
+ path.nodes.forEach((node, j) => {
158
+ pathSegments.push(node.label);
159
+ if (j < path.relationships.length) {
160
+ pathSegments.push(`↓ ${path.relationships[j]}`);
161
+ }
162
+ });
163
+ output += pathSegments.join('\n') + '\n\n';
164
+ // Detailed concept information for each node
165
+ path.nodes.forEach((node, nodeIdx) => {
166
+ output += `### ${nodeIdx + 1}. ${node.label}\n\n`;
167
+ // Concept ID and description
168
+ output += `**ID:** ${node.id}\n`;
169
+ if (node.description) {
170
+ output += `**Description:** ${node.description}\n`;
171
+ }
172
+ // Grounding strength with confidence-awareness
173
+ if (node.grounding_strength !== undefined || node.grounding_display) {
174
+ output += `**Grounding:** ${(0, utils_js_1.formatGroundingWithConfidence)(node.grounding_strength, node.grounding_display, node.confidence_score)}\n`;
175
+ }
176
+ // Diversity metrics if available
177
+ if (node.diversity_score !== undefined && node.diversity_score !== null && node.diversity_related_count !== undefined) {
178
+ output += `**Diversity:** ${(node.diversity_score * 100).toFixed(1)}% (${node.diversity_related_count} related concepts)\n`;
179
+ }
180
+ // Authenticated diversity if available
181
+ if (node.authenticated_diversity !== undefined && node.authenticated_diversity !== null) {
182
+ const authDiv = node.authenticated_diversity;
183
+ const sign = authDiv >= 0 ? '+' : '';
184
+ // Near-zero values (|authDiv| < 0.05) are "unclear" - grounding too weak to authenticate
185
+ const status = Math.abs(authDiv) < 0.05 ? 'unclear ◯' :
186
+ authDiv > 0.3 ? 'diverse support ✅' :
187
+ authDiv > 0 ? 'some support ✓' :
188
+ authDiv > -0.3 ? 'weak contradiction ⚠' :
189
+ 'diverse contradiction ❌';
190
+ output += `**Authenticated:** ${sign}${(Math.abs(authDiv) * 100).toFixed(1)}% (${status})\n`;
191
+ }
192
+ // Evidence samples (limit to 3 for token efficiency)
193
+ if (node.sample_evidence && node.sample_evidence.length > 0) {
194
+ const evidenceCount = node.sample_evidence.length;
195
+ output += `\n**Evidence (${evidenceCount} sample${evidenceCount !== 1 ? 's' : ''}):**\n\n`;
196
+ node.sample_evidence.slice(0, 3).forEach((inst, idx) => {
197
+ const truncated = inst.quote.length > 150 ? inst.quote.substring(0, 150) + '...' : inst.quote;
198
+ output += `${idx + 1}. ${inst.document} (para ${inst.paragraph}):\n`;
199
+ output += ` "${truncated}"\n`;
200
+ // ADR-057: Image availability
201
+ if (inst.has_image && inst.source_id) {
202
+ output += ` [IMAGE AVAILABLE] Use get_source_image("${inst.source_id}") to view\n`;
203
+ }
204
+ });
205
+ if (evidenceCount > 3) {
206
+ output += ` ... and ${evidenceCount - 3} more samples\n`;
207
+ output += ` Use get_concept_details("${node.id}") for all evidence\n`;
208
+ }
209
+ }
210
+ // Show relationship to next node
211
+ if (nodeIdx < path.relationships.length) {
212
+ output += `\n**→ ${path.relationships[nodeIdx]}**\n`;
213
+ }
214
+ output += '\n';
215
+ });
216
+ output += '---\n\n';
217
+ });
218
+ return output;
219
+ }
220
+ /**
221
+ * Format related concepts as markdown
222
+ */
223
+ function formatRelatedConcepts(result) {
224
+ let output = `# Related Concepts\n\n`;
225
+ output += `From: ${result.concept_id}\n`;
226
+ output += `Max Depth: ${result.max_depth}\n`;
227
+ output += `Found: ${result.count} concepts\n\n`;
228
+ if (result.count === 0) {
229
+ output += 'No related concepts found\n';
230
+ return output;
231
+ }
232
+ let currentDistance = -1;
233
+ result.results.forEach(concept => {
234
+ if (concept.distance !== currentDistance) {
235
+ currentDistance = concept.distance;
236
+ output += `\n## Distance ${currentDistance}\n\n`;
237
+ }
238
+ output += `${concept.label} (${concept.concept_id})\n`;
239
+ output += `Path: ${concept.path_types.join(' -> ')}\n`;
240
+ });
241
+ return output;
242
+ }
243
+ //# sourceMappingURL=concept.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concept.js","sourceRoot":"","sources":["../../../src/mcp/formatters/concept.ts"],"names":[],"mappings":"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"}