0xray 4.0.34 → 4.0.36
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/.grok-plugin/plugin.json +1 -1
- package/.xray/codex.json +12 -4
- package/.xray/features.json +1 -1
- package/AGENTS-consumer.md +6 -6
- package/AGENTS.md +5 -5
- package/README.md +2 -2
- package/dist/AGENTS.md +5 -5
- package/dist/CHANGELOG.md +26 -0
- package/dist/README.md +2 -2
- package/dist/cli/index.js +2 -5
- package/dist/governance/governance-service.js +1 -1
- package/dist/integrations/base/README.md +1 -9
- package/dist/integrations/base/index.d.ts +0 -1
- package/dist/integrations/base/index.js +0 -2
- package/dist/integrations/governance/index.js +31 -8
- package/dist/integrations/grok/hooks/grok-hook-utils.js +1 -1
- package/dist/integrations/grok/hooks/session-start.js +12 -0
- package/dist/integrations/grok/plugin/0xray/hooks/hooks.json +6 -6
- package/dist/integrations/hooks/goggles-mcp.mjs +10 -3
- package/dist/integrations/hooks/goggles-pipeline.mjs +110 -23
- package/dist/integrations/hooks/host-truth.mjs +74 -0
- package/dist/integrations/hooks/station-hook-runtime.cjs +3 -0
- package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/dist/mcps/knowledge-skills/storyteller.server.js +0 -1
- package/dist/nucleus/delegation-gate.d.ts +2 -2
- package/dist/nucleus/delegation-gate.js +13 -2
- package/dist/nucleus/work-freshness.mjs +189 -0
- package/dist/processors/implementations/agents-md-validation-processor.js +1 -1
- package/docs-site/docs/plates/boot.md +17 -2
- package/docs-site/docs/plates/governance.md +3 -2
- package/docs-site/docs/plates/index.md +3 -1
- package/docs-site/docs/plates/memory-recall.md +26 -35
- package/docs-site/docs/plates/orchestration.md +39 -35
- package/docs-site/docs/plates/processor.md +34 -36
- package/docs-site/docs/plates/reporting.md +3 -8
- package/docs-site/docs/plates/routing.md +22 -11
- package/package.json +3 -2
- package/scripts/foundry/release.mjs +48 -5
- package/scripts/mjs/run-grok-hook.mjs +50 -0
- package/scripts/mjs/test-consumer-readiness.mjs +1 -0
- package/scripts/mjs/test-mcp-functionality.mjs +14 -9
- package/scripts/node/basic-security-audit.cjs +0 -1
- package/scripts/node/bridge-mcp-wiring.cjs +66 -3
- package/scripts/node/install-bridges.cjs +3 -3
- package/scripts/node/postinstall.cjs +1 -1
- package/scripts/node/prepare-consumer.cjs +11 -7
- package/scripts/node/setup-dev.cjs +18 -26
- package/scripts/node/validate-mcp-connectivity.js +2 -1
- package/src/integrations/grok/plugin/0xray/hooks/hooks.json +6 -6
- package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/src/mcps/knowledge-skills/storyteller.server.ts +0 -1
- package/xray/agents_template.md +5 -5
- package/xray/codex.json +12 -4
- package/xray/features.json +1 -1
- package/dist/agents/known-names.d.ts +0 -26
- package/dist/agents/known-names.js +0 -72
- package/dist/analytics/consent-manager.d.ts +0 -92
- package/dist/analytics/consent-manager.js +0 -257
- package/dist/benchmark/performance-benchmark.d.ts +0 -103
- package/dist/benchmark/performance-benchmark.js +0 -373
- package/dist/cli/commands/analytics-disable.d.ts +0 -9
- package/dist/cli/commands/analytics-disable.js +0 -72
- package/dist/cli/commands/analytics-enable-action.d.ts +0 -8
- package/dist/cli/commands/analytics-enable-action.js +0 -82
- package/dist/cli/commands/analytics-preview.d.ts +0 -9
- package/dist/cli/commands/analytics-preview.js +0 -106
- package/dist/cli/commands/analytics-status.d.ts +0 -9
- package/dist/cli/commands/analytics-status.js +0 -68
- package/dist/cli/commands/enforce.d.ts +0 -12
- package/dist/cli/commands/enforce.js +0 -78
- package/dist/cli/commands/govern.d.ts +0 -29
- package/dist/cli/commands/govern.js +0 -149
- package/dist/cli/commands/security-audit.d.ts +0 -23
- package/dist/cli/commands/security-audit.js +0 -219
- package/dist/cli/server.d.ts +0 -1
- package/dist/cli/server.js +0 -147
- package/dist/config/routing-mappings.d.ts +0 -26
- package/dist/config/routing-mappings.js +0 -151
- package/dist/core/bridge.mjs +0 -922
- package/dist/core/trace-context.d.ts +0 -12
- package/dist/core/trace-context.js +0 -33
- package/dist/enforcement/index.d.ts +0 -22
- package/dist/enforcement/index.js +0 -40
- package/dist/enforcement/loaders/index.d.ts +0 -36
- package/dist/enforcement/loaders/index.js +0 -39
- package/dist/enforcement/test-auto-healing.d.ts +0 -83
- package/dist/enforcement/test-auto-healing.js +0 -325
- package/dist/inference/index.d.ts +0 -10
- package/dist/inference/index.js +0 -5
- package/dist/infrastructure/iac-validator.d.ts +0 -150
- package/dist/infrastructure/iac-validator.js +0 -465
- package/dist/infrastructure/schemas/cloud-schemas.d.ts +0 -482
- package/dist/infrastructure/schemas/cloud-schemas.js +0 -488
- package/dist/integrations/base/ExampleIntegration.d.ts +0 -46
- package/dist/integrations/base/ExampleIntegration.js +0 -180
- package/dist/integrations/enforcement-gate.d.ts +0 -44
- package/dist/integrations/enforcement-gate.js +0 -348
- package/dist/mcps/connection/connection-manager.d.ts +0 -39
- package/dist/mcps/connection/connection-manager.js +0 -79
- package/dist/mcps/index.d.ts +0 -17
- package/dist/mcps/index.js +0 -65
- package/dist/mcps/orchestrator/index.d.ts +0 -6
- package/dist/mcps/orchestrator/index.js +0 -5
- package/dist/metrics/index.d.ts +0 -6
- package/dist/metrics/index.js +0 -6
- package/dist/orchestrator/self-direction-activation.d.ts +0 -108
- package/dist/orchestrator/self-direction-activation.js +0 -244
- package/dist/orchestrator/universal-registry-bridge.d.ts +0 -84
- package/dist/orchestrator/universal-registry-bridge.js +0 -246
- package/dist/performance/performance-budget-enforcer.d.ts +0 -157
- package/dist/performance/performance-budget-enforcer.js +0 -433
- package/dist/performance/performance-regression-tester.d.ts +0 -107
- package/dist/performance/performance-regression-tester.js +0 -341
- package/dist/postprocessor/analysis/CodeChangeAnalyzer.d.ts +0 -11
- package/dist/postprocessor/analysis/CodeChangeAnalyzer.js +0 -50
- package/dist/postprocessor/config/ProcessorConfigLoader.d.ts +0 -44
- package/dist/postprocessor/config/ProcessorConfigLoader.js +0 -16
- package/dist/postprocessor/integration.d.ts +0 -156
- package/dist/postprocessor/integration.js +0 -194
- package/dist/postprocessor/metamorphosis/index.d.ts +0 -2
- package/dist/postprocessor/metamorphosis/index.js +0 -1
- package/dist/postprocessor/redeploy/RetryHandler.d.ts +0 -49
- package/dist/postprocessor/redeploy/RetryHandler.js +0 -118
- package/dist/processors/implementations/session-capture-processor.d.ts +0 -14
- package/dist/processors/implementations/session-capture-processor.js +0 -37
- package/dist/public/XrayService.d.ts +0 -17
- package/dist/public/XrayService.js +0 -40
- package/dist/public/index.d.ts +0 -4
- package/dist/public/index.js +0 -2
- package/dist/security/comprehensive-security-audit.d.ts +0 -157
- package/dist/security/comprehensive-security-audit.js +0 -1004
- package/dist/security/index.d.ts +0 -13
- package/dist/security/index.js +0 -13
- package/dist/security/security-agent-coordinator.d.ts +0 -71
- package/dist/security/security-agent-coordinator.js +0 -203
- package/dist/security/security-hardening-system.d.ts +0 -238
- package/dist/security/security-hardening-system.js +0 -726
- package/dist/security/security-orchestration-layer.d.ts +0 -118
- package/dist/security/security-orchestration-layer.js +0 -495
- package/dist/testing/memory-regression-suite.d.ts +0 -105
- package/dist/testing/memory-regression-suite.js +0 -258
- package/dist/tools/assess-complexity-tool.d.ts +0 -28
- package/dist/tools/assess-complexity-tool.js +0 -44
- package/dist/tools/query-routing-tool.d.ts +0 -17
- package/dist/tools/query-routing-tool.js +0 -59
- package/dist/utils/batch-operations.d.ts +0 -25
- package/dist/utils/batch-operations.js +0 -292
- package/dist/utils/task-graph.d.ts +0 -29
- package/dist/utils/task-graph.js +0 -106
- package/dist/utils/test-template-generator.d.ts +0 -25
- package/dist/utils/test-template-generator.js +0 -178
- package/dist/utils/token-manager.d.ts +0 -48
- package/dist/utils/token-manager.js +0 -163
- package/dist/validation/agent-config-validator.d.ts +0 -110
- package/dist/validation/agent-config-validator.js +0 -280
- package/dist/validation/orchestration-flow-validator.d.ts +0 -87
- package/dist/validation/orchestration-flow-validator.js +0 -606
- package/src/mcps/connection/connection-manager.ts +0 -91
- package/src/mcps/index.ts +0 -80
- package/src/mcps/orchestrator/index.ts +0 -29
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
import { spawn } from "child_process";
|
|
2
|
-
import * as fs from "fs";
|
|
3
|
-
import * as path from "path";
|
|
4
|
-
import { getBatchOperations } from "../core/features-config.js";
|
|
5
|
-
/**
|
|
6
|
-
* Validate operation is safe for command execution
|
|
7
|
-
* Prevents command injection by validating patterns and replacements
|
|
8
|
-
*/
|
|
9
|
-
function validateSafeString(str, operationType) {
|
|
10
|
-
// Allow only alphanumeric, basic regex characters, and whitespace
|
|
11
|
-
// SECURITY: Blocks shell metacharacters that could enable command injection
|
|
12
|
-
const safePattern = /^[a-zA-Z0-9\s\-_.@\\{}()*+?^$.|<>]+$/;
|
|
13
|
-
const isSafe = safePattern.test(str) && str.length <= 200;
|
|
14
|
-
if (!isSafe) {
|
|
15
|
-
const errorMsg = operationType
|
|
16
|
-
? `Invalid ${operationType} operation: ${str}`
|
|
17
|
-
: `Invalid operation: ${str}`;
|
|
18
|
-
throw new Error(errorMsg);
|
|
19
|
-
}
|
|
20
|
-
return isSafe;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Validate operation type and pattern/replacement strings
|
|
24
|
-
*/
|
|
25
|
-
function validateOperation(op) {
|
|
26
|
-
// For FileOperation, validate the operation type
|
|
27
|
-
if ("operation" in op) {
|
|
28
|
-
const allowedOperations = ["replace", "append", "prepend", "delete"];
|
|
29
|
-
if (!allowedOperations.includes(op.operation)) {
|
|
30
|
-
throw new Error(`Invalid operation type: ${op.operation}`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
// For ReplacementOperation, validate pattern/replacement strings
|
|
34
|
-
if ("pattern" in op) {
|
|
35
|
-
// Validate pattern string for command injection prevention
|
|
36
|
-
if (op.pattern) {
|
|
37
|
-
validateSafeString(op.pattern, 'pattern');
|
|
38
|
-
}
|
|
39
|
-
// Validate replacement string if it exists (ReplacementOperation only)
|
|
40
|
-
if ("replacement" in op && op.replacement) {
|
|
41
|
-
validateSafeString(op.replacement, 'replacement');
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
// Validate content if it exists (FileOperation only)
|
|
45
|
-
if ("content" in op && op.content) {
|
|
46
|
-
validateSafeString(op.content, 'content');
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function escapeForSed(str) {
|
|
50
|
-
return str.replace(/[\/&]/g, "\\$&");
|
|
51
|
-
}
|
|
52
|
-
function escapeForGrep(str) {
|
|
53
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
54
|
-
}
|
|
55
|
-
export async function batchReplace(files, operations) {
|
|
56
|
-
const startTime = Date.now();
|
|
57
|
-
const config = getBatchOperations();
|
|
58
|
-
if (!config.enabled) {
|
|
59
|
-
return executeSequential(files, operations, startTime);
|
|
60
|
-
}
|
|
61
|
-
const firstOperation = operations[0];
|
|
62
|
-
if (config.prefer_sed_for_replacements &&
|
|
63
|
-
operations.length === 1 &&
|
|
64
|
-
firstOperation) {
|
|
65
|
-
return executeSedBatch(files, firstOperation, startTime);
|
|
66
|
-
}
|
|
67
|
-
if (config.parallel_file_updates &&
|
|
68
|
-
files.length > config.auto_batch_threshold) {
|
|
69
|
-
return executeParallelBatch(files, operations, config.max_concurrent_edits, startTime);
|
|
70
|
-
}
|
|
71
|
-
return executeSequential(files, operations, startTime);
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Execute sed command using spawn to prevent command injection
|
|
75
|
-
* SECURITY: Uses array arguments to prevent shell injection attacks
|
|
76
|
-
*/
|
|
77
|
-
async function executeSedBatch(files, operation, startTime) {
|
|
78
|
-
const errors = [];
|
|
79
|
-
let filesModified = 0;
|
|
80
|
-
const pattern = operation.isRegex
|
|
81
|
-
? operation.pattern
|
|
82
|
-
: escapeForGrep(operation.pattern);
|
|
83
|
-
const replacement = escapeForSed(operation.replacement);
|
|
84
|
-
const sedFlags = operation.caseSensitive ? "g" : "gi";
|
|
85
|
-
for (const file of files) {
|
|
86
|
-
try {
|
|
87
|
-
if (!fs.existsSync(file)) {
|
|
88
|
-
errors.push({ file, error: "File not found" });
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
// SECURITY FIX: Use spawn with array arguments to prevent command injection
|
|
92
|
-
// This avoids shell interpretation and injection attacks
|
|
93
|
-
const args = ["-i", "", `s/${pattern}/${replacement}/${sedFlags}`, file];
|
|
94
|
-
await new Promise((resolve, reject) => {
|
|
95
|
-
const sedProcess = spawn("sed", args);
|
|
96
|
-
let stderr = "";
|
|
97
|
-
sedProcess.stderr?.on("data", (data) => {
|
|
98
|
-
stderr += data.toString();
|
|
99
|
-
});
|
|
100
|
-
sedProcess.on("close", (code) => {
|
|
101
|
-
if (code === 0) {
|
|
102
|
-
resolve();
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
reject(new Error(`sed failed with code ${code}: ${stderr}`));
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
sedProcess.on("error", (err) => {
|
|
109
|
-
reject(new Error(`Failed to spawn sed: ${err.message}`));
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
filesModified++;
|
|
113
|
-
}
|
|
114
|
-
catch (err) {
|
|
115
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
116
|
-
errors.push({ file, error: errorMessage });
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return {
|
|
120
|
-
success: errors.length === 0,
|
|
121
|
-
filesModified,
|
|
122
|
-
errors,
|
|
123
|
-
duration: Date.now() - startTime,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
async function executeParallelBatch(files, operations, maxConcurrent, startTime) {
|
|
127
|
-
const errors = [];
|
|
128
|
-
let filesModified = 0;
|
|
129
|
-
const chunks = [];
|
|
130
|
-
for (let i = 0; i < files.length; i += maxConcurrent) {
|
|
131
|
-
chunks.push(files.slice(i, i + maxConcurrent));
|
|
132
|
-
}
|
|
133
|
-
for (const chunk of chunks) {
|
|
134
|
-
const promises = chunk.map(async (file) => {
|
|
135
|
-
try {
|
|
136
|
-
await processFileOperations(file, operations);
|
|
137
|
-
return { file, success: true };
|
|
138
|
-
}
|
|
139
|
-
catch (err) {
|
|
140
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
141
|
-
return { file, success: false, error: errorMessage };
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
const results = await Promise.all(promises);
|
|
145
|
-
for (const result of results) {
|
|
146
|
-
if (result.success) {
|
|
147
|
-
filesModified++;
|
|
148
|
-
}
|
|
149
|
-
else if (result.error) {
|
|
150
|
-
errors.push({ file: result.file, error: result.error });
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return {
|
|
155
|
-
success: errors.length === 0,
|
|
156
|
-
filesModified,
|
|
157
|
-
errors,
|
|
158
|
-
duration: Date.now() - startTime,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
async function executeSequential(files, operations, startTime) {
|
|
162
|
-
const errors = [];
|
|
163
|
-
let filesModified = 0;
|
|
164
|
-
for (const file of files) {
|
|
165
|
-
try {
|
|
166
|
-
await processFileOperations(file, operations);
|
|
167
|
-
filesModified++;
|
|
168
|
-
}
|
|
169
|
-
catch (err) {
|
|
170
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
171
|
-
errors.push({ file, error: errorMessage });
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return {
|
|
175
|
-
success: errors.length === 0,
|
|
176
|
-
filesModified,
|
|
177
|
-
errors,
|
|
178
|
-
duration: Date.now() - startTime,
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
async function processFileOperations(filePath, operations) {
|
|
182
|
-
if (!fs.existsSync(filePath)) {
|
|
183
|
-
throw new Error(`File not found: ${filePath}`);
|
|
184
|
-
}
|
|
185
|
-
let content = fs.readFileSync(filePath, "utf-8");
|
|
186
|
-
let modified = false;
|
|
187
|
-
for (const op of operations) {
|
|
188
|
-
const flags = op.caseSensitive ? "g" : "gi";
|
|
189
|
-
const regex = op.isRegex
|
|
190
|
-
? new RegExp(op.pattern, flags)
|
|
191
|
-
: new RegExp(escapeForGrep(op.pattern), flags);
|
|
192
|
-
if (regex.test(content)) {
|
|
193
|
-
content = content.replace(regex, op.replacement);
|
|
194
|
-
modified = true;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
if (modified) {
|
|
198
|
-
fs.writeFileSync(filePath, content, "utf-8");
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
export async function batchFileOperations(operations) {
|
|
202
|
-
const startTime = Date.now();
|
|
203
|
-
const errors = [];
|
|
204
|
-
let filesModified = 0;
|
|
205
|
-
for (const op of operations) {
|
|
206
|
-
try {
|
|
207
|
-
switch (op.operation) {
|
|
208
|
-
case "replace":
|
|
209
|
-
if (op.pattern && op.content) {
|
|
210
|
-
await processFileOperations(op.filePath, [
|
|
211
|
-
{ pattern: op.pattern, replacement: op.content },
|
|
212
|
-
]);
|
|
213
|
-
}
|
|
214
|
-
break;
|
|
215
|
-
case "append":
|
|
216
|
-
if (op.content) {
|
|
217
|
-
const existing = fs.existsSync(op.filePath)
|
|
218
|
-
? fs.readFileSync(op.filePath, "utf-8")
|
|
219
|
-
: "";
|
|
220
|
-
fs.writeFileSync(op.filePath, existing + op.content, "utf-8");
|
|
221
|
-
}
|
|
222
|
-
break;
|
|
223
|
-
case "prepend":
|
|
224
|
-
if (op.content) {
|
|
225
|
-
const existing = fs.existsSync(op.filePath)
|
|
226
|
-
? fs.readFileSync(op.filePath, "utf-8")
|
|
227
|
-
: "";
|
|
228
|
-
fs.writeFileSync(op.filePath, op.content + existing, "utf-8");
|
|
229
|
-
}
|
|
230
|
-
break;
|
|
231
|
-
case "delete":
|
|
232
|
-
if (fs.existsSync(op.filePath)) {
|
|
233
|
-
fs.unlinkSync(op.filePath);
|
|
234
|
-
}
|
|
235
|
-
break;
|
|
236
|
-
}
|
|
237
|
-
filesModified++;
|
|
238
|
-
}
|
|
239
|
-
catch (err) {
|
|
240
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
241
|
-
errors.push({ file: op.filePath, error: errorMessage });
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return {
|
|
245
|
-
success: errors.length === 0,
|
|
246
|
-
filesModified,
|
|
247
|
-
errors,
|
|
248
|
-
duration: Date.now() - startTime,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
export function findFilesWithPattern(directory, pattern, extensions = [".ts", ".tsx", ".js", ".jsx", ".json"]) {
|
|
252
|
-
const results = [];
|
|
253
|
-
function searchDir(dir) {
|
|
254
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
255
|
-
for (const entry of entries) {
|
|
256
|
-
const fullPath = path.join(dir, entry.name);
|
|
257
|
-
if (entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
258
|
-
continue;
|
|
259
|
-
}
|
|
260
|
-
if (entry.isDirectory()) {
|
|
261
|
-
searchDir(fullPath);
|
|
262
|
-
}
|
|
263
|
-
else if (entry.isFile()) {
|
|
264
|
-
const ext = path.extname(entry.name);
|
|
265
|
-
if (extensions.includes(ext)) {
|
|
266
|
-
try {
|
|
267
|
-
const content = fs.readFileSync(fullPath, "utf-8");
|
|
268
|
-
if (content.includes(pattern)) {
|
|
269
|
-
results.push(fullPath);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
catch {
|
|
273
|
-
continue;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
searchDir(directory);
|
|
280
|
-
return results;
|
|
281
|
-
}
|
|
282
|
-
export async function bulkRename(directory, oldName, newName, extensions = [".ts", ".tsx", ".js", ".jsx"]) {
|
|
283
|
-
const files = findFilesWithPattern(directory, oldName, extensions);
|
|
284
|
-
return batchReplace(files, [
|
|
285
|
-
{
|
|
286
|
-
pattern: oldName,
|
|
287
|
-
replacement: newName,
|
|
288
|
-
isRegex: false,
|
|
289
|
-
caseSensitive: true,
|
|
290
|
-
},
|
|
291
|
-
]);
|
|
292
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Task graph utilities — pure functions for dependency resolution,
|
|
3
|
-
* topological sorting, and conflict resolution.
|
|
4
|
-
*
|
|
5
|
-
* Extracted from KernelOrchestrator for neutral access.
|
|
6
|
-
*/
|
|
7
|
-
import type { TaskDefinition } from "../agents/types.js";
|
|
8
|
-
/**
|
|
9
|
-
* DFS-based topological sort with circular dependency detection.
|
|
10
|
-
*/
|
|
11
|
-
export declare function topologicalSort(tasks: TaskDefinition[]): TaskDefinition[];
|
|
12
|
-
/**
|
|
13
|
-
* Validates that all task dependencies are within the current task batch.
|
|
14
|
-
* Throws a descriptive error listing cross-orchestrator dependencies.
|
|
15
|
-
*/
|
|
16
|
-
export declare function validateTaskDependencies(tasks: TaskDefinition[]): void;
|
|
17
|
-
export interface ConflictInput {
|
|
18
|
-
response?: unknown;
|
|
19
|
-
proposed?: unknown;
|
|
20
|
-
expertiseScore?: number;
|
|
21
|
-
}
|
|
22
|
-
export interface ConflictResult {
|
|
23
|
-
response: string;
|
|
24
|
-
expertiseScore: number;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Resolve conflicts by majority vote or highest expertise score.
|
|
28
|
-
*/
|
|
29
|
-
export declare function resolveConflicts(conflicts: ConflictInput[], strategy?: "majority_vote" | "expert_priority"): ConflictResult;
|
package/dist/utils/task-graph.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Task graph utilities — pure functions for dependency resolution,
|
|
3
|
-
* topological sorting, and conflict resolution.
|
|
4
|
-
*
|
|
5
|
-
* Extracted from KernelOrchestrator for neutral access.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* DFS-based topological sort with circular dependency detection.
|
|
9
|
-
*/
|
|
10
|
-
export function topologicalSort(tasks) {
|
|
11
|
-
const visited = new Set();
|
|
12
|
-
const visiting = new Set();
|
|
13
|
-
const result = [];
|
|
14
|
-
const visit = (taskId) => {
|
|
15
|
-
if (visiting.has(taskId)) {
|
|
16
|
-
throw new Error(`Circular dependency detected: ${taskId}`);
|
|
17
|
-
}
|
|
18
|
-
if (visited.has(taskId)) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
visiting.add(taskId);
|
|
22
|
-
const task = tasks.find((t) => t.id === taskId);
|
|
23
|
-
if (task && task.dependencies) {
|
|
24
|
-
for (const dep of task.dependencies) {
|
|
25
|
-
visit(dep);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
visiting.delete(taskId);
|
|
29
|
-
visited.add(taskId);
|
|
30
|
-
if (task) {
|
|
31
|
-
result.push(task);
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
for (const task of tasks) {
|
|
35
|
-
if (!visited.has(task.id)) {
|
|
36
|
-
visit(task.id);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return result;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Validates that all task dependencies are within the current task batch.
|
|
43
|
-
* Throws a descriptive error listing cross-orchestrator dependencies.
|
|
44
|
-
*/
|
|
45
|
-
export function validateTaskDependencies(tasks) {
|
|
46
|
-
const taskIds = new Set(tasks.map((t) => t.id));
|
|
47
|
-
const errors = [];
|
|
48
|
-
for (const task of tasks) {
|
|
49
|
-
if (task.dependencies && task.dependencies.length > 0) {
|
|
50
|
-
for (const dep of task.dependencies) {
|
|
51
|
-
if (!taskIds.has(dep)) {
|
|
52
|
-
errors.push(`Task "${task.id}" depends on "${dep}" which is NOT in this orchestrator's task batch.\n` +
|
|
53
|
-
`Available tasks in this batch: ${Array.from(taskIds).join(", ")}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (errors.length > 0) {
|
|
59
|
-
const errorMessage = `[TEST ARCHITECTURE ERROR] Cross-orchestrator dependencies detected.\n\n` +
|
|
60
|
-
`${errors.join("\n\n")}\n\n` +
|
|
61
|
-
`This usually means:\n` +
|
|
62
|
-
`1. You're creating multiple orchestrator instances in one test\n` +
|
|
63
|
-
`2. Task dependencies are crossing orchestrator boundaries\n\n` +
|
|
64
|
-
`FIX: Either:\n` +
|
|
65
|
-
`A) Include the missing dependency task in this executeComplexTask() call\n` +
|
|
66
|
-
`B) Use a single orchestrator for all dependent tasks\n` +
|
|
67
|
-
`C) Remove the dependency if it's not needed\n\n` +
|
|
68
|
-
`Example of correct usage:\n` +
|
|
69
|
-
` const orch = new XrayOrchestrator();\n` +
|
|
70
|
-
` await orch.executeComplexTask("test", [\n` +
|
|
71
|
-
` { id: "task-1" },\n` +
|
|
72
|
-
` { id: "task-2", dependencies: ["task-1"] } // Same orchestrator\n` +
|
|
73
|
-
` ]);`;
|
|
74
|
-
throw new Error(errorMessage);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Resolve conflicts by majority vote or highest expertise score.
|
|
79
|
-
*/
|
|
80
|
-
export function resolveConflicts(conflicts, strategy) {
|
|
81
|
-
if (conflicts.length === 0) {
|
|
82
|
-
return { response: "", expertiseScore: 0 };
|
|
83
|
-
}
|
|
84
|
-
if (strategy === "majority_vote") {
|
|
85
|
-
const votes = {};
|
|
86
|
-
conflicts.forEach((conflict) => {
|
|
87
|
-
const response = String(conflict.response ?? conflict.proposed ?? "");
|
|
88
|
-
votes[response] = (votes[response] || 0) + 1;
|
|
89
|
-
});
|
|
90
|
-
const maxVotes = Math.max(...Object.values(votes));
|
|
91
|
-
const winner = Object.entries(votes).find(([_, voteCount]) => voteCount === maxVotes);
|
|
92
|
-
if (winner) {
|
|
93
|
-
const winningConflicts = conflicts.filter((c) => String(c.response ?? c.proposed ?? "") === winner[0]);
|
|
94
|
-
const avgExpertise = winningConflicts.reduce((sum, c) => sum + (c.expertiseScore || 0), 0) / winningConflicts.length;
|
|
95
|
-
return { response: winner[0], expertiseScore: avgExpertise };
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
// Fallback to highest expertise score
|
|
99
|
-
const bestConflict = conflicts.reduce((best, current) => (current.expertiseScore || 0) > (best.expertiseScore || 0)
|
|
100
|
-
? current
|
|
101
|
-
: best);
|
|
102
|
-
return {
|
|
103
|
-
response: String(bestConflict.response ?? bestConflict.proposed ?? ""),
|
|
104
|
-
expertiseScore: bestConflict.expertiseScore || 0,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test Template Generator for 0xRay Framework
|
|
3
|
-
*
|
|
4
|
-
* Automatically generates test templates for different file types
|
|
5
|
-
* to ensure consistent test coverage and structure.
|
|
6
|
-
*/
|
|
7
|
-
export interface TestTemplateOptions {
|
|
8
|
-
filePath: string;
|
|
9
|
-
componentName?: string;
|
|
10
|
-
exports?: string[];
|
|
11
|
-
isReact?: boolean;
|
|
12
|
-
isTypeScript?: boolean;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Generate a test template based on file type and structure
|
|
16
|
-
*/
|
|
17
|
-
export declare function generateTestTemplate(options: TestTemplateOptions): string;
|
|
18
|
-
/**
|
|
19
|
-
* Analyze a source file to extract exports for test generation
|
|
20
|
-
*/
|
|
21
|
-
export declare function analyzeSourceFile(filePath: string): {
|
|
22
|
-
exports: string[];
|
|
23
|
-
isReact: boolean;
|
|
24
|
-
isTypeScript: boolean;
|
|
25
|
-
};
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test Template Generator for 0xRay Framework
|
|
3
|
-
*
|
|
4
|
-
* Automatically generates test templates for different file types
|
|
5
|
-
* to ensure consistent test coverage and structure.
|
|
6
|
-
*/
|
|
7
|
-
import { frameworkLogger } from "../core/framework-logger.js";
|
|
8
|
-
import fs from "fs";
|
|
9
|
-
/**
|
|
10
|
-
* Generate a test template based on file type and structure
|
|
11
|
-
*/
|
|
12
|
-
export function generateTestTemplate(options) {
|
|
13
|
-
const { filePath, componentName, exports = [], isReact = false, isTypeScript = false, } = options;
|
|
14
|
-
const fileName = filePath
|
|
15
|
-
.split("/")
|
|
16
|
-
.pop()
|
|
17
|
-
?.replace(/\.(ts|tsx|js|jsx)$/, "") || "Unknown";
|
|
18
|
-
const testFileName = `${fileName}.test.${isTypeScript ? "ts" : "js"}${isReact ? "x" : ""}`;
|
|
19
|
-
if (isReact) {
|
|
20
|
-
return generateReactTestTemplate(fileName, componentName || fileName, isTypeScript);
|
|
21
|
-
}
|
|
22
|
-
return generateUnitTestTemplate(fileName, exports, isTypeScript);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Generate React component test template
|
|
26
|
-
*/
|
|
27
|
-
function generateReactTestTemplate(fileName, componentName, isTypeScript) {
|
|
28
|
-
const typeAnnotation = isTypeScript ? ": RenderResult" : "";
|
|
29
|
-
const typeImport = isTypeScript ? ", RenderResult" : "";
|
|
30
|
-
return `import { render, screen } from '@testing-library/react';
|
|
31
|
-
import { expect, describe, it${typeImport} } from '${isTypeScript ? "vitest" : "jest"}';
|
|
32
|
-
import { ${componentName} } from './${fileName}';
|
|
33
|
-
|
|
34
|
-
describe('${componentName}', () => {
|
|
35
|
-
it('should render successfully', () => {
|
|
36
|
-
const { container }${typeAnnotation} = render(<${componentName} />);
|
|
37
|
-
expect(container).toBeInTheDocument();
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('should render with default props', () => {
|
|
41
|
-
render(<${componentName} />);
|
|
42
|
-
// Add specific assertions based on component behavior
|
|
43
|
-
expect(screen.getByRole('generic')).toBeInTheDocument();
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
// Add more test cases based on component props and behavior
|
|
47
|
-
// it('should handle prop changes', () => {
|
|
48
|
-
// const { rerender } = render(<${componentName} prop="value" />);
|
|
49
|
-
// expect(screen.getByText('value')).toBeInTheDocument();
|
|
50
|
-
//
|
|
51
|
-
// rerender(<${componentName} prop="newValue" />);
|
|
52
|
-
// expect(screen.getByText('newValue')).toBeInTheDocument();
|
|
53
|
-
// });
|
|
54
|
-
|
|
55
|
-
// Add accessibility tests
|
|
56
|
-
it('should be accessible', () => {
|
|
57
|
-
const { container } = render(<${componentName} />);
|
|
58
|
-
expect(container).toBeAccessible();
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
`;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Generate unit test template for utility functions/classes
|
|
65
|
-
*/
|
|
66
|
-
function generateUnitTestTemplate(fileName, exports, isTypeScript) {
|
|
67
|
-
const describeBlocks = exports
|
|
68
|
-
.map((exportName) => {
|
|
69
|
-
if (exportName.match(/^[A-Z]/)) {
|
|
70
|
-
// Class export
|
|
71
|
-
return generateClassTestTemplate(exportName);
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
// Function export
|
|
75
|
-
return generateFunctionTestTemplate(exportName);
|
|
76
|
-
}
|
|
77
|
-
})
|
|
78
|
-
.join("\n\n");
|
|
79
|
-
return `import { expect, describe, it } from '${isTypeScript ? "vitest" : "jest"}';
|
|
80
|
-
${exports.length > 0 ? `import { ${exports.join(", ")} } from './${fileName}';` : `// import functions from './${fileName}'`}
|
|
81
|
-
|
|
82
|
-
${describeBlocks}
|
|
83
|
-
|
|
84
|
-
describe('${fileName}', () => {
|
|
85
|
-
// Add general module tests here
|
|
86
|
-
it('should export expected functions', () => {
|
|
87
|
-
${exports.length > 0 ? exports.map((exp) => `expect(typeof ${exp}).toBe('function');`).join("\n ") : "// Add export tests"}
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
`;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Generate test template for a class
|
|
94
|
-
*/
|
|
95
|
-
function generateClassTestTemplate(className) {
|
|
96
|
-
return `describe('${className}', () => {
|
|
97
|
-
let instance: ${className};
|
|
98
|
-
|
|
99
|
-
beforeEach(() => {
|
|
100
|
-
// instance = new ${className}();
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('should create instance successfully', () => {
|
|
104
|
-
// expect(instance).toBeInstanceOf(${className});
|
|
105
|
-
expect(true).toBe(true); // Placeholder test
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// Add method tests
|
|
109
|
-
// it('should have expected methods', () => {
|
|
110
|
-
// expect(typeof instance.methodName).toBe('function');
|
|
111
|
-
// });
|
|
112
|
-
|
|
113
|
-
// Add property tests
|
|
114
|
-
// it('should have expected properties', () => {
|
|
115
|
-
// expect(instance.propertyName).toBeDefined();
|
|
116
|
-
// });
|
|
117
|
-
});`;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Generate test template for a function
|
|
121
|
-
*/
|
|
122
|
-
function generateFunctionTestTemplate(functionName) {
|
|
123
|
-
return `describe('${functionName}', () => {
|
|
124
|
-
it('should be a function', () => {
|
|
125
|
-
expect(typeof ${functionName}).toBe('function');
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('should handle basic input', () => {
|
|
129
|
-
// const result = ${functionName}(/* test input */);
|
|
130
|
-
// expect(result).toBe(/* expected output */);
|
|
131
|
-
expect(true).toBe(true); // Placeholder test
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('should handle edge cases', () => {
|
|
135
|
-
// Test null, undefined, empty inputs
|
|
136
|
-
// expect(() => ${functionName}(null)).toThrow();
|
|
137
|
-
expect(true).toBe(true); // Placeholder test
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// Add more specific test cases based on function behavior
|
|
141
|
-
});`;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Analyze a source file to extract exports for test generation
|
|
145
|
-
*/
|
|
146
|
-
export function analyzeSourceFile(filePath) {
|
|
147
|
-
try {
|
|
148
|
-
const content = fs.readFileSync(filePath, "utf-8");
|
|
149
|
-
const exports = [];
|
|
150
|
-
const isReact = /\b(React|jsx?|tsx?)\b/.test(content) ||
|
|
151
|
-
filePath.endsWith(".tsx") ||
|
|
152
|
-
filePath.endsWith(".jsx");
|
|
153
|
-
const isTypeScript = filePath.endsWith(".ts") || filePath.endsWith(".tsx");
|
|
154
|
-
// Extract named exports
|
|
155
|
-
const exportMatches = content.match(/export\s+(?:const|function|class|let|var)\s+(\w+)/g);
|
|
156
|
-
if (exportMatches) {
|
|
157
|
-
exportMatches.forEach((match) => {
|
|
158
|
-
const nameMatch = match.match(/(?:const|function|class|let|var)\s+(\w+)/);
|
|
159
|
-
if (nameMatch && nameMatch[1] && !exports.includes(nameMatch[1])) {
|
|
160
|
-
exports.push(nameMatch[1]);
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
// Extract default export if no named exports found
|
|
165
|
-
if (exports.length === 0 && /export\s+default/.test(content)) {
|
|
166
|
-
const fileName = filePath
|
|
167
|
-
.split("/")
|
|
168
|
-
.pop()
|
|
169
|
-
?.replace(/\.(ts|tsx|js|jsx)$/, "") || "Component";
|
|
170
|
-
exports.push(fileName.charAt(0).toUpperCase() + fileName.slice(1));
|
|
171
|
-
}
|
|
172
|
-
return { exports, isReact, isTypeScript };
|
|
173
|
-
}
|
|
174
|
-
catch (error) {
|
|
175
|
-
frameworkLogger.log("test-template-generator", "analyze-file", "error", { error, message: `Error analyzing ${filePath}:` });
|
|
176
|
-
return { exports: [], isReact: false, isTypeScript: false };
|
|
177
|
-
}
|
|
178
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
export interface TokenLimits {
|
|
2
|
-
maxPromptTokens: number;
|
|
3
|
-
warningThreshold: number;
|
|
4
|
-
modelLimits: Record<string, number>;
|
|
5
|
-
}
|
|
6
|
-
export interface ContextPruningConfig {
|
|
7
|
-
enabled: boolean;
|
|
8
|
-
aggressivePruning: boolean;
|
|
9
|
-
preserveCriticalContext: boolean;
|
|
10
|
-
}
|
|
11
|
-
export declare class TokenManager {
|
|
12
|
-
private config;
|
|
13
|
-
constructor(configPath?: string);
|
|
14
|
-
private loadConfig;
|
|
15
|
-
/**
|
|
16
|
-
* Estimate token count for text (rough approximation)
|
|
17
|
-
* Uses 4 characters per token as a conservative estimate
|
|
18
|
-
*/
|
|
19
|
-
estimateTokens(text: string): number;
|
|
20
|
-
/**
|
|
21
|
-
* Check if prompt exceeds limits
|
|
22
|
-
*/
|
|
23
|
-
checkLimits(prompt: string, modelName?: string): {
|
|
24
|
-
withinLimit: boolean;
|
|
25
|
-
currentTokens: number;
|
|
26
|
-
maxTokens: number;
|
|
27
|
-
needsPruning: boolean;
|
|
28
|
-
warning: boolean;
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* Prune context to fit within token limits
|
|
32
|
-
*/
|
|
33
|
-
pruneContext(context: string, targetTokens?: number): string;
|
|
34
|
-
private extractCriticalSections;
|
|
35
|
-
private extractSection;
|
|
36
|
-
private extractNonCriticalContent;
|
|
37
|
-
private pruneNonCriticalContent;
|
|
38
|
-
/**
|
|
39
|
-
* Generate warning message for token limits
|
|
40
|
-
*/
|
|
41
|
-
generateWarning(limitCheck: ReturnType<TokenManager["checkLimits"]>): string;
|
|
42
|
-
/**
|
|
43
|
-
* Get current configuration
|
|
44
|
-
*/
|
|
45
|
-
getConfig(): TokenLimits & {
|
|
46
|
-
contextPruning: ContextPruningConfig;
|
|
47
|
-
};
|
|
48
|
-
}
|