sneakoscope 4.2.1 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -6
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/bin/sks.js +1 -1
- package/dist/cli/command-registry.js +2 -1
- package/dist/cli/ultra-search-command.js +163 -0
- package/dist/cli/xai-command.js +28 -168
- package/dist/core/agents/agent-codex-cockpit.js +3 -3
- package/dist/core/agents/agent-wrongness.js +1 -1
- package/dist/core/fsx.js +1 -1
- package/dist/core/release-parallel-full-coverage.js +1 -1
- package/dist/core/routes.js +3 -2
- package/dist/core/source-intelligence/source-intelligence-policy.js +45 -26
- package/dist/core/source-intelligence/source-intelligence-proof.js +10 -16
- package/dist/core/source-intelligence/source-intelligence-runner.js +56 -42
- package/dist/core/trust-kernel/trust-report.js +3 -5
- package/dist/core/ultra-search/index.js +3 -0
- package/dist/core/ultra-search/runtime.js +502 -0
- package/dist/core/ultra-search/types.js +3 -0
- package/dist/core/version.js +1 -1
- package/dist/scripts/agent-visual-consistency-check.js +1 -1
- package/dist/scripts/release-metadata-1-19-check.js +2 -2
- package/dist/scripts/release-parallel-check.js +2 -2
- package/dist/scripts/release-parallel-full-coverage-check.js +1 -1
- package/dist/scripts/release-readiness-report.js +6 -6
- package/dist/scripts/sks-1-18-gate-lib.js +2 -2
- package/dist/scripts/source-intelligence-all-modes-check.js +9 -19
- package/dist/scripts/source-intelligence-policy-check.js +6 -6
- package/dist/scripts/ultra-search-provider-interface-check.js +27 -0
- package/package.json +2 -2
- package/dist/core/mcp/xai-mcp-detector.js +0 -157
- package/dist/core/mcp/xai-search-adapter.js +0 -100
- package/dist/scripts/xai-mcp-capability-check.js +0 -14
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
import { assertFiles, assertGate, emitGate, importDist, SOURCE_INTELLIGENCE_FILES } from './sks-1-18-gate-lib.js';
|
|
4
4
|
assertFiles(SOURCE_INTELLIGENCE_FILES);
|
|
5
5
|
const mod = await importDist('core/source-intelligence/source-intelligence-policy.js');
|
|
6
|
-
const base = mod.buildSourceIntelligencePolicy({ context7Available: true, codexWebCapability: { available: true, status: 'available', reason: 'fixture' }
|
|
7
|
-
const
|
|
8
|
-
const blocked = mod.buildSourceIntelligencePolicy({ context7Available: false });
|
|
9
|
-
assertGate(base.mode === '
|
|
10
|
-
assertGate(
|
|
6
|
+
const base = mod.buildSourceIntelligencePolicy({ query: 'current release notes', context7Available: true, codexWebCapability: { available: true, status: 'available', reason: 'fixture' } });
|
|
7
|
+
const xSearch = mod.buildSourceIntelligencePolicy({ query: 'site:x.com product launch', context7Available: true, codexWebCapability: { available: true, status: 'available', reason: 'fixture' }, xaiDetection: { configured: true, search_capable: true } });
|
|
8
|
+
const blocked = mod.buildSourceIntelligencePolicy({ query: 'npm package docs', context7Available: false });
|
|
9
|
+
assertGate(base.mode === 'ultra_balanced', 'default mode must be ultra_balanced', base);
|
|
10
|
+
assertGate(xSearch.mode === 'x_search' && xSearch.selected_providers.includes('x_public') && !Object.hasOwn(xSearch, ['xai', 'mcp'].join('_')), 'X-search mode must be provider-independent and ignore xAI detection', xSearch);
|
|
11
11
|
assertGate(blocked.mode === 'blocked' && blocked.blockers.includes('docs_context_missing'), 'Context7 missing must block docs context');
|
|
12
|
-
emitGate('source-intelligence:policy', { modes: [base.mode,
|
|
12
|
+
emitGate('source-intelligence:policy', { modes: [base.mode, xSearch.mode, blocked.mode] });
|
|
13
13
|
//# sourceMappingURL=source-intelligence-policy-check.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { assertGate, emitGate, importDist } from './sks-1-18-gate-lib.js';
|
|
7
|
+
const mod = await importDist('core/ultra-search/index.js');
|
|
8
|
+
const missionDir = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-ultra-search-'));
|
|
9
|
+
const result = await mod.runUltraSearch({
|
|
10
|
+
missionDir,
|
|
11
|
+
query: 'npm package docs',
|
|
12
|
+
mode: 'balanced',
|
|
13
|
+
context7: async () => [{ title: 'npm docs', url: 'https://docs.npmjs.com', snippet: 'official docs' }],
|
|
14
|
+
codexWebSearch: async () => [{ title: 'npm registry', url: 'https://www.npmjs.com/package/npm', snippet: 'registry' }],
|
|
15
|
+
env: { SKS_CODEX_WEB_SEARCH_AVAILABLE: '1' }
|
|
16
|
+
});
|
|
17
|
+
assertGate(result.proof.provider_independent === true, 'UltraSearch proof must be provider-independent', result.proof);
|
|
18
|
+
assertGate(result.proof.xai_runtime_dependency === false, 'UltraSearch must not require xAI runtime', result.proof);
|
|
19
|
+
assertGate(result.sources.some((source) => source.acquisition_verdict === 'verified_content'), 'UltraSearch must normalize verified source evidence', result.sources);
|
|
20
|
+
assertGate(result.convergence.schema === 'sks.ultra-search-convergence.v1', 'UltraSearch convergence artifact must be typed', result.convergence);
|
|
21
|
+
emitGate('ultra-search:provider-interface', {
|
|
22
|
+
mode: result.mode,
|
|
23
|
+
sources: result.sources.length,
|
|
24
|
+
verified: result.proof.verified_source_count,
|
|
25
|
+
xai_runtime_dependency: result.proof.xai_runtime_dependency
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=ultra-search-provider-interface-check.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sneakoscope",
|
|
3
3
|
"displayName": "ㅅㅋㅅ",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.4.0",
|
|
5
5
|
"description": "Sneakoscope Codex: fast proof-first Codex trust layer with image-based Voxel TriWiki.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
|
|
@@ -476,12 +476,12 @@
|
|
|
476
476
|
"qa:native-agent-backend": "node ./dist/scripts/agent-native-release-gate.js qa-native-agent-backend",
|
|
477
477
|
"agent:non-recursive-pipeline-report": "node ./dist/scripts/non-recursive-pipeline-check.js --json",
|
|
478
478
|
"agent:legacy-multiagent-removed": "node ./dist/scripts/legacy-multiagent-removal-check.js",
|
|
479
|
-
"xai-mcp:capability": "node ./dist/scripts/xai-mcp-capability-check.js",
|
|
480
479
|
"mcp:0.134-modernization": "node ./dist/scripts/mcp-0-134-modernization-check.js",
|
|
481
480
|
"mcp:readonly-concurrency": "node ./dist/scripts/mcp-readonly-concurrency-check.js",
|
|
482
481
|
"mcp:readonly-runtime-scheduler": "node ./dist/scripts/mcp-readonly-runtime-scheduler-check.js",
|
|
483
482
|
"codex:0.134-runner-truth": "node ./dist/scripts/codex-0-134-runner-truth-check.js",
|
|
484
483
|
"source-intelligence:policy": "node ./dist/scripts/source-intelligence-policy-check.js",
|
|
484
|
+
"ultra-search:provider-interface": "node ./dist/scripts/ultra-search-provider-interface-check.js",
|
|
485
485
|
"context7:evidence-dedupe": "node ./dist/scripts/context7-evidence-dedupe-check.js",
|
|
486
486
|
"source-intelligence:codex-history-search": "node ./dist/scripts/codex-history-search-check.js",
|
|
487
487
|
"source-intelligence:all-modes": "node ./dist/scripts/source-intelligence-all-modes-check.js",
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import os from 'node:os';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { exists, nowIso, readText } from '../fsx.js';
|
|
4
|
-
export const XAI_MCP_DETECTION_SCHEMA = 'sks.xai-mcp-detection.v1';
|
|
5
|
-
const XAI_SERVER_RE = /(?:^|[-_\s.])(xai|x-ai|x_ai|grok|x\.ai)(?:$|[-_\s.])/i;
|
|
6
|
-
const SEARCH_TOOL_RE = /(?:search|query|web|retrieve|retrieval|news|grok)/i;
|
|
7
|
-
export function isXaiServerName(name) {
|
|
8
|
-
return XAI_SERVER_RE.test(normalizeName(name));
|
|
9
|
-
}
|
|
10
|
-
export function isSearchToolName(name) {
|
|
11
|
-
return SEARCH_TOOL_RE.test(normalizeName(name));
|
|
12
|
-
}
|
|
13
|
-
export async function detectXaiMcp(opts = {}) {
|
|
14
|
-
const root = path.resolve(opts.root || process.cwd());
|
|
15
|
-
const home = opts.home || os.homedir();
|
|
16
|
-
const configPaths = [
|
|
17
|
-
{ path: path.join(home, '.codex', 'config.toml'), source: 'user' },
|
|
18
|
-
{ path: path.join(root, '.codex', 'config.toml'), source: 'project' },
|
|
19
|
-
{ path: path.join(root, '.codex', 'config.json'), source: 'project' }
|
|
20
|
-
];
|
|
21
|
-
const provided = opts.configSources || [];
|
|
22
|
-
const discovered = [...provided];
|
|
23
|
-
for (const entry of configPaths) {
|
|
24
|
-
if (provided.some((source) => path.resolve(source.path) === path.resolve(entry.path)))
|
|
25
|
-
continue;
|
|
26
|
-
if (await exists(entry.path)) {
|
|
27
|
-
discovered.push({ path: entry.path, source: entry.source, text: String(await readText(entry.path, '')) });
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return detectXaiMcpFromConfig(discovered, {
|
|
31
|
-
checked: configPaths.map((entry) => entry.path),
|
|
32
|
-
toolLists: opts.toolLists || {}
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
export function detectXaiMcpFromConfig(sources = [], opts = {}) {
|
|
36
|
-
try {
|
|
37
|
-
const servers = sources.flatMap((source) => detectServersInSource(source, opts.toolLists || {}));
|
|
38
|
-
const configured = servers.length > 0;
|
|
39
|
-
const searchCapable = servers.some((server) => server.search_capable);
|
|
40
|
-
const configuredButUnverified = configured && !searchCapable && servers.some((server) => server.configured_but_unverified);
|
|
41
|
-
const status = !configured
|
|
42
|
-
? 'missing'
|
|
43
|
-
: searchCapable
|
|
44
|
-
? 'search_capable'
|
|
45
|
-
: configuredButUnverified
|
|
46
|
-
? 'configured_but_unverified'
|
|
47
|
-
: 'configured_no_search';
|
|
48
|
-
return {
|
|
49
|
-
schema: XAI_MCP_DETECTION_SCHEMA,
|
|
50
|
-
generated_at: nowIso(),
|
|
51
|
-
ok: true,
|
|
52
|
-
status,
|
|
53
|
-
configured,
|
|
54
|
-
search_capable: searchCapable,
|
|
55
|
-
configured_but_unverified: configuredButUnverified,
|
|
56
|
-
servers,
|
|
57
|
-
config_paths_checked: [...new Set([...(opts.checked || []), ...sources.map((source) => source.path)])],
|
|
58
|
-
config_paths_found: sources.map((source) => source.path),
|
|
59
|
-
blockers: [],
|
|
60
|
-
warnings: configuredButUnverified ? ['xai_mcp_configured_but_tool_list_unverified'] : []
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
catch (err) {
|
|
64
|
-
return {
|
|
65
|
-
schema: XAI_MCP_DETECTION_SCHEMA,
|
|
66
|
-
generated_at: nowIso(),
|
|
67
|
-
ok: false,
|
|
68
|
-
status: 'error',
|
|
69
|
-
configured: false,
|
|
70
|
-
search_capable: false,
|
|
71
|
-
configured_but_unverified: false,
|
|
72
|
-
servers: [],
|
|
73
|
-
config_paths_checked: opts.checked || [],
|
|
74
|
-
config_paths_found: sources.map((source) => source.path),
|
|
75
|
-
blockers: [`xai_mcp_detection_error:${err instanceof Error ? err.message : String(err)}`],
|
|
76
|
-
warnings: []
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
function detectServersInSource(source, toolLists) {
|
|
81
|
-
const jsonServers = parseJsonServers(source);
|
|
82
|
-
const tomlServers = jsonServers.length ? [] : parseTomlServerNames(source.text);
|
|
83
|
-
const names = [...jsonServers, ...tomlServers].filter((server) => isXaiServerName(server.name));
|
|
84
|
-
return names.map((server) => {
|
|
85
|
-
const configuredTools = [...server.tools, ...(toolLists[server.name] || []), ...(toolLists[normalizeName(server.name)] || [])];
|
|
86
|
-
const uniqueTools = [...new Set(configuredTools.map(String).filter(Boolean))];
|
|
87
|
-
const searchCapable = uniqueTools.some(isSearchToolName);
|
|
88
|
-
return {
|
|
89
|
-
name: normalizeName(server.name),
|
|
90
|
-
source: `${source.source}:${source.path}`,
|
|
91
|
-
configured: true,
|
|
92
|
-
search_capable: searchCapable,
|
|
93
|
-
configured_but_unverified: !searchCapable && uniqueTools.length === 0,
|
|
94
|
-
tools: uniqueTools,
|
|
95
|
-
raw_name: server.name
|
|
96
|
-
};
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
function parseJsonServers(source) {
|
|
100
|
-
const text = source.text.trim();
|
|
101
|
-
if (!text.startsWith('{'))
|
|
102
|
-
return [];
|
|
103
|
-
try {
|
|
104
|
-
const parsed = JSON.parse(text);
|
|
105
|
-
const servers = parsed?.mcp_servers || parsed?.mcpServers || {};
|
|
106
|
-
return Object.entries(servers).map(([name, value]) => ({
|
|
107
|
-
name,
|
|
108
|
-
tools: extractToolNames(value)
|
|
109
|
-
}));
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
return [];
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
function parseTomlServerNames(text) {
|
|
116
|
-
const rows = [];
|
|
117
|
-
const tableRe = /^\s*\[(?:mcp_servers|mcpServers)\.([^\]]+)\]\s*$/gm;
|
|
118
|
-
let match;
|
|
119
|
-
while ((match = tableRe.exec(text)) !== null) {
|
|
120
|
-
const name = unquote(match[1] || '');
|
|
121
|
-
const bodyStart = match.index + match[0].length;
|
|
122
|
-
const nextTable = text.slice(bodyStart).search(/^\s*\[/m);
|
|
123
|
-
const body = nextTable >= 0 ? text.slice(bodyStart, bodyStart + nextTable) : text.slice(bodyStart);
|
|
124
|
-
rows.push({ name, tools: extractToolNamesFromText(body) });
|
|
125
|
-
}
|
|
126
|
-
return rows;
|
|
127
|
-
}
|
|
128
|
-
function extractToolNames(value) {
|
|
129
|
-
if (!value || typeof value !== 'object')
|
|
130
|
-
return [];
|
|
131
|
-
const possible = [
|
|
132
|
-
value.tools,
|
|
133
|
-
value.tool_names,
|
|
134
|
-
value.capabilities,
|
|
135
|
-
value.search_tools
|
|
136
|
-
];
|
|
137
|
-
return possible.flatMap((entry) => Array.isArray(entry) ? entry.map(String) : []);
|
|
138
|
-
}
|
|
139
|
-
function extractToolNamesFromText(text) {
|
|
140
|
-
const tools = [];
|
|
141
|
-
const arrayRe = /(?:tools|tool_names|capabilities|search_tools)\s*=\s*\[([^\]]*)\]/g;
|
|
142
|
-
let match;
|
|
143
|
-
while ((match = arrayRe.exec(text)) !== null) {
|
|
144
|
-
tools.push(...String(match[1] || '').split(',').map((part) => unquote(part.trim())).filter(Boolean));
|
|
145
|
-
}
|
|
146
|
-
const keyRe = /^\s*(search|query|web|retrieve|news|grok)\s*=/gmi;
|
|
147
|
-
while ((match = keyRe.exec(text)) !== null)
|
|
148
|
-
tools.push(match[1] || '');
|
|
149
|
-
return tools;
|
|
150
|
-
}
|
|
151
|
-
function normalizeName(name) {
|
|
152
|
-
return String(name || '').trim().replace(/^["']|["']$/g, '').toLowerCase();
|
|
153
|
-
}
|
|
154
|
-
function unquote(value) {
|
|
155
|
-
return String(value || '').trim().replace(/^["']|["']$/g, '');
|
|
156
|
-
}
|
|
157
|
-
//# sourceMappingURL=xai-mcp-detector.js.map
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { ensureDir, nowIso, sha256, writeJsonAtomic } from '../fsx.js';
|
|
3
|
-
export const XAI_SEARCH_EVIDENCE_SCHEMA = 'sks.xai-search-evidence.v1';
|
|
4
|
-
export async function runXaiSearch(query, opts = {}) {
|
|
5
|
-
const timeoutMs = opts.timeoutMs || 10_000;
|
|
6
|
-
if (opts.configured === false)
|
|
7
|
-
return blockedEvidence(query, timeoutMs, 'not_configured', ['xai_mcp_missing']);
|
|
8
|
-
if (!opts.search)
|
|
9
|
-
return blockedEvidence(query, timeoutMs, 'blocked', ['xai_search_adapter_missing']);
|
|
10
|
-
try {
|
|
11
|
-
const raw = await withTimeout(opts.search(query), timeoutMs);
|
|
12
|
-
const results = normalizeXaiSearchResults(raw);
|
|
13
|
-
let rawArtifact = null;
|
|
14
|
-
if (opts.artifactDir) {
|
|
15
|
-
await ensureDir(opts.artifactDir);
|
|
16
|
-
rawArtifact = path.join(opts.artifactDir, `xai-search-raw-${sha256(JSON.stringify({ query, raw })).slice(0, 12)}.json`);
|
|
17
|
-
await writeJsonAtomic(rawArtifact, { schema: 'sks.xai-search-raw-local-only.v1', generated_at: nowIso(), local_only: true, query, raw });
|
|
18
|
-
}
|
|
19
|
-
return {
|
|
20
|
-
schema: XAI_SEARCH_EVIDENCE_SCHEMA,
|
|
21
|
-
generated_at: nowIso(),
|
|
22
|
-
ok: true,
|
|
23
|
-
query,
|
|
24
|
-
status: 'completed',
|
|
25
|
-
timeout_ms: timeoutMs,
|
|
26
|
-
results: results.map((record) => ({ ...record, local_only_raw_artifact: rawArtifact })),
|
|
27
|
-
raw_response_artifact: rawArtifact,
|
|
28
|
-
redacted_summary: {
|
|
29
|
-
result_count: results.length,
|
|
30
|
-
urls: results.map((record) => record.url)
|
|
31
|
-
},
|
|
32
|
-
blockers: []
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
catch (err) {
|
|
36
|
-
const timeout = err instanceof Error && err.message === 'xai_search_timeout';
|
|
37
|
-
return blockedEvidence(query, timeoutMs, timeout ? 'timeout' : 'blocked', [
|
|
38
|
-
timeout ? 'xai_search_timeout' : `xai_search_failure:${err instanceof Error ? err.message : String(err)}`
|
|
39
|
-
]);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
export function normalizeXaiSearchResults(raw) {
|
|
43
|
-
const rows = Array.isArray(raw)
|
|
44
|
-
? raw
|
|
45
|
-
: Array.isArray(raw?.results)
|
|
46
|
-
? raw.results
|
|
47
|
-
: Array.isArray(raw?.data)
|
|
48
|
-
? raw.data
|
|
49
|
-
: [];
|
|
50
|
-
return rows.map((row, index) => ({
|
|
51
|
-
provider: 'xai',
|
|
52
|
-
id: String(row.id || row.url || row.link || `xai-${index + 1}`),
|
|
53
|
-
title: String(row.title || row.name || row.heading || `X AI result ${index + 1}`),
|
|
54
|
-
url: row.url || row.link || null,
|
|
55
|
-
snippet: String(row.snippet || row.summary || row.text || ''),
|
|
56
|
-
published_at: row.published_at || row.publishedAt || row.date || null,
|
|
57
|
-
local_only_raw_artifact: null
|
|
58
|
-
}));
|
|
59
|
-
}
|
|
60
|
-
export function redactXaiRawResponse(raw) {
|
|
61
|
-
const results = normalizeXaiSearchResults(raw);
|
|
62
|
-
return {
|
|
63
|
-
provider: 'xai',
|
|
64
|
-
result_count: results.length,
|
|
65
|
-
results: results.map((result) => ({
|
|
66
|
-
title: result.title,
|
|
67
|
-
url: result.url,
|
|
68
|
-
snippet: result.snippet.slice(0, 240),
|
|
69
|
-
published_at: result.published_at
|
|
70
|
-
}))
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
function blockedEvidence(query, timeoutMs, status, blockers) {
|
|
74
|
-
return {
|
|
75
|
-
schema: XAI_SEARCH_EVIDENCE_SCHEMA,
|
|
76
|
-
generated_at: nowIso(),
|
|
77
|
-
ok: false,
|
|
78
|
-
query,
|
|
79
|
-
status,
|
|
80
|
-
timeout_ms: timeoutMs,
|
|
81
|
-
results: [],
|
|
82
|
-
raw_response_artifact: null,
|
|
83
|
-
redacted_summary: { result_count: 0, urls: [] },
|
|
84
|
-
blockers
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
function withTimeout(promise, timeoutMs) {
|
|
88
|
-
return new Promise((resolve, reject) => {
|
|
89
|
-
const timer = setTimeout(() => reject(new Error('xai_search_timeout')), timeoutMs);
|
|
90
|
-
timer.unref?.();
|
|
91
|
-
promise.then((value) => {
|
|
92
|
-
clearTimeout(timer);
|
|
93
|
-
resolve(value);
|
|
94
|
-
}, (err) => {
|
|
95
|
-
clearTimeout(timer);
|
|
96
|
-
reject(err);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
//# sourceMappingURL=xai-search-adapter.js.map
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// @ts-nocheck
|
|
3
|
-
import { assertGate, emitGate, importDist } from './sks-1-18-gate-lib.js';
|
|
4
|
-
const detector = await importDist('core/mcp/xai-mcp-detector.js');
|
|
5
|
-
const detection = detector.detectXaiMcpFromConfig([
|
|
6
|
-
{ path: 'fixture.toml', source: 'provided', text: '[mcp_servers.grok]\ntools = ["search", "query"]\n' }
|
|
7
|
-
]);
|
|
8
|
-
assertGate(detection.ok === true, 'X AI detector must not fail');
|
|
9
|
-
assertGate(detection.configured === true, 'X AI detector must detect configured Grok MCP');
|
|
10
|
-
assertGate(detection.search_capable === true, 'X AI detector must detect search-capable tools');
|
|
11
|
-
const missing = detector.detectXaiMcpFromConfig([]);
|
|
12
|
-
assertGate(missing.ok === true && missing.status === 'missing', 'missing X AI MCP must be ok fallback');
|
|
13
|
-
emitGate('xai-mcp:capability', { configured_status: detection.status, missing_status: missing.status });
|
|
14
|
-
//# sourceMappingURL=xai-mcp-capability-check.js.map
|