@aaronsb/kg-cli 0.6.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.md +112 -0
- package/dist/api/client.d.ts +867 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +1362 -0
- package/dist/api/client.js.map +1 -0
- package/dist/cli/admin/backup.d.ts +9 -0
- package/dist/cli/admin/backup.d.ts.map +1 -0
- package/dist/cli/admin/backup.js +363 -0
- package/dist/cli/admin/backup.js.map +1 -0
- package/dist/cli/admin/index.d.ts +7 -0
- package/dist/cli/admin/index.d.ts.map +1 -0
- package/dist/cli/admin/index.js +52 -0
- package/dist/cli/admin/index.js.map +1 -0
- package/dist/cli/admin/scheduler.d.ts +7 -0
- package/dist/cli/admin/scheduler.d.ts.map +1 -0
- package/dist/cli/admin/scheduler.js +125 -0
- package/dist/cli/admin/scheduler.js.map +1 -0
- package/dist/cli/admin/status.d.ts +7 -0
- package/dist/cli/admin/status.d.ts.map +1 -0
- package/dist/cli/admin/status.js +134 -0
- package/dist/cli/admin/status.js.map +1 -0
- package/dist/cli/admin/utils.d.ts +34 -0
- package/dist/cli/admin/utils.d.ts.map +1 -0
- package/dist/cli/admin/utils.js +441 -0
- package/dist/cli/admin/utils.js.map +1 -0
- package/dist/cli/ai-config/embedding.d.ts +11 -0
- package/dist/cli/ai-config/embedding.d.ts.map +1 -0
- package/dist/cli/ai-config/embedding.js +598 -0
- package/dist/cli/ai-config/embedding.js.map +1 -0
- package/dist/cli/ai-config/extraction.d.ts +11 -0
- package/dist/cli/ai-config/extraction.d.ts.map +1 -0
- package/dist/cli/ai-config/extraction.js +206 -0
- package/dist/cli/ai-config/extraction.js.map +1 -0
- package/dist/cli/ai-config/index.d.ts +21 -0
- package/dist/cli/ai-config/index.d.ts.map +1 -0
- package/dist/cli/ai-config/index.js +27 -0
- package/dist/cli/ai-config/index.js.map +1 -0
- package/dist/cli/ai-config/keys.d.ts +11 -0
- package/dist/cli/ai-config/keys.d.ts.map +1 -0
- package/dist/cli/ai-config/keys.js +182 -0
- package/dist/cli/ai-config/keys.js.map +1 -0
- package/dist/cli/ai-config/utils.d.ts +13 -0
- package/dist/cli/ai-config/utils.d.ts.map +1 -0
- package/dist/cli/ai-config/utils.js +84 -0
- package/dist/cli/ai-config/utils.js.map +1 -0
- package/dist/cli/artifact.d.ts +8 -0
- package/dist/cli/artifact.d.ts.map +1 -0
- package/dist/cli/artifact.js +296 -0
- package/dist/cli/artifact.js.map +1 -0
- package/dist/cli/auth-admin.d.ts +11 -0
- package/dist/cli/auth-admin.d.ts.map +1 -0
- package/dist/cli/auth-admin.js +415 -0
- package/dist/cli/auth-admin.js.map +1 -0
- package/dist/cli/colors.d.ts +105 -0
- package/dist/cli/colors.d.ts.map +1 -0
- package/dist/cli/colors.js +164 -0
- package/dist/cli/colors.js.map +1 -0
- package/dist/cli/commands.d.ts +6 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +164 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/config.d.ts +6 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +694 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/curve-viz.d.ts +89 -0
- package/dist/cli/curve-viz.d.ts.map +1 -0
- package/dist/cli/curve-viz.js +228 -0
- package/dist/cli/curve-viz.js.map +1 -0
- package/dist/cli/database.d.ts +6 -0
- package/dist/cli/database.d.ts.map +1 -0
- package/dist/cli/database.js +324 -0
- package/dist/cli/database.js.map +1 -0
- package/dist/cli/document.d.ts +6 -0
- package/dist/cli/document.d.ts.map +1 -0
- package/dist/cli/document.js +458 -0
- package/dist/cli/document.js.map +1 -0
- package/dist/cli/group.d.ts +8 -0
- package/dist/cli/group.d.ts.map +1 -0
- package/dist/cli/group.js +174 -0
- package/dist/cli/group.js.map +1 -0
- package/dist/cli/health.d.ts +6 -0
- package/dist/cli/health.d.ts.map +1 -0
- package/dist/cli/health.js +34 -0
- package/dist/cli/health.js.map +1 -0
- package/dist/cli/help-formatter.d.ts +16 -0
- package/dist/cli/help-formatter.d.ts.map +1 -0
- package/dist/cli/help-formatter.js +248 -0
- package/dist/cli/help-formatter.js.map +1 -0
- package/dist/cli/help.d.ts +9 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +227 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/ingest.d.ts +6 -0
- package/dist/cli/ingest.d.ts.map +1 -0
- package/dist/cli/ingest.js +722 -0
- package/dist/cli/ingest.js.map +1 -0
- package/dist/cli/jobs.d.ts +6 -0
- package/dist/cli/jobs.d.ts.map +1 -0
- package/dist/cli/jobs.js +663 -0
- package/dist/cli/jobs.js.map +1 -0
- package/dist/cli/login.d.ts +21 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/login.js +221 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/logout.d.ts +16 -0
- package/dist/cli/logout.d.ts.map +1 -0
- package/dist/cli/logout.js +141 -0
- package/dist/cli/logout.js.map +1 -0
- package/dist/cli/mcp-config.d.ts +10 -0
- package/dist/cli/mcp-config.d.ts.map +1 -0
- package/dist/cli/mcp-config.js +358 -0
- package/dist/cli/mcp-config.js.map +1 -0
- package/dist/cli/oauth.d.ts +15 -0
- package/dist/cli/oauth.d.ts.map +1 -0
- package/dist/cli/oauth.js +296 -0
- package/dist/cli/oauth.js.map +1 -0
- package/dist/cli/ontology.d.ts +6 -0
- package/dist/cli/ontology.d.ts.map +1 -0
- package/dist/cli/ontology.js +231 -0
- package/dist/cli/ontology.js.map +1 -0
- package/dist/cli/polarity.d.ts +6 -0
- package/dist/cli/polarity.d.ts.map +1 -0
- package/dist/cli/polarity.js +295 -0
- package/dist/cli/polarity.js.map +1 -0
- package/dist/cli/projection.d.ts +8 -0
- package/dist/cli/projection.d.ts.map +1 -0
- package/dist/cli/projection.js +297 -0
- package/dist/cli/projection.js.map +1 -0
- package/dist/cli/query-def.d.ts +8 -0
- package/dist/cli/query-def.d.ts.map +1 -0
- package/dist/cli/query-def.js +163 -0
- package/dist/cli/query-def.js.map +1 -0
- package/dist/cli/rbac.d.ts +12 -0
- package/dist/cli/rbac.d.ts.map +1 -0
- package/dist/cli/rbac.js +615 -0
- package/dist/cli/rbac.js.map +1 -0
- package/dist/cli/search.d.ts +6 -0
- package/dist/cli/search.d.ts.map +1 -0
- package/dist/cli/search.js +829 -0
- package/dist/cli/search.js.map +1 -0
- package/dist/cli/source.d.ts +6 -0
- package/dist/cli/source.d.ts.map +1 -0
- package/dist/cli/source.js +202 -0
- package/dist/cli/source.js.map +1 -0
- package/dist/cli/verb-router.d.ts +25 -0
- package/dist/cli/verb-router.d.ts.map +1 -0
- package/dist/cli/verb-router.js +415 -0
- package/dist/cli/verb-router.js.map +1 -0
- package/dist/cli/vocabulary/config.d.ts +7 -0
- package/dist/cli/vocabulary/config.d.ts.map +1 -0
- package/dist/cli/vocabulary/config.js +201 -0
- package/dist/cli/vocabulary/config.js.map +1 -0
- package/dist/cli/vocabulary/consolidate.d.ts +8 -0
- package/dist/cli/vocabulary/consolidate.d.ts.map +1 -0
- package/dist/cli/vocabulary/consolidate.js +192 -0
- package/dist/cli/vocabulary/consolidate.js.map +1 -0
- package/dist/cli/vocabulary/embeddings.d.ts +9 -0
- package/dist/cli/vocabulary/embeddings.d.ts.map +1 -0
- package/dist/cli/vocabulary/embeddings.js +205 -0
- package/dist/cli/vocabulary/embeddings.js.map +1 -0
- package/dist/cli/vocabulary/epistemic.d.ts +7 -0
- package/dist/cli/vocabulary/epistemic.d.ts.map +1 -0
- package/dist/cli/vocabulary/epistemic.js +315 -0
- package/dist/cli/vocabulary/epistemic.js.map +1 -0
- package/dist/cli/vocabulary/index.d.ts +7 -0
- package/dist/cli/vocabulary/index.d.ts.map +1 -0
- package/dist/cli/vocabulary/index.js +45 -0
- package/dist/cli/vocabulary/index.js.map +1 -0
- package/dist/cli/vocabulary/profiles.d.ts +7 -0
- package/dist/cli/vocabulary/profiles.d.ts.map +1 -0
- package/dist/cli/vocabulary/profiles.js +171 -0
- package/dist/cli/vocabulary/profiles.js.map +1 -0
- package/dist/cli/vocabulary/similarity.d.ts +9 -0
- package/dist/cli/vocabulary/similarity.d.ts.map +1 -0
- package/dist/cli/vocabulary/similarity.js +199 -0
- package/dist/cli/vocabulary/similarity.js.map +1 -0
- package/dist/cli/vocabulary/status.d.ts +8 -0
- package/dist/cli/vocabulary/status.d.ts.map +1 -0
- package/dist/cli/vocabulary/status.js +280 -0
- package/dist/cli/vocabulary/status.js.map +1 -0
- package/dist/cli/vocabulary/sync.d.ts +7 -0
- package/dist/cli/vocabulary/sync.d.ts.map +1 -0
- package/dist/cli/vocabulary/sync.js +111 -0
- package/dist/cli/vocabulary/sync.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/auth/auth-client.d.ts +247 -0
- package/dist/lib/auth/auth-client.d.ts.map +1 -0
- package/dist/lib/auth/auth-client.js +305 -0
- package/dist/lib/auth/auth-client.js.map +1 -0
- package/dist/lib/auth/challenge.d.ts +39 -0
- package/dist/lib/auth/challenge.d.ts.map +1 -0
- package/dist/lib/auth/challenge.js +125 -0
- package/dist/lib/auth/challenge.js.map +1 -0
- package/dist/lib/auth/client-credentials-flow.d.ts +58 -0
- package/dist/lib/auth/client-credentials-flow.d.ts.map +1 -0
- package/dist/lib/auth/client-credentials-flow.js +118 -0
- package/dist/lib/auth/client-credentials-flow.js.map +1 -0
- package/dist/lib/auth/device-flow.d.ts +75 -0
- package/dist/lib/auth/device-flow.d.ts.map +1 -0
- package/dist/lib/auth/device-flow.js +177 -0
- package/dist/lib/auth/device-flow.js.map +1 -0
- package/dist/lib/auth/index.d.ts +14 -0
- package/dist/lib/auth/index.d.ts.map +1 -0
- package/dist/lib/auth/index.js +34 -0
- package/dist/lib/auth/index.js.map +1 -0
- package/dist/lib/auth/oauth-types.d.ts +69 -0
- package/dist/lib/auth/oauth-types.d.ts.map +1 -0
- package/dist/lib/auth/oauth-types.js +10 -0
- package/dist/lib/auth/oauth-types.js.map +1 -0
- package/dist/lib/auth/oauth-utils.d.ts +51 -0
- package/dist/lib/auth/oauth-utils.d.ts.map +1 -0
- package/dist/lib/auth/oauth-utils.js +110 -0
- package/dist/lib/auth/oauth-utils.js.map +1 -0
- package/dist/lib/auth/token-manager.d.ts +87 -0
- package/dist/lib/auth/token-manager.d.ts.map +1 -0
- package/dist/lib/auth/token-manager.js +139 -0
- package/dist/lib/auth/token-manager.js.map +1 -0
- package/dist/lib/auth/token-refresh.d.ts +63 -0
- package/dist/lib/auth/token-refresh.d.ts.map +1 -0
- package/dist/lib/auth/token-refresh.js +141 -0
- package/dist/lib/auth/token-refresh.js.map +1 -0
- package/dist/lib/config.d.ts +286 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +537 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/job-stream.d.ts +53 -0
- package/dist/lib/job-stream.d.ts.map +1 -0
- package/dist/lib/job-stream.js +153 -0
- package/dist/lib/job-stream.js.map +1 -0
- package/dist/lib/mcp-allowlist.d.ts +101 -0
- package/dist/lib/mcp-allowlist.d.ts.map +1 -0
- package/dist/lib/mcp-allowlist.js +340 -0
- package/dist/lib/mcp-allowlist.js.map +1 -0
- package/dist/lib/table-example.d.ts +7 -0
- package/dist/lib/table-example.d.ts.map +1 -0
- package/dist/lib/table-example.js +105 -0
- package/dist/lib/table-example.js.map +1 -0
- package/dist/lib/table.d.ts +95 -0
- package/dist/lib/table.d.ts.map +1 -0
- package/dist/lib/table.js +263 -0
- package/dist/lib/table.js.map +1 -0
- package/dist/lib/terminal-images.d.ts +66 -0
- package/dist/lib/terminal-images.d.ts.map +1 -0
- package/dist/lib/terminal-images.js +268 -0
- package/dist/lib/terminal-images.js.map +1 -0
- package/dist/mcp/formatters.d.ts +100 -0
- package/dist/mcp/formatters.d.ts.map +1 -0
- package/dist/mcp/formatters.js +1411 -0
- package/dist/mcp/formatters.js.map +1 -0
- package/dist/mcp-server.d.ts +9 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +1810 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/types/index.d.ts +742 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/version.d.ts +10 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +13 -0
- package/dist/version.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,829 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Search and Query Commands
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.searchCommand = void 0;
|
|
40
|
+
const commander_1 = require("commander");
|
|
41
|
+
const client_1 = require("../api/client");
|
|
42
|
+
const colors = __importStar(require("./colors"));
|
|
43
|
+
const colors_1 = require("./colors");
|
|
44
|
+
const help_formatter_1 = require("./help-formatter");
|
|
45
|
+
const config_1 = require("../lib/config");
|
|
46
|
+
const terminal_images_1 = require("../lib/terminal-images");
|
|
47
|
+
const nodePath = __importStar(require("path"));
|
|
48
|
+
/**
|
|
49
|
+
* Format grounding strength for display (ADR-044)
|
|
50
|
+
* This is the fallback when grounding_display is not available.
|
|
51
|
+
*/
|
|
52
|
+
function formatGroundingStrength(grounding) {
|
|
53
|
+
const groundingValue = grounding.toFixed(3);
|
|
54
|
+
const percentValue = grounding * 100;
|
|
55
|
+
// Use ā symbol when value is very close to zero but not exactly zero
|
|
56
|
+
const groundingPercent = (Math.abs(percentValue) < 0.1 && percentValue !== 0)
|
|
57
|
+
? `ā${percentValue >= 0 ? '0' : '-0'}`
|
|
58
|
+
: percentValue.toFixed(0);
|
|
59
|
+
if (grounding >= 0.7) {
|
|
60
|
+
return colors.status.success(`ā Strong (${groundingValue}, ${groundingPercent}%)`);
|
|
61
|
+
}
|
|
62
|
+
else if (grounding >= 0.3) {
|
|
63
|
+
return colors.status.warning(`ā” Moderate (${groundingValue}, ${groundingPercent}%)`);
|
|
64
|
+
}
|
|
65
|
+
else if (grounding >= 0) {
|
|
66
|
+
return colors.status.dim(`⯠Weak (${groundingValue}, ${groundingPercent}%)`);
|
|
67
|
+
}
|
|
68
|
+
else if (grounding >= -0.3) {
|
|
69
|
+
return colors.status.warning(`ā Negative (${groundingValue}, ${groundingPercent}%)`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
return colors.status.error(`ā Contradicted (${groundingValue}, ${groundingPercent}%)`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Format grounding with confidence-awareness (grounding Ć confidence two-dimensional model)
|
|
77
|
+
*
|
|
78
|
+
* Uses grounding_display when available (categorical label from API).
|
|
79
|
+
* Includes numeric confidence_score alongside the label for quantitative insight.
|
|
80
|
+
* Falls back to raw grounding score display for backwards compatibility.
|
|
81
|
+
*
|
|
82
|
+
* The grounding_display labels come from a 3Ć3 matrix:
|
|
83
|
+
* | Grounding Ć Confidence | Display |
|
|
84
|
+
* |------------------------|---------|
|
|
85
|
+
* | Positive + Confident | "Well-supported" |
|
|
86
|
+
* | Positive + Tentative | "Some support (limited data)" |
|
|
87
|
+
* | Positive + Insufficient| "Possibly supported (needs exploration)" |
|
|
88
|
+
* | Neutral + Confident | "Balanced perspectives" |
|
|
89
|
+
* | Neutral + Tentative | "Unclear" |
|
|
90
|
+
* | Neutral + Insufficient | "Unexplored" |
|
|
91
|
+
* | Negative + Confident | "Contested" |
|
|
92
|
+
* | Negative + Tentative | "Possibly contested" |
|
|
93
|
+
* | Negative + Insufficient| "Unknown (needs exploration)" |
|
|
94
|
+
*/
|
|
95
|
+
function formatGroundingWithConfidence(grounding, groundingDisplay, confidenceLevel, confidenceScore = null) {
|
|
96
|
+
// Format confidence score as percentage if available
|
|
97
|
+
const confScoreStr = confidenceScore !== undefined && confidenceScore !== null
|
|
98
|
+
? ` [${(confidenceScore * 100).toFixed(0)}% conf]`
|
|
99
|
+
: '';
|
|
100
|
+
// If we have a grounding_display label from the API, use it with appropriate styling
|
|
101
|
+
if (groundingDisplay) {
|
|
102
|
+
// Style based on the label content
|
|
103
|
+
if (groundingDisplay.includes('Well-supported')) {
|
|
104
|
+
return colors.status.success(`ā ${groundingDisplay}`) + colors.status.dim(confScoreStr);
|
|
105
|
+
}
|
|
106
|
+
else if (groundingDisplay.includes('Contested')) {
|
|
107
|
+
return colors.status.error(`ā ${groundingDisplay}`) + colors.status.dim(confScoreStr);
|
|
108
|
+
}
|
|
109
|
+
else if (groundingDisplay.includes('Unexplored') || groundingDisplay.includes('Unknown')) {
|
|
110
|
+
return colors.status.dim(`⯠${groundingDisplay}${confScoreStr}`);
|
|
111
|
+
}
|
|
112
|
+
else if (groundingDisplay.includes('limited data') || groundingDisplay.includes('needs exploration')) {
|
|
113
|
+
return colors.status.warning(`ā” ${groundingDisplay}`) + colors.status.dim(confScoreStr);
|
|
114
|
+
}
|
|
115
|
+
else if (groundingDisplay.includes('Balanced')) {
|
|
116
|
+
return colors.status.dim(`ā ${groundingDisplay}${confScoreStr}`);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Default styling for other labels
|
|
120
|
+
return colors.status.dim(`⯠${groundingDisplay}${confScoreStr}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Fall back to raw grounding score display if available
|
|
124
|
+
if (grounding !== undefined && grounding !== null) {
|
|
125
|
+
return formatGroundingStrength(grounding);
|
|
126
|
+
}
|
|
127
|
+
// No grounding information available
|
|
128
|
+
return colors.status.dim('⯠Unexplored');
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Format diversity score for display (ADR-063)
|
|
132
|
+
*/
|
|
133
|
+
function formatDiversity(diversity, relatedCount) {
|
|
134
|
+
const diversityPercent = (diversity * 100).toFixed(1);
|
|
135
|
+
if (diversity > 0.6) {
|
|
136
|
+
return colors.status.success(`š Very High (${diversityPercent}%, ${relatedCount} concepts)`);
|
|
137
|
+
}
|
|
138
|
+
else if (diversity > 0.4) {
|
|
139
|
+
return colors.status.success(`š High (${diversityPercent}%, ${relatedCount} concepts)`);
|
|
140
|
+
}
|
|
141
|
+
else if (diversity > 0.2) {
|
|
142
|
+
return colors.status.warning(`ā Moderate (${diversityPercent}%, ${relatedCount} concepts)`);
|
|
143
|
+
}
|
|
144
|
+
else if (diversity > 0.1) {
|
|
145
|
+
return colors.status.dim(`ā Low (${diversityPercent}%, ${relatedCount} concepts)`);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
return colors.status.error(`⯠Very Low (${diversityPercent}%, ${relatedCount} concepts)`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Format authenticated diversity for display (ADR-044 + ADR-063)
|
|
153
|
+
*/
|
|
154
|
+
function formatAuthenticatedDiversity(authDiv) {
|
|
155
|
+
const percent = (Math.abs(authDiv) * 100).toFixed(1);
|
|
156
|
+
if (authDiv > 0.3) {
|
|
157
|
+
return colors.status.success(`ā
+${percent}% (diverse support)`);
|
|
158
|
+
}
|
|
159
|
+
else if (authDiv > 0) {
|
|
160
|
+
return colors.status.dim(`ā +${percent}% (some support)`);
|
|
161
|
+
}
|
|
162
|
+
else if (authDiv > -0.3) {
|
|
163
|
+
return colors.status.warning(`ā ${percent}% (weak contradiction)`);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
return colors.status.error(`ā ${percent}% (diverse contradiction)`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const queryCommand = (0, help_formatter_1.setCommandHelp)(new commander_1.Command('query'), 'Search concepts by semantic similarity', 'Search for concepts using vector similarity (embeddings) - use specific phrases for best results')
|
|
170
|
+
.showHelpAfterError()
|
|
171
|
+
.argument('<query>', 'Natural language search query (2-3 words work best)')
|
|
172
|
+
.option('-l, --limit <number>', 'Maximum number of results to return', '10')
|
|
173
|
+
.option('--min-similarity <number>', 'Minimum similarity score (0.0-1.0, default 0.7=70%, lower to 0.5 for broader matches)', '0.7')
|
|
174
|
+
.option('--no-evidence', 'Hide evidence quotes (shown by default)')
|
|
175
|
+
.option('--no-images', 'Hide inline image display (shown by default if chafa installed)')
|
|
176
|
+
.option('--no-grounding', 'Disable grounding strength calculation (ADR-044 probabilistic truth convergence) for faster results')
|
|
177
|
+
.option('--no-diversity', 'Disable semantic diversity calculation (ADR-063 authenticity signal) for faster results')
|
|
178
|
+
.option('--diversity-hops <number>', 'Maximum traversal depth for diversity (1-3, default 2)', '2')
|
|
179
|
+
.option('--download <directory>', 'Download images to specified directory instead of displaying inline')
|
|
180
|
+
.option('--json', 'Output raw JSON instead of formatted text for scripting')
|
|
181
|
+
.option('--save-artifact', 'Save result as persistent artifact (ADR-083)')
|
|
182
|
+
.action(async (query, options) => {
|
|
183
|
+
try {
|
|
184
|
+
const client = (0, client_1.createClientFromEnv)();
|
|
185
|
+
const config = (0, config_1.getConfig)();
|
|
186
|
+
// Use config defaults, allow CLI flags to override
|
|
187
|
+
// Commander.js --no-evidence flag sets options.evidence to false
|
|
188
|
+
const includeEvidence = options.evidence !== undefined ? options.evidence : config.getSearchShowEvidence();
|
|
189
|
+
const shouldShowImages = options.images !== undefined ? options.images : config.getSearchShowImages();
|
|
190
|
+
const includeGrounding = options.grounding !== false; // Default: true
|
|
191
|
+
const includeDiversity = options.diversity !== false; // Default: true
|
|
192
|
+
const result = await client.searchConcepts({
|
|
193
|
+
query,
|
|
194
|
+
limit: parseInt(options.limit),
|
|
195
|
+
min_similarity: parseFloat(options.minSimilarity),
|
|
196
|
+
include_evidence: includeEvidence,
|
|
197
|
+
include_grounding: includeGrounding,
|
|
198
|
+
include_diversity: includeDiversity,
|
|
199
|
+
diversity_max_hops: parseInt(options.diversityHops)
|
|
200
|
+
});
|
|
201
|
+
// JSON output mode
|
|
202
|
+
if (options.json) {
|
|
203
|
+
console.log(JSON.stringify(result, null, 2));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
console.log('\n' + (0, colors_1.separator)());
|
|
207
|
+
console.log(colors.ui.title(`š Searching for: ${query}`));
|
|
208
|
+
console.log((0, colors_1.separator)());
|
|
209
|
+
console.log(colors.status.success(`\nā Found ${result.count} concepts:\n`));
|
|
210
|
+
for (const [i, concept] of result.results.entries()) {
|
|
211
|
+
const scoreColor = (0, colors_1.getConceptColor)(concept.score);
|
|
212
|
+
console.log(colors.ui.bullet('ā') + ' ' + colors.concept.label(`${i + 1}. ${concept.label}`));
|
|
213
|
+
if (concept.description) {
|
|
214
|
+
console.log(` ${colors.status.dim(concept.description)}`);
|
|
215
|
+
}
|
|
216
|
+
console.log(` ${colors.ui.key('ID:')} ${colors.concept.id(concept.concept_id)}`);
|
|
217
|
+
console.log(` ${colors.ui.key('Similarity:')} ${(0, colors_1.coloredPercentage)(concept.score)}`);
|
|
218
|
+
console.log(` ${colors.ui.key('Documents:')} ${colors.evidence.document(concept.documents.join(', '))}`);
|
|
219
|
+
console.log(` ${colors.ui.key('Evidence:')} ${colors.evidence.count(String(concept.evidence_count))} instances`);
|
|
220
|
+
// Display grounding with confidence-awareness (ADR-044 + grounding Ć confidence model)
|
|
221
|
+
if (concept.grounding_strength !== undefined || concept.grounding_display) {
|
|
222
|
+
console.log(` ${colors.ui.key('Grounding:')} ${formatGroundingWithConfidence(concept.grounding_strength, concept.grounding_display, concept.confidence_level, concept.confidence_score)}`);
|
|
223
|
+
}
|
|
224
|
+
// Display diversity if available (ADR-063)
|
|
225
|
+
if (concept.diversity_score !== undefined && concept.diversity_score !== null && concept.diversity_related_count !== undefined) {
|
|
226
|
+
console.log(` ${colors.ui.key('Diversity:')} ${formatDiversity(concept.diversity_score, concept.diversity_related_count)}`);
|
|
227
|
+
}
|
|
228
|
+
// Display authenticated diversity if available (ADR-044 + ADR-063)
|
|
229
|
+
if (concept.authenticated_diversity !== undefined && concept.authenticated_diversity !== null) {
|
|
230
|
+
console.log(` ${colors.ui.key('Authenticated:')} ${formatAuthenticatedDiversity(concept.authenticated_diversity)}`);
|
|
231
|
+
}
|
|
232
|
+
// Display sample evidence if requested
|
|
233
|
+
if (includeEvidence && concept.sample_evidence && concept.sample_evidence.length > 0) {
|
|
234
|
+
console.log(` ${colors.ui.key('Sample Evidence:')}`);
|
|
235
|
+
for (const [idx, inst] of concept.sample_evidence.entries()) {
|
|
236
|
+
const truncatedQuote = inst.quote.length > 100
|
|
237
|
+
? inst.quote.substring(0, 100) + '...'
|
|
238
|
+
: inst.quote;
|
|
239
|
+
console.log(` ${colors.ui.bullet(`${idx + 1}.`)} ${colors.evidence.document(inst.document)} ${colors.evidence.paragraph(`(para ${inst.paragraph})`)}`);
|
|
240
|
+
console.log(` ${colors.evidence.quote(`"${truncatedQuote}"`)}`);
|
|
241
|
+
// ADR-057: Handle images if available
|
|
242
|
+
if (inst.has_image && inst.source_id) {
|
|
243
|
+
const downloadDir = options.download;
|
|
244
|
+
if (downloadDir) {
|
|
245
|
+
// Download mode
|
|
246
|
+
try {
|
|
247
|
+
console.log(colors.status.dim(` š„ Downloading image from ${inst.source_id}...`));
|
|
248
|
+
const imageBuffer = await client.getSourceImage(inst.source_id);
|
|
249
|
+
const extension = (0, terminal_images_1.detectImageFormat)(imageBuffer);
|
|
250
|
+
const filename = `${inst.source_id}${extension}`;
|
|
251
|
+
const outputPath = nodePath.join(downloadDir, filename);
|
|
252
|
+
if ((0, terminal_images_1.saveImageToFile)(imageBuffer, outputPath)) {
|
|
253
|
+
console.log(colors.status.success(` ā Saved to ${outputPath}`));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
console.log(colors.status.error(` ā Failed to download image: ${error.message}`));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else if (shouldShowImages && config.isChafaEnabled()) {
|
|
261
|
+
// Display mode
|
|
262
|
+
if ((0, terminal_images_1.isChafaAvailable)()) {
|
|
263
|
+
try {
|
|
264
|
+
console.log(colors.status.dim(` š¼ļø Displaying image from ${inst.source_id}...`));
|
|
265
|
+
const imageBuffer = await client.getSourceImage(inst.source_id);
|
|
266
|
+
const extension = (0, terminal_images_1.detectImageFormat)(imageBuffer);
|
|
267
|
+
await (0, terminal_images_1.displayImageBufferWithChafa)(imageBuffer, extension, {
|
|
268
|
+
width: config.getChafaWidth(),
|
|
269
|
+
scale: config.getChafaScale(),
|
|
270
|
+
align: config.getChafaAlign(),
|
|
271
|
+
colors: config.getChafaColors()
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
console.log(colors.status.error(` ā Failed to display image: ${error.message}`));
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
console.log(colors.status.warning(` š¼ļø Image available (source: ${inst.source_id})`));
|
|
280
|
+
(0, terminal_images_1.printChafaInstallInstructions)();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
// Just indicate image is available
|
|
285
|
+
console.log(colors.status.dim(` š¼ļø Image available (use --show-images to display or --download <dir> to save)`));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
console.log();
|
|
291
|
+
}
|
|
292
|
+
// Show hint if additional results available below threshold
|
|
293
|
+
if (result.below_threshold_count && result.below_threshold_count > 0 && result.suggested_threshold) {
|
|
294
|
+
const thresholdPercent = (result.suggested_threshold * 100).toFixed(0);
|
|
295
|
+
console.log(colors.status.warning(`š” ${result.below_threshold_count} additional concept${result.below_threshold_count > 1 ? 's' : ''} available at ${thresholdPercent}% threshold`));
|
|
296
|
+
console.log(colors.status.dim(` Try: kg search query "${query}" --min-similarity ${result.suggested_threshold}\n`));
|
|
297
|
+
}
|
|
298
|
+
// ADR-083: Save result as artifact if requested
|
|
299
|
+
if (options.saveArtifact && result.count > 0) {
|
|
300
|
+
try {
|
|
301
|
+
const artifactResult = await client.createArtifact({
|
|
302
|
+
artifact_type: 'search_result',
|
|
303
|
+
representation: 'cli',
|
|
304
|
+
name: `Search: "${query}" (${result.count} results)`,
|
|
305
|
+
parameters: {
|
|
306
|
+
query,
|
|
307
|
+
limit: parseInt(options.limit),
|
|
308
|
+
min_similarity: parseFloat(options.minSimilarity),
|
|
309
|
+
include_evidence: includeEvidence,
|
|
310
|
+
include_grounding: includeGrounding,
|
|
311
|
+
include_diversity: includeDiversity,
|
|
312
|
+
diversity_max_hops: parseInt(options.diversityHops)
|
|
313
|
+
},
|
|
314
|
+
payload: result
|
|
315
|
+
});
|
|
316
|
+
console.log(colors.status.success(`ā Artifact saved: ${artifactResult.id}`));
|
|
317
|
+
console.log(colors.status.dim(` View: kg artifact show ${artifactResult.id}`));
|
|
318
|
+
}
|
|
319
|
+
catch (artifactError) {
|
|
320
|
+
console.error(colors.status.error(`ā Failed to save artifact: ${artifactError.message}`));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
catch (error) {
|
|
325
|
+
console.error(colors.status.error('ā Search failed'));
|
|
326
|
+
console.error(colors.status.error(error.response?.data?.detail || error.message));
|
|
327
|
+
process.exit(1);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
const showCommand = (0, help_formatter_1.setCommandHelp)(new commander_1.Command('show'), 'Get full details for a concept', 'Get comprehensive details for a concept: all evidence, relationships, sources, and grounding strength')
|
|
331
|
+
.alias('details') // backwards compatibility
|
|
332
|
+
.showHelpAfterError()
|
|
333
|
+
.argument('<concept-id>', 'Concept ID to retrieve (from search results)')
|
|
334
|
+
.option('--no-grounding', 'Disable grounding strength calculation (ADR-044 probabilistic truth convergence) for faster results')
|
|
335
|
+
.option('--json', 'Output raw JSON instead of formatted text for scripting')
|
|
336
|
+
.action(async (conceptId, options) => {
|
|
337
|
+
try {
|
|
338
|
+
const client = (0, client_1.createClientFromEnv)();
|
|
339
|
+
const includeGrounding = options.grounding !== false; // Default: true
|
|
340
|
+
const concept = await client.getConceptDetails(conceptId, includeGrounding);
|
|
341
|
+
// JSON output mode
|
|
342
|
+
if (options.json) {
|
|
343
|
+
console.log(JSON.stringify(concept, null, 2));
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
console.log('\n' + (0, colors_1.separator)());
|
|
347
|
+
console.log(colors.ui.title(`š Concept Details: ${concept.label}`));
|
|
348
|
+
console.log((0, colors_1.separator)());
|
|
349
|
+
console.log(`\n${colors.ui.key('ID:')} ${colors.concept.id(concept.concept_id)}`);
|
|
350
|
+
if (concept.description) {
|
|
351
|
+
console.log(`${colors.ui.key('Description:')} ${colors.status.dim(concept.description)}`);
|
|
352
|
+
}
|
|
353
|
+
console.log(`${colors.ui.key('Search Terms:')} ${colors.concept.searchTerms(concept.search_terms.join(', '))}`);
|
|
354
|
+
console.log(`${colors.ui.key('Documents:')} ${colors.evidence.document(concept.documents.join(', '))}`);
|
|
355
|
+
// Display grounding with confidence-awareness (ADR-044 + grounding Ć confidence model)
|
|
356
|
+
if (concept.grounding_strength !== undefined || concept.grounding_display) {
|
|
357
|
+
console.log(`${colors.ui.key('Grounding:')} ${formatGroundingWithConfidence(concept.grounding_strength, concept.grounding_display, concept.confidence_level, concept.confidence_score)}`);
|
|
358
|
+
}
|
|
359
|
+
console.log('\n' + colors.ui.header(`Evidence (${concept.instances.length} instances)`));
|
|
360
|
+
console.log((0, colors_1.separator)(80, 'ā'));
|
|
361
|
+
concept.instances.forEach((inst, i) => {
|
|
362
|
+
console.log(`\n${colors.ui.bullet(`${i + 1}.`)} ${colors.evidence.document(inst.document)} ${colors.evidence.paragraph(`(para ${inst.paragraph})`)}`);
|
|
363
|
+
console.log(` ${colors.evidence.quote(`"${inst.quote}"`)}`);
|
|
364
|
+
});
|
|
365
|
+
if (concept.relationships.length > 0) {
|
|
366
|
+
console.log('\n' + colors.ui.header(`Relationships (${concept.relationships.length})`));
|
|
367
|
+
console.log((0, colors_1.separator)(80, 'ā'));
|
|
368
|
+
concept.relationships.forEach(rel => {
|
|
369
|
+
const relColor = (0, colors_1.getRelationshipColor)(rel.rel_type);
|
|
370
|
+
const confidence = rel.confidence ? ` ${colors.status.dim(`[${(rel.confidence * 100).toFixed(0)}%]`)}` : '';
|
|
371
|
+
console.log(` ${colors.path.arrow('ā')} ${relColor(rel.rel_type)} ${colors.path.arrow('ā')} ${colors.concept.label(rel.to_label)} ${colors.concept.id(`(${rel.to_id})`)}${confidence}`);
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
console.log('\n' + colors.status.warning('ā No outgoing relationships'));
|
|
376
|
+
}
|
|
377
|
+
console.log();
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
console.error(colors.status.error('ā Failed to get concept details'));
|
|
381
|
+
console.error(colors.status.error(error.response?.data?.detail || error.message));
|
|
382
|
+
process.exit(1);
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
const relatedCommand = (0, help_formatter_1.setCommandHelp)(new commander_1.Command('related'), 'Find related concepts by graph traversal', 'Find concepts related through graph traversal (breadth-first search) - groups results by distance')
|
|
386
|
+
.showHelpAfterError()
|
|
387
|
+
.argument('<concept-id>', 'Starting concept ID for traversal')
|
|
388
|
+
.option('-d, --depth <number>', 'Maximum traversal depth in hops (1-2 fast, 3-4 moderate, 5 slow)', '2')
|
|
389
|
+
.option('-t, --types <types...>', 'Filter by relationship types (IMPLIES, ENABLES, SUPPORTS, etc. - see kg vocab list)')
|
|
390
|
+
.option('--include-epistemic <statuses...>', 'Only include relationships with these epistemic statuses (ADR-065): AFFIRMATIVE, CONTESTED, CONTRADICTORY, HISTORICAL')
|
|
391
|
+
.option('--exclude-epistemic <statuses...>', 'Exclude relationships with these epistemic statuses (ADR-065)')
|
|
392
|
+
.option('--json', 'Output raw JSON instead of formatted text for scripting')
|
|
393
|
+
.action(async (conceptId, options) => {
|
|
394
|
+
try {
|
|
395
|
+
const client = (0, client_1.createClientFromEnv)();
|
|
396
|
+
const result = await client.findRelatedConcepts({
|
|
397
|
+
concept_id: conceptId,
|
|
398
|
+
max_depth: parseInt(options.depth),
|
|
399
|
+
relationship_types: options.types,
|
|
400
|
+
// ADR-065: Epistemic status filtering
|
|
401
|
+
include_epistemic_status: options.includeEpistemic,
|
|
402
|
+
exclude_epistemic_status: options.excludeEpistemic
|
|
403
|
+
});
|
|
404
|
+
// JSON output mode
|
|
405
|
+
if (options.json) {
|
|
406
|
+
console.log(JSON.stringify(result, null, 2));
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
console.log('\n' + (0, colors_1.separator)());
|
|
410
|
+
console.log(colors.ui.title(`š Related Concepts from: ${conceptId}`));
|
|
411
|
+
console.log(`${colors.ui.key('Max depth:')} ${colors.path.distance(String(result.max_depth))}`);
|
|
412
|
+
console.log((0, colors_1.separator)());
|
|
413
|
+
console.log(colors.status.success(`\nā Found ${result.count} related concepts:\n`));
|
|
414
|
+
let currentDistance = -1;
|
|
415
|
+
result.results.forEach(concept => {
|
|
416
|
+
if (concept.distance !== currentDistance) {
|
|
417
|
+
currentDistance = concept.distance;
|
|
418
|
+
console.log('\n' + colors.path.distance(`Distance ${currentDistance}:`));
|
|
419
|
+
}
|
|
420
|
+
console.log(` ${colors.ui.bullet('ā')} ${colors.concept.label(concept.label)} ${colors.concept.id(`(${concept.concept_id})`)}`);
|
|
421
|
+
// Color-code the path by relationship types
|
|
422
|
+
const coloredPath = concept.path_types.map(type => (0, colors_1.getRelationshipColor)(type)(type)).join(colors.path.arrow(' ā '));
|
|
423
|
+
console.log(` ${colors.ui.key('Path:')} ${coloredPath}`);
|
|
424
|
+
});
|
|
425
|
+
console.log();
|
|
426
|
+
}
|
|
427
|
+
catch (error) {
|
|
428
|
+
console.error(colors.status.error('ā Failed to find related concepts'));
|
|
429
|
+
console.error(colors.status.error(error.response?.data?.detail || error.message));
|
|
430
|
+
process.exit(1);
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
const connectCommand = (0, help_formatter_1.setCommandHelp)(new commander_1.Command('connect'), 'Find paths between two concepts', 'Find shortest path between two concepts using IDs or semantic phrase matching')
|
|
434
|
+
.showHelpAfterError()
|
|
435
|
+
.argument('<from>', 'Starting concept (exact ID or descriptive phrase - e.g., "licensing issues" not "licensing")')
|
|
436
|
+
.argument('<to>', 'Target concept (exact ID or descriptive phrase - use 2-3 word phrases for best results)')
|
|
437
|
+
.option('--max-hops <number>', 'Maximum path length', '5')
|
|
438
|
+
.option('--min-similarity <number>', 'Semantic similarity threshold for phrase matching (default 50% - lower for broader matches)', '0.5')
|
|
439
|
+
.option('--no-evidence', 'Hide evidence quotes (shown by default)')
|
|
440
|
+
.option('--no-images', 'Hide inline image display (shown by default if chafa installed)')
|
|
441
|
+
.option('--no-grounding', 'Disable grounding strength calculation (faster)')
|
|
442
|
+
.option('--download <directory>', 'Download images to specified directory instead of displaying inline')
|
|
443
|
+
.option('--json', 'Output raw JSON instead of formatted text')
|
|
444
|
+
.option('--include-epistemic <statuses...>', 'Only include relationships with these epistemic statuses (ADR-065): AFFIRMATIVE, CONTESTED, CONTRADICTORY, HISTORICAL')
|
|
445
|
+
.option('--exclude-epistemic <statuses...>', 'Exclude relationships with these epistemic statuses (ADR-065)')
|
|
446
|
+
.addHelpText('after', `
|
|
447
|
+
Examples:
|
|
448
|
+
$ kg search connect concept-id-123 concept-id-456
|
|
449
|
+
$ kg search connect "licensing issues" "AGE benefits"
|
|
450
|
+
$ kg search connect "Apache AGE" "graph database" --min-similarity 0.3
|
|
451
|
+
$ kg search connect "my concept" "another concept" --show-evidence
|
|
452
|
+
$ kg search connect "concept-a" "concept-b" --include-epistemic AFFIRMATIVE
|
|
453
|
+
$ kg search connect "concept-a" "concept-b" --exclude-epistemic HISTORICAL INSUFFICIENT_DATA
|
|
454
|
+
|
|
455
|
+
Notes:
|
|
456
|
+
- Generic single words ("features", "issues") may not match well
|
|
457
|
+
- Use specific 2-3 word phrases for better semantic matching
|
|
458
|
+
- Lower --min-similarity (e.g., 0.3) to find weaker concept matches
|
|
459
|
+
- Error messages suggest threshold adjustments when near-misses exist
|
|
460
|
+
- Use --include-epistemic to filter by relationship confidence level (ADR-065)
|
|
461
|
+
`)
|
|
462
|
+
.action(async (from, to, options) => {
|
|
463
|
+
try {
|
|
464
|
+
const client = (0, client_1.createClientFromEnv)();
|
|
465
|
+
const config = (0, config_1.getConfig)();
|
|
466
|
+
// Use config defaults, allow CLI flags to override
|
|
467
|
+
const includeEvidence = options.evidence !== undefined ? options.evidence : config.getSearchShowEvidence();
|
|
468
|
+
const shouldShowImages = options.images !== undefined ? options.images : config.getSearchShowImages();
|
|
469
|
+
const includeGrounding = options.grounding !== false; // Default: true
|
|
470
|
+
// Auto-detect if using concept IDs (contain hyphens/underscores) or natural language
|
|
471
|
+
const isFromId = from.includes('-') || from.includes('_');
|
|
472
|
+
const isToId = to.includes('-') || to.includes('_');
|
|
473
|
+
let result;
|
|
474
|
+
let fromLabel = from;
|
|
475
|
+
let toLabel = to;
|
|
476
|
+
if (isFromId && isToId) {
|
|
477
|
+
// Both are concept IDs - use ID-based search
|
|
478
|
+
result = await client.findConnection({
|
|
479
|
+
from_id: from,
|
|
480
|
+
to_id: to,
|
|
481
|
+
max_hops: parseInt(options.maxHops),
|
|
482
|
+
include_evidence: includeEvidence,
|
|
483
|
+
include_grounding: includeGrounding,
|
|
484
|
+
// ADR-065: Epistemic status filtering
|
|
485
|
+
include_epistemic_status: options.includeEpistemic,
|
|
486
|
+
exclude_epistemic_status: options.excludeEpistemic
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
// At least one is a natural language query - use search-based
|
|
491
|
+
result = await client.findConnectionBySearch({
|
|
492
|
+
from_query: from,
|
|
493
|
+
to_query: to,
|
|
494
|
+
max_hops: parseInt(options.maxHops),
|
|
495
|
+
threshold: parseFloat(options.minSimilarity),
|
|
496
|
+
include_evidence: includeEvidence,
|
|
497
|
+
include_grounding: includeGrounding,
|
|
498
|
+
// ADR-065: Epistemic status filtering
|
|
499
|
+
include_epistemic_status: options.includeEpistemic,
|
|
500
|
+
exclude_epistemic_status: options.excludeEpistemic
|
|
501
|
+
});
|
|
502
|
+
// Update labels with matched concepts
|
|
503
|
+
if (result.from_concept) {
|
|
504
|
+
fromLabel = `${result.from_concept.label} (matched: "${from}")`;
|
|
505
|
+
}
|
|
506
|
+
if (result.to_concept) {
|
|
507
|
+
toLabel = `${result.to_concept.label} (matched: "${to}")`;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
// JSON output mode
|
|
511
|
+
if (options.json) {
|
|
512
|
+
console.log(JSON.stringify(result, null, 2));
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
console.log('\n' + (0, colors_1.separator)());
|
|
516
|
+
console.log(colors.ui.title('š Finding Connection'));
|
|
517
|
+
console.log((0, colors_1.separator)());
|
|
518
|
+
console.log(` ${colors.ui.key('From:')} ${colors.concept.label(fromLabel)}`);
|
|
519
|
+
if ('from_similarity' in result && result.from_similarity) {
|
|
520
|
+
console.log(` ${colors.ui.key('Match:')} ${(0, colors_1.coloredPercentage)(result.from_similarity)}`);
|
|
521
|
+
}
|
|
522
|
+
console.log(` ${colors.ui.key('To:')} ${colors.concept.label(toLabel)}`);
|
|
523
|
+
if ('to_similarity' in result && result.to_similarity) {
|
|
524
|
+
console.log(` ${colors.ui.key('Match:')} ${(0, colors_1.coloredPercentage)(result.to_similarity)}`);
|
|
525
|
+
}
|
|
526
|
+
console.log(` ${colors.ui.key('Max hops:')} ${colors.path.hop(String(result.max_hops))}\n`);
|
|
527
|
+
if (result.count === 0) {
|
|
528
|
+
console.log(colors.status.warning(`ā No connection found within ${result.max_hops} hops`));
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
console.log(colors.status.success(`ā Found ${result.count} path(s):\n`));
|
|
532
|
+
for (const [i, path] of result.paths.entries()) {
|
|
533
|
+
console.log(colors.path.distance(`Path ${i + 1}`) + colors.status.dim(` (${path.hops} hops):`));
|
|
534
|
+
for (const [j, node] of path.nodes.entries()) {
|
|
535
|
+
console.log(` ${colors.path.node(node.label)} ${colors.concept.id(`(${node.id})`)}`);
|
|
536
|
+
if (node.description) {
|
|
537
|
+
console.log(` ${colors.status.dim(node.description)}`);
|
|
538
|
+
}
|
|
539
|
+
// Display grounding with confidence-awareness (ADR-044 + grounding Ć confidence model)
|
|
540
|
+
if (includeGrounding && (node.grounding_strength !== undefined || node.grounding_display)) {
|
|
541
|
+
console.log(` ${colors.ui.key('Grounding:')} ${formatGroundingWithConfidence(node.grounding_strength, node.grounding_display, node.confidence_level, node.confidence_score)}`);
|
|
542
|
+
}
|
|
543
|
+
// Display sample evidence if requested
|
|
544
|
+
if (includeEvidence && node.sample_evidence && node.sample_evidence.length > 0) {
|
|
545
|
+
console.log(` ${colors.ui.key('Evidence:')}`);
|
|
546
|
+
for (const [idx, inst] of node.sample_evidence.entries()) {
|
|
547
|
+
const truncatedQuote = inst.quote.length > 80
|
|
548
|
+
? inst.quote.substring(0, 80) + '...'
|
|
549
|
+
: inst.quote;
|
|
550
|
+
console.log(` ${colors.ui.bullet(`${idx + 1}.`)} ${colors.evidence.document(inst.document)} ${colors.evidence.paragraph(`(para ${inst.paragraph})`)}`);
|
|
551
|
+
console.log(` ${colors.evidence.quote(`"${truncatedQuote}"`)}`);
|
|
552
|
+
// ADR-057: Handle images if available
|
|
553
|
+
if (inst.has_image && inst.source_id) {
|
|
554
|
+
const downloadDir = options.download;
|
|
555
|
+
if (downloadDir) {
|
|
556
|
+
// Download mode
|
|
557
|
+
try {
|
|
558
|
+
console.log(colors.status.dim(` š„ Downloading image from ${inst.source_id}...`));
|
|
559
|
+
const imageBuffer = await client.getSourceImage(inst.source_id);
|
|
560
|
+
const extension = (0, terminal_images_1.detectImageFormat)(imageBuffer);
|
|
561
|
+
const filename = `${inst.source_id}${extension}`;
|
|
562
|
+
const outputPath = nodePath.join(downloadDir, filename);
|
|
563
|
+
if ((0, terminal_images_1.saveImageToFile)(imageBuffer, outputPath)) {
|
|
564
|
+
console.log(colors.status.success(` ā Saved to ${outputPath}`));
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
catch (error) {
|
|
568
|
+
console.log(colors.status.error(` ā Failed to download image: ${error.message}`));
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
else if (shouldShowImages && config.isChafaEnabled()) {
|
|
572
|
+
// Display mode
|
|
573
|
+
if ((0, terminal_images_1.isChafaAvailable)()) {
|
|
574
|
+
try {
|
|
575
|
+
console.log(colors.status.dim(` š¼ļø Displaying image from ${inst.source_id}...`));
|
|
576
|
+
const imageBuffer = await client.getSourceImage(inst.source_id);
|
|
577
|
+
const extension = (0, terminal_images_1.detectImageFormat)(imageBuffer);
|
|
578
|
+
await (0, terminal_images_1.displayImageBufferWithChafa)(imageBuffer, extension, {
|
|
579
|
+
width: config.getChafaWidth(),
|
|
580
|
+
scale: config.getChafaScale(),
|
|
581
|
+
align: config.getChafaAlign(),
|
|
582
|
+
colors: config.getChafaColors()
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
catch (error) {
|
|
586
|
+
console.log(colors.status.error(` ā Failed to display image: ${error.message}`));
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
console.log(colors.status.warning(` š¼ļø Image available (source: ${inst.source_id})`));
|
|
591
|
+
(0, terminal_images_1.printChafaInstallInstructions)();
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
// Just indicate image is available
|
|
596
|
+
console.log(colors.status.dim(` š¼ļø Image available (use --show-images to display or --download <dir> to save)`));
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
if (j < path.relationships.length) {
|
|
602
|
+
const relType = path.relationships[j];
|
|
603
|
+
const relColor = (0, colors_1.getRelationshipColor)(relType);
|
|
604
|
+
console.log(` ${colors.path.arrow('ā')} ${relColor(relType)}`);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
console.log();
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
console.log((0, colors_1.separator)());
|
|
611
|
+
}
|
|
612
|
+
catch (error) {
|
|
613
|
+
console.error(colors.status.error('ā Failed to find connection'));
|
|
614
|
+
console.error(colors.status.error(error.response?.data?.detail || error.message));
|
|
615
|
+
process.exit(1);
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
const sourcesCommand = (0, help_formatter_1.setCommandHelp)(new commander_1.Command('sources'), 'Search source text by semantic similarity', 'Search source documents directly using embeddings - returns matched text with related concepts (ADR-068)')
|
|
619
|
+
.showHelpAfterError()
|
|
620
|
+
.argument('<query>', 'Search query text (searches source embeddings, not concept embeddings)')
|
|
621
|
+
.option('-l, --limit <number>', 'Maximum number of sources to return', '10')
|
|
622
|
+
.option('--min-similarity <number>', 'Minimum similarity score (0.0-1.0, default 0.7)', '0.7')
|
|
623
|
+
.option('-o, --ontology <name>', 'Filter by ontology/document name')
|
|
624
|
+
.option('--no-concepts', 'Hide concepts extracted from matched sources (shown by default)')
|
|
625
|
+
.option('--no-full-text', 'Hide full source text (shown by default)')
|
|
626
|
+
.option('--json', 'Output raw JSON instead of formatted text for scripting')
|
|
627
|
+
.action(async (query, options) => {
|
|
628
|
+
try {
|
|
629
|
+
const client = (0, client_1.createClientFromEnv)();
|
|
630
|
+
const includeConcepts = options.concepts !== false; // Default: true
|
|
631
|
+
const includeFullText = options.fullText !== false; // Default: true
|
|
632
|
+
const result = await client.searchSources({
|
|
633
|
+
query,
|
|
634
|
+
limit: parseInt(options.limit),
|
|
635
|
+
min_similarity: parseFloat(options.minSimilarity),
|
|
636
|
+
ontology: options.ontology,
|
|
637
|
+
include_concepts: includeConcepts,
|
|
638
|
+
include_full_text: includeFullText
|
|
639
|
+
});
|
|
640
|
+
// JSON output mode
|
|
641
|
+
if (options.json) {
|
|
642
|
+
console.log(JSON.stringify(result, null, 2));
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
console.log('\n' + (0, colors_1.separator)());
|
|
646
|
+
console.log(colors.ui.title(`š Source Search: ${query}`));
|
|
647
|
+
console.log((0, colors_1.separator)());
|
|
648
|
+
console.log(colors.status.success(`\nā Found ${result.count} source(s):\n`));
|
|
649
|
+
for (const [i, source] of result.results.entries()) {
|
|
650
|
+
console.log(colors.ui.bullet('ā') + ' ' + colors.concept.label(`${i + 1}. ${source.document} (para ${source.paragraph})`));
|
|
651
|
+
console.log(` ${colors.ui.key('Source ID:')} ${colors.concept.id(source.source_id)}`);
|
|
652
|
+
console.log(` ${colors.ui.key('Similarity:')} ${(0, colors_1.coloredPercentage)(source.similarity)}`);
|
|
653
|
+
if (source.is_stale) {
|
|
654
|
+
console.log(` ${colors.status.warning('ā Stale embedding (source text changed)')}`);
|
|
655
|
+
}
|
|
656
|
+
// Display matched chunk
|
|
657
|
+
console.log(` ${colors.ui.key('Matched chunk:')} ${colors.evidence.paragraph(`[${source.matched_chunk.start_offset}:${source.matched_chunk.end_offset}]`)}`);
|
|
658
|
+
const truncatedChunk = source.matched_chunk.chunk_text.length > 150
|
|
659
|
+
? source.matched_chunk.chunk_text.substring(0, 150) + '...'
|
|
660
|
+
: source.matched_chunk.chunk_text;
|
|
661
|
+
console.log(` ${colors.evidence.quote(`"${truncatedChunk}"`)}`);
|
|
662
|
+
// Display full text if requested
|
|
663
|
+
if (includeFullText && source.full_text) {
|
|
664
|
+
console.log(` ${colors.ui.key('Full text:')}`);
|
|
665
|
+
const truncatedText = source.full_text.length > 200
|
|
666
|
+
? source.full_text.substring(0, 200) + '...'
|
|
667
|
+
: source.full_text;
|
|
668
|
+
console.log(` ${colors.status.dim(truncatedText)}`);
|
|
669
|
+
}
|
|
670
|
+
// Display concepts extracted from this source
|
|
671
|
+
if (includeConcepts && source.concepts && source.concepts.length > 0) {
|
|
672
|
+
console.log(` ${colors.ui.key('Concepts:')} ${colors.status.dim(`(${source.concepts.length} extracted)`)}`);
|
|
673
|
+
for (const concept of source.concepts.slice(0, 5)) { // Show max 5 concepts
|
|
674
|
+
console.log(` ${colors.ui.bullet('ā')} ${colors.concept.label(concept.label)} ${colors.concept.id(`(${concept.concept_id})`)}`);
|
|
675
|
+
if (concept.description) {
|
|
676
|
+
console.log(` ${colors.status.dim(concept.description)}`);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
if (source.concepts.length > 5) {
|
|
680
|
+
console.log(` ${colors.status.dim(`... and ${source.concepts.length - 5} more`)}`);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
console.log();
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
catch (error) {
|
|
687
|
+
console.error(colors.status.error('\nā Source search failed'));
|
|
688
|
+
if (error.response) {
|
|
689
|
+
// API returned error response
|
|
690
|
+
const status = error.response.status;
|
|
691
|
+
const detail = error.response.data?.detail || 'Unknown error';
|
|
692
|
+
console.error(colors.status.warning(`\nAPI Error (${status}): ${detail}`));
|
|
693
|
+
if (status === 500 && detail.includes('embedding')) {
|
|
694
|
+
console.error(colors.status.dim('\nš” Suggestion: Check embedding provider configuration:'));
|
|
695
|
+
console.error(colors.status.dim(' kg admin embedding list'));
|
|
696
|
+
}
|
|
697
|
+
else if (status === 404) {
|
|
698
|
+
console.error(colors.status.dim('\nš” Suggestion: Verify API endpoint exists (may need to update CLI)'));
|
|
699
|
+
}
|
|
700
|
+
else if (status === 401 || status === 403) {
|
|
701
|
+
console.error(colors.status.dim('\nš” Suggestion: Check authentication:'));
|
|
702
|
+
console.error(colors.status.dim(' kg login'));
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
else if (error.request) {
|
|
706
|
+
// No response received
|
|
707
|
+
console.error(colors.status.warning('\nNo response from API server'));
|
|
708
|
+
console.error(colors.status.dim('\nš” Suggestion: Check API is running:'));
|
|
709
|
+
console.error(colors.status.dim(' kg health'));
|
|
710
|
+
}
|
|
711
|
+
else {
|
|
712
|
+
// Request setup error
|
|
713
|
+
console.error(colors.status.warning(`\n${error.message}`));
|
|
714
|
+
}
|
|
715
|
+
process.exit(1);
|
|
716
|
+
}
|
|
717
|
+
});
|
|
718
|
+
// Configure colored help for all search subcommands
|
|
719
|
+
[queryCommand, showCommand, relatedCommand, connectCommand, sourcesCommand].forEach(help_formatter_1.configureColoredHelp);
|
|
720
|
+
exports.searchCommand = (0, help_formatter_1.setCommandHelp)(new commander_1.Command('search'), 'Search and explore the knowledge graph', 'Search and explore the knowledge graph using vector similarity, graph traversal, and path finding')
|
|
721
|
+
.showHelpAfterError('(add --help for additional information)')
|
|
722
|
+
.showSuggestionAfterError()
|
|
723
|
+
// Allow direct search: kg search <term> (shortcut for kg search query <term>)
|
|
724
|
+
.argument('[query]', 'Search query (shortcut for: kg search query <term>)')
|
|
725
|
+
.option('-l, --limit <number>', 'Maximum number of results to return', '10')
|
|
726
|
+
.option('--min-similarity <number>', 'Minimum similarity score (0.0-1.0)', '0.7')
|
|
727
|
+
.option('--json', 'Output raw JSON instead of formatted text')
|
|
728
|
+
.option('--save-artifact', 'Save result as persistent artifact (ADR-083)')
|
|
729
|
+
.action(async (query, options, command) => {
|
|
730
|
+
// If no query provided and no subcommand matched, show help
|
|
731
|
+
if (!query) {
|
|
732
|
+
command.help();
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
// Check if query matches a subcommand name - if so, Commander already handled it
|
|
736
|
+
const subcommandNames = ['query', 'details', 'related', 'connect', 'sources'];
|
|
737
|
+
if (subcommandNames.includes(query)) {
|
|
738
|
+
// This shouldn't happen as Commander routes subcommands, but safety check
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
// Delegate to query action for direct search shortcut
|
|
742
|
+
try {
|
|
743
|
+
const client = (0, client_1.createClientFromEnv)();
|
|
744
|
+
const config = (0, config_1.getConfig)();
|
|
745
|
+
const result = await client.searchConcepts({
|
|
746
|
+
query,
|
|
747
|
+
limit: parseInt(options.limit),
|
|
748
|
+
min_similarity: parseFloat(options.minSimilarity),
|
|
749
|
+
include_evidence: config.getSearchShowEvidence(),
|
|
750
|
+
include_grounding: true,
|
|
751
|
+
include_diversity: true,
|
|
752
|
+
diversity_max_hops: 2
|
|
753
|
+
});
|
|
754
|
+
// JSON output mode
|
|
755
|
+
if (options.json) {
|
|
756
|
+
console.log(JSON.stringify(result, null, 2));
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
console.log('\n' + (0, colors_1.separator)());
|
|
760
|
+
console.log(colors.ui.title(`š Searching for: ${query}`));
|
|
761
|
+
console.log((0, colors_1.separator)());
|
|
762
|
+
console.log(colors.status.success(`\nā Found ${result.count} concepts:\n`));
|
|
763
|
+
for (const [i, concept] of result.results.entries()) {
|
|
764
|
+
console.log(colors.ui.bullet('ā') + ' ' + colors.concept.label(`${i + 1}. ${concept.label}`));
|
|
765
|
+
if (concept.description) {
|
|
766
|
+
console.log(` ${colors.status.dim(concept.description)}`);
|
|
767
|
+
}
|
|
768
|
+
console.log(` ${colors.ui.key('ID:')} ${colors.concept.id(concept.concept_id)}`);
|
|
769
|
+
console.log(` ${colors.ui.key('Similarity:')} ${(0, colors_1.coloredPercentage)(concept.score)}`);
|
|
770
|
+
console.log(` ${colors.ui.key('Documents:')} ${colors.evidence.document(concept.documents.join(', '))}`);
|
|
771
|
+
console.log(` ${colors.ui.key('Evidence:')} ${colors.evidence.count(String(concept.evidence_count))} instances`);
|
|
772
|
+
// Display grounding with confidence-awareness
|
|
773
|
+
if (concept.grounding_strength !== undefined || concept.grounding_display) {
|
|
774
|
+
console.log(` ${colors.ui.key('Grounding:')} ${formatGroundingWithConfidence(concept.grounding_strength, concept.grounding_display, concept.confidence_level, concept.confidence_score)}`);
|
|
775
|
+
}
|
|
776
|
+
// Display diversity if available
|
|
777
|
+
if (concept.diversity_score !== undefined && concept.diversity_score !== null && concept.diversity_related_count !== undefined) {
|
|
778
|
+
console.log(` ${colors.ui.key('Diversity:')} ${formatDiversity(concept.diversity_score, concept.diversity_related_count)}`);
|
|
779
|
+
}
|
|
780
|
+
// Display authenticated diversity if available
|
|
781
|
+
if (concept.authenticated_diversity !== undefined && concept.authenticated_diversity !== null) {
|
|
782
|
+
console.log(` ${colors.ui.key('Authenticated:')} ${formatAuthenticatedDiversity(concept.authenticated_diversity)}`);
|
|
783
|
+
}
|
|
784
|
+
console.log();
|
|
785
|
+
}
|
|
786
|
+
// Show hint if additional results available below threshold
|
|
787
|
+
if (result.below_threshold_count && result.below_threshold_count > 0 && result.suggested_threshold) {
|
|
788
|
+
const thresholdPercent = (result.suggested_threshold * 100).toFixed(0);
|
|
789
|
+
console.log(colors.status.warning(`š” ${result.below_threshold_count} additional concept${result.below_threshold_count > 1 ? 's' : ''} available at ${thresholdPercent}% threshold`));
|
|
790
|
+
console.log(colors.status.dim(` Try: kg search "${query}" --min-similarity ${result.suggested_threshold}\n`));
|
|
791
|
+
}
|
|
792
|
+
// ADR-083: Save result as artifact if requested
|
|
793
|
+
if (options.saveArtifact && result.count > 0) {
|
|
794
|
+
try {
|
|
795
|
+
const artifactResult = await client.createArtifact({
|
|
796
|
+
artifact_type: 'search_result',
|
|
797
|
+
representation: 'cli',
|
|
798
|
+
name: `Search: "${query}" (${result.count} results)`,
|
|
799
|
+
parameters: {
|
|
800
|
+
query,
|
|
801
|
+
limit: parseInt(options.limit),
|
|
802
|
+
min_similarity: parseFloat(options.minSimilarity),
|
|
803
|
+
include_evidence: config.getSearchShowEvidence(),
|
|
804
|
+
include_grounding: true,
|
|
805
|
+
include_diversity: true,
|
|
806
|
+
diversity_max_hops: 2
|
|
807
|
+
},
|
|
808
|
+
payload: result
|
|
809
|
+
});
|
|
810
|
+
console.log(colors.status.success(`ā Artifact saved: ${artifactResult.id}`));
|
|
811
|
+
console.log(colors.status.dim(` View: kg artifact show ${artifactResult.id}`));
|
|
812
|
+
}
|
|
813
|
+
catch (artifactError) {
|
|
814
|
+
console.error(colors.status.error(`ā Failed to save artifact: ${artifactError.message}`));
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
catch (error) {
|
|
819
|
+
console.error(colors.status.error('ā Search failed'));
|
|
820
|
+
console.error(colors.status.error(error.response?.data?.detail || error.message));
|
|
821
|
+
process.exit(1);
|
|
822
|
+
}
|
|
823
|
+
})
|
|
824
|
+
.addCommand(queryCommand)
|
|
825
|
+
.addCommand(showCommand)
|
|
826
|
+
.addCommand(relatedCommand)
|
|
827
|
+
.addCommand(connectCommand)
|
|
828
|
+
.addCommand(sourcesCommand);
|
|
829
|
+
//# sourceMappingURL=search.js.map
|