nexus-agents 2.26.1 → 2.28.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 -7
- package/dist/{chunk-X33QNBGA.js → chunk-E7EX2KQJ.js} +3 -5
- package/dist/{chunk-X33QNBGA.js.map → chunk-E7EX2KQJ.js.map} +1 -1
- package/dist/{chunk-BOWNZMPH.js → chunk-L2SHSW4T.js} +3017 -1300
- package/dist/chunk-L2SHSW4T.js.map +1 -0
- package/dist/{chunk-ARNVVQ5W.js → chunk-LKSTILEE.js} +1213 -117
- package/dist/chunk-LKSTILEE.js.map +1 -0
- package/dist/{chunk-L3LQ3RP5.js → chunk-QZEAD6AG.js} +10339 -6289
- package/dist/chunk-QZEAD6AG.js.map +1 -0
- package/dist/{chunk-LCHCASB7.js → chunk-UGNLR4NZ.js} +2 -2
- package/dist/{chunk-UVQ7R4C4.js → chunk-YSDUVCCZ.js} +137 -717
- package/dist/chunk-YSDUVCCZ.js.map +1 -0
- package/dist/cli.d.ts +8 -1
- package/dist/cli.js +644 -216
- package/dist/cli.js.map +1 -1
- package/dist/{dist-Y5F6UM2N.js → dist-H5XNXVAV.js} +1384 -1295
- package/dist/dist-H5XNXVAV.js.map +1 -0
- package/dist/doctor-deep-BDE2PHVX.js +11 -0
- package/dist/index.d.ts +4299 -7411
- package/dist/index.js +588 -132
- package/dist/index.js.map +1 -1
- package/dist/{setup-command-VNF3KTCJ.js → setup-command-SS7LMN7Y.js} +5 -6
- package/dist/setup-config-DSMOOLVW.js +9 -0
- package/dist/workflows/templates/code-review.yaml +1 -1
- package/dist/workflows/templates/refactoring.yaml +1 -1
- package/dist/workflows/templates/research-review.yaml +19 -4
- package/dist/workflows/templates/security-audit.yaml +1 -1
- package/dist/workflows/templates/standards-review.yaml +1 -1
- package/package.json +12 -12
- package/src/workflows/templates/code-review.yaml +1 -1
- package/src/workflows/templates/refactoring.yaml +1 -1
- package/src/workflows/templates/research-review.yaml +19 -4
- package/src/workflows/templates/security-audit.yaml +1 -1
- package/src/workflows/templates/standards-review.yaml +1 -1
- package/dist/chunk-ARNVVQ5W.js.map +0 -1
- package/dist/chunk-BOWNZMPH.js.map +0 -1
- package/dist/chunk-L3LQ3RP5.js.map +0 -1
- package/dist/chunk-LCDOP543.js +0 -365
- package/dist/chunk-LCDOP543.js.map +0 -1
- package/dist/chunk-PGNRXCYY.js +0 -776
- package/dist/chunk-PGNRXCYY.js.map +0 -1
- package/dist/chunk-UVQ7R4C4.js.map +0 -1
- package/dist/dist-Y5F6UM2N.js.map +0 -1
- package/dist/doctor-deep-I2J5CRFG.js +0 -13
- package/dist/setup-config-VQSWWJ5O.js +0 -9
- /package/dist/{chunk-LCHCASB7.js.map → chunk-UGNLR4NZ.js.map} +0 -0
- /package/dist/{doctor-deep-I2J5CRFG.js.map → doctor-deep-BDE2PHVX.js.map} +0 -0
- /package/dist/{setup-command-VNF3KTCJ.js.map → setup-command-SS7LMN7Y.js.map} +0 -0
- /package/dist/{setup-config-VQSWWJ5O.js.map → setup-config-DSMOOLVW.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
createFeedbackIntegration,
|
|
41
41
|
createFullGitHubProvider,
|
|
42
42
|
createGatewayServerProxy,
|
|
43
|
+
createHarnessExecutor,
|
|
43
44
|
createLearnablePolicy,
|
|
44
45
|
createMockTechLead,
|
|
45
46
|
createRealWorkflowEngine,
|
|
@@ -123,6 +124,7 @@ import {
|
|
|
123
124
|
registerResearchCatalogReviewTool,
|
|
124
125
|
registerResearchDiscoverTool,
|
|
125
126
|
registerResearchQueryTool,
|
|
127
|
+
registerResearchSynthesizeTool,
|
|
126
128
|
registerResources,
|
|
127
129
|
registerRunGraphWorkflowTool,
|
|
128
130
|
registerRunWorkflowTool,
|
|
@@ -134,17 +136,17 @@ import {
|
|
|
134
136
|
sanitizeInput,
|
|
135
137
|
setGlobalToolRateLimiterFactory,
|
|
136
138
|
shutdownToolMemory,
|
|
139
|
+
synthesizeResearch,
|
|
137
140
|
validateArgs,
|
|
138
141
|
validateCommand,
|
|
139
142
|
validateNexusEnv,
|
|
140
143
|
validateTimeout,
|
|
141
144
|
validateWorkflow,
|
|
142
145
|
wrapInMarkdownFence
|
|
143
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-QZEAD6AG.js";
|
|
144
147
|
import {
|
|
145
|
-
doctorCommand,
|
|
146
148
|
setupCommandAsync
|
|
147
|
-
} from "./chunk-
|
|
149
|
+
} from "./chunk-YSDUVCCZ.js";
|
|
148
150
|
import {
|
|
149
151
|
VERSION,
|
|
150
152
|
capitalize,
|
|
@@ -153,11 +155,13 @@ import {
|
|
|
153
155
|
connectTransport,
|
|
154
156
|
createAllAdapters,
|
|
155
157
|
createServer,
|
|
158
|
+
doctorCommand,
|
|
156
159
|
getAvailableClis,
|
|
160
|
+
initDataDirectories,
|
|
157
161
|
isRecord,
|
|
158
162
|
truncateSentence
|
|
159
|
-
} from "./chunk-
|
|
160
|
-
import "./chunk-
|
|
163
|
+
} from "./chunk-LKSTILEE.js";
|
|
164
|
+
import "./chunk-UGNLR4NZ.js";
|
|
161
165
|
import {
|
|
162
166
|
calculateConsensus,
|
|
163
167
|
countByCategory,
|
|
@@ -175,28 +179,23 @@ import {
|
|
|
175
179
|
CATEGORY_DISPLAY_NAMES,
|
|
176
180
|
DEFAULT_PR_REVIEW_CONFIG
|
|
177
181
|
} from "./chunk-X2M7OF27.js";
|
|
178
|
-
import "./chunk-
|
|
179
|
-
import {
|
|
180
|
-
getAdaptiveBonus,
|
|
181
|
-
parseTierOverrides
|
|
182
|
-
} from "./chunk-PGNRXCYY.js";
|
|
182
|
+
import "./chunk-E7EX2KQJ.js";
|
|
183
183
|
import {
|
|
184
184
|
API_TIMEOUTS,
|
|
185
|
-
CLI_SUBPROCESS_TIMEOUTS,
|
|
186
|
-
MCP_TIMEOUTS
|
|
187
|
-
} from "./chunk-LCDOP543.js";
|
|
188
|
-
import {
|
|
189
185
|
AgentCapability,
|
|
190
186
|
AgentError,
|
|
191
187
|
CLI_NAMES,
|
|
188
|
+
CLI_SUBPROCESS_TIMEOUTS,
|
|
192
189
|
DEFAULT_CLI,
|
|
193
190
|
DEFAULT_MODEL_CAPABILITIES,
|
|
194
191
|
DEFAULT_MODEL_PROFILES,
|
|
195
192
|
ErrorCode,
|
|
196
193
|
INPUT_MODALITIES,
|
|
197
194
|
LinUCBBandit,
|
|
195
|
+
MCP_TIMEOUTS,
|
|
198
196
|
NexusError,
|
|
199
197
|
OUTPUT_MODALITIES,
|
|
198
|
+
OutcomeStore,
|
|
200
199
|
SPECIAL_FEATURES,
|
|
201
200
|
SecurityError,
|
|
202
201
|
TASK_CATEGORIES,
|
|
@@ -220,6 +219,8 @@ import {
|
|
|
220
219
|
formatPercentage,
|
|
221
220
|
formatStatus,
|
|
222
221
|
formatZodError,
|
|
222
|
+
generateWeatherReport,
|
|
223
|
+
getAdaptiveBonus,
|
|
223
224
|
getErrorMessage,
|
|
224
225
|
getModelCapabilities,
|
|
225
226
|
getOutcomeStore,
|
|
@@ -227,16 +228,18 @@ import {
|
|
|
227
228
|
getTimeProvider,
|
|
228
229
|
logger,
|
|
229
230
|
ok,
|
|
231
|
+
parseTierOverrides,
|
|
230
232
|
resetOutcomeStore,
|
|
231
233
|
runWarmUp,
|
|
232
234
|
safeRegex,
|
|
235
|
+
setOutcomeStore,
|
|
233
236
|
summarizeTaskProfile,
|
|
234
237
|
symbols,
|
|
235
238
|
taskAnalysisResultToTaskProfile,
|
|
236
239
|
toError,
|
|
237
240
|
writeEmptyLine,
|
|
238
241
|
writeLine
|
|
239
|
-
} from "./chunk-
|
|
242
|
+
} from "./chunk-L2SHSW4T.js";
|
|
240
243
|
import "./chunk-UP2VWCW5.js";
|
|
241
244
|
|
|
242
245
|
// src/cli.ts
|
|
@@ -420,8 +423,8 @@ function resolveOutputPath(output2) {
|
|
|
420
423
|
}
|
|
421
424
|
return resolve(process.cwd(), DEFAULT_CONFIG_FILE);
|
|
422
425
|
}
|
|
423
|
-
function fileExists(
|
|
424
|
-
return existsSync(
|
|
426
|
+
function fileExists(path24) {
|
|
427
|
+
return existsSync(path24);
|
|
425
428
|
}
|
|
426
429
|
async function ensureDirectory(filePath) {
|
|
427
430
|
const dir = dirname(filePath);
|
|
@@ -429,9 +432,9 @@ async function ensureDirectory(filePath) {
|
|
|
429
432
|
await mkdir(dir, { recursive: true });
|
|
430
433
|
}
|
|
431
434
|
}
|
|
432
|
-
async function writeConfigFile(
|
|
433
|
-
await ensureDirectory(
|
|
434
|
-
await writeFile(
|
|
435
|
+
async function writeConfigFile(path24) {
|
|
436
|
+
await ensureDirectory(path24);
|
|
437
|
+
await writeFile(path24, CONFIG_TEMPLATE, "utf-8");
|
|
435
438
|
}
|
|
436
439
|
async function runConfigInit(options = {}) {
|
|
437
440
|
const outputPath = resolveOutputPath(options.output);
|
|
@@ -1400,14 +1403,14 @@ ${colors.dim}Session ended.${colors.reset}
|
|
|
1400
1403
|
});
|
|
1401
1404
|
});
|
|
1402
1405
|
rl.prompt();
|
|
1403
|
-
return new Promise((
|
|
1406
|
+
return new Promise((resolve12) => {
|
|
1404
1407
|
rl.on("line", (line) => {
|
|
1405
1408
|
void (async () => {
|
|
1406
1409
|
try {
|
|
1407
1410
|
const shouldExit = await processLine(line, session, logger17);
|
|
1408
1411
|
if (shouldExit) {
|
|
1409
1412
|
rl.close();
|
|
1410
|
-
|
|
1413
|
+
resolve12();
|
|
1411
1414
|
return;
|
|
1412
1415
|
}
|
|
1413
1416
|
} catch (error) {
|
|
@@ -1419,7 +1422,7 @@ ${colors.dim}Session ended.${colors.reset}
|
|
|
1419
1422
|
})();
|
|
1420
1423
|
});
|
|
1421
1424
|
rl.on("close", () => {
|
|
1422
|
-
|
|
1425
|
+
resolve12();
|
|
1423
1426
|
});
|
|
1424
1427
|
});
|
|
1425
1428
|
}
|
|
@@ -2413,9 +2416,9 @@ async function evaluateDirectory(target, timeoutMs) {
|
|
|
2413
2416
|
}
|
|
2414
2417
|
const aggregator = createAggregator();
|
|
2415
2418
|
const results = [];
|
|
2416
|
-
for (const [
|
|
2419
|
+
for (const [path24, evaluations] of evaluationsByComponent) {
|
|
2417
2420
|
if (evaluations.length > 0) {
|
|
2418
|
-
results.push(aggregator.aggregate(
|
|
2421
|
+
results.push(aggregator.aggregate(path24, evaluations));
|
|
2419
2422
|
}
|
|
2420
2423
|
}
|
|
2421
2424
|
const priority = { deprecate: 0, refactor: 1, review: 2, retain: 3 };
|
|
@@ -3562,21 +3565,22 @@ function printSuccessMessage(durationMs) {
|
|
|
3562
3565
|
|
|
3563
3566
|
// src/cli/routing-audit-logic.ts
|
|
3564
3567
|
var logger5 = createLogger({ component: "routing-audit" });
|
|
3568
|
+
var sharedAnalyzer = createSharedTaskAnalyzer();
|
|
3565
3569
|
var CLI_NAMES2 = ["claude", "gemini", "codex", "opencode"];
|
|
3570
|
+
var CONTEXT_NORMALIZATION_TOKENS = 1e5;
|
|
3566
3571
|
function analyzeTaskString(taskStr) {
|
|
3567
3572
|
const task = {
|
|
3568
3573
|
id: "audit-" + String(getTimeProvider().now()),
|
|
3569
3574
|
description: taskStr,
|
|
3570
3575
|
context: {}
|
|
3571
3576
|
};
|
|
3572
|
-
const
|
|
3573
|
-
const analysis = analyzer.analyze(task);
|
|
3577
|
+
const analysis = sharedAnalyzer.analyze(task);
|
|
3574
3578
|
return taskAnalysisResultToTaskProfile(analysis);
|
|
3575
3579
|
}
|
|
3576
3580
|
function taskProfileToBanditContextFromProfile(profile) {
|
|
3577
3581
|
return {
|
|
3578
3582
|
taskComplexity: profile.reasoningComplexity / 10,
|
|
3579
|
-
contextLengthNormalized: Math.min(profile.contextRequired /
|
|
3583
|
+
contextLengthNormalized: Math.min(profile.contextRequired / CONTEXT_NORMALIZATION_TOKENS, 1),
|
|
3580
3584
|
isCodeTask: profile.codeGeneration ? 1 : 0,
|
|
3581
3585
|
isReasoningTask: profile.taskType === "architecture" || profile.reasoningComplexity > 5 ? 1 : 0,
|
|
3582
3586
|
budgetUtilization: 0.5,
|
|
@@ -3926,27 +3930,27 @@ var CliAdapterAgent = class {
|
|
|
3926
3930
|
};
|
|
3927
3931
|
|
|
3928
3932
|
// src/cli/orchestrate-puppeteer.ts
|
|
3929
|
-
function loadPolicyParameters(
|
|
3933
|
+
function loadPolicyParameters(path24, logger17) {
|
|
3930
3934
|
try {
|
|
3931
|
-
if (fs2.existsSync(
|
|
3932
|
-
const content = fs2.readFileSync(
|
|
3935
|
+
if (fs2.existsSync(path24)) {
|
|
3936
|
+
const content = fs2.readFileSync(path24, "utf-8");
|
|
3933
3937
|
const params = JSON.parse(content);
|
|
3934
|
-
logger17.info("Loaded policy parameters", { path:
|
|
3938
|
+
logger17.info("Loaded policy parameters", { path: path24 });
|
|
3935
3939
|
return params;
|
|
3936
3940
|
}
|
|
3937
3941
|
} catch (error) {
|
|
3938
3942
|
const message = getErrorMessage(error);
|
|
3939
|
-
logger17.warn("Failed to load policy parameters", { path:
|
|
3943
|
+
logger17.warn("Failed to load policy parameters", { path: path24, error: message });
|
|
3940
3944
|
}
|
|
3941
3945
|
return void 0;
|
|
3942
3946
|
}
|
|
3943
|
-
function savePolicyParameters(
|
|
3947
|
+
function savePolicyParameters(path24, params, logger17) {
|
|
3944
3948
|
try {
|
|
3945
|
-
fs2.writeFileSync(
|
|
3946
|
-
logger17.info("Saved policy parameters", { path:
|
|
3949
|
+
fs2.writeFileSync(path24, JSON.stringify(params, null, 2));
|
|
3950
|
+
logger17.info("Saved policy parameters", { path: path24 });
|
|
3947
3951
|
} catch (error) {
|
|
3948
3952
|
const message = getErrorMessage(error);
|
|
3949
|
-
logger17.warn("Failed to save policy parameters", { path:
|
|
3953
|
+
logger17.warn("Failed to save policy parameters", { path: path24, error: message });
|
|
3950
3954
|
}
|
|
3951
3955
|
}
|
|
3952
3956
|
function createAgentsFromAdapters(adapters) {
|
|
@@ -4874,38 +4878,33 @@ async function handleList(args, log) {
|
|
|
4874
4878
|
const format = args.includes("--json") ? "json" : "table";
|
|
4875
4879
|
const result = await sessionList({ limit, format, logger: log });
|
|
4876
4880
|
if (!result.ok) {
|
|
4877
|
-
|
|
4878
|
-
process.exit(1);
|
|
4881
|
+
throw new Error(result.error.message);
|
|
4879
4882
|
}
|
|
4880
4883
|
printSessionList(result.value, format);
|
|
4881
4884
|
}
|
|
4882
4885
|
async function handleShow(args, log) {
|
|
4883
4886
|
const sessionId = args[0];
|
|
4884
4887
|
if (sessionId === void 0) {
|
|
4885
|
-
|
|
4886
|
-
process.exit(1);
|
|
4888
|
+
throw new Error("Session ID required");
|
|
4887
4889
|
}
|
|
4888
4890
|
const format = args.includes("--json") ? "json" : "text";
|
|
4889
4891
|
const result = await sessionShow({ sessionId, format, logger: log });
|
|
4890
4892
|
if (!result.ok) {
|
|
4891
|
-
|
|
4892
|
-
process.exit(1);
|
|
4893
|
+
throw new Error(result.error.message);
|
|
4893
4894
|
}
|
|
4894
4895
|
printSessionShow(result.value, format);
|
|
4895
4896
|
}
|
|
4896
4897
|
async function handleExport(args, log) {
|
|
4897
4898
|
const sessionId = args[0];
|
|
4898
4899
|
if (sessionId === void 0) {
|
|
4899
|
-
|
|
4900
|
-
process.exit(1);
|
|
4900
|
+
throw new Error("Session ID required");
|
|
4901
4901
|
}
|
|
4902
4902
|
const outputIdx = args.indexOf("--output");
|
|
4903
4903
|
const outputPath = outputIdx >= 0 ? args[outputIdx + 1] : void 0;
|
|
4904
4904
|
const format = args.includes("--markdown") ? "markdown" : "json";
|
|
4905
4905
|
const result = await sessionExport({ sessionId, output: outputPath, format, logger: log });
|
|
4906
4906
|
if (!result.ok) {
|
|
4907
|
-
|
|
4908
|
-
process.exit(1);
|
|
4907
|
+
throw new Error(result.error.message);
|
|
4909
4908
|
}
|
|
4910
4909
|
if (outputPath === void 0) output(result.value);
|
|
4911
4910
|
else output("Exported to " + outputPath);
|
|
@@ -4913,28 +4912,24 @@ async function handleExport(args, log) {
|
|
|
4913
4912
|
async function handleDelete(args, log) {
|
|
4914
4913
|
const sessionId = args[0];
|
|
4915
4914
|
if (sessionId === void 0) {
|
|
4916
|
-
|
|
4917
|
-
process.exit(1);
|
|
4915
|
+
throw new Error("Session ID required");
|
|
4918
4916
|
}
|
|
4919
4917
|
const result = await sessionDelete({ sessionId, logger: log });
|
|
4920
4918
|
if (!result.ok) {
|
|
4921
|
-
|
|
4922
|
-
process.exit(1);
|
|
4919
|
+
throw new Error(result.error.message);
|
|
4923
4920
|
}
|
|
4924
4921
|
output(result.value ? "Session deleted." : "Session not found.");
|
|
4925
4922
|
}
|
|
4926
4923
|
async function handlePrune(args, log) {
|
|
4927
4924
|
const daysArg = args[0];
|
|
4928
4925
|
if (daysArg === void 0) {
|
|
4929
|
-
|
|
4930
|
-
process.exit(1);
|
|
4926
|
+
throw new Error("Days argument required");
|
|
4931
4927
|
}
|
|
4932
4928
|
const days = parseInt(daysArg, 10);
|
|
4933
4929
|
const dryRun = args.includes("--dry-run");
|
|
4934
4930
|
const result = await sessionPrune({ days, dryRun, logger: log });
|
|
4935
4931
|
if (!result.ok) {
|
|
4936
|
-
|
|
4937
|
-
process.exit(1);
|
|
4932
|
+
throw new Error(result.error.message);
|
|
4938
4933
|
}
|
|
4939
4934
|
const count = String(result.value);
|
|
4940
4935
|
output(dryRun ? "Would delete " + count + " sessions." : "Deleted " + count + " sessions.");
|
|
@@ -5129,9 +5124,9 @@ _Generated by \`nexus-agents system-review\`_`;
|
|
|
5129
5124
|
}
|
|
5130
5125
|
function createIssue(result) {
|
|
5131
5126
|
const date = getTimeProvider().nowDateString();
|
|
5132
|
-
const body = createIssueBody(result).replace(/
|
|
5127
|
+
const body = createIssueBody(result).replace(/'/g, "'\\''");
|
|
5133
5128
|
const out = safeExecSandboxed(
|
|
5134
|
-
`gh issue create --title
|
|
5129
|
+
`gh issue create --title 'System Review: ${date}' --body '${body}' --label 'system-review'`,
|
|
5135
5130
|
{ context: "gh" }
|
|
5136
5131
|
);
|
|
5137
5132
|
if (out !== null) {
|
|
@@ -5658,7 +5653,7 @@ function validateGitHubIssue(issueNumber) {
|
|
|
5658
5653
|
return output2 !== null;
|
|
5659
5654
|
}
|
|
5660
5655
|
function escapeForShell(text) {
|
|
5661
|
-
return text.replace(/
|
|
5656
|
+
return text.replace(/'/g, "'\\''");
|
|
5662
5657
|
}
|
|
5663
5658
|
function formatVoteComment(result) {
|
|
5664
5659
|
const now = new Date(getTimeProvider().now()).toLocaleDateString("en-US", {
|
|
@@ -5698,7 +5693,7 @@ function recordVoteToGitHub(issueNumber, result) {
|
|
|
5698
5693
|
const comment = formatVoteComment(result);
|
|
5699
5694
|
const escapedComment = escapeForShell(comment);
|
|
5700
5695
|
const output2 = safeExecSandboxed(
|
|
5701
|
-
`gh issue comment ${String(issueNumber)} --body
|
|
5696
|
+
`gh issue comment ${String(issueNumber)} --body '${escapedComment}'`,
|
|
5702
5697
|
{ context: "gh" }
|
|
5703
5698
|
);
|
|
5704
5699
|
if (output2 !== null) {
|
|
@@ -6526,9 +6521,10 @@ function generateProposal(issues, options) {
|
|
|
6526
6521
|
}
|
|
6527
6522
|
function createSprintIssue(proposal) {
|
|
6528
6523
|
try {
|
|
6529
|
-
const
|
|
6524
|
+
const escapedTitle = proposal.title.replace(/'/g, "'\\''");
|
|
6525
|
+
const escapedBody = proposal.body.replace(/'/g, "'\\''");
|
|
6530
6526
|
const output2 = safeExecSandboxed(
|
|
6531
|
-
`gh issue create --title
|
|
6527
|
+
`gh issue create --title '${escapedTitle}' --body '${escapedBody}' --label 'epic'`,
|
|
6532
6528
|
{ context: "gh" }
|
|
6533
6529
|
);
|
|
6534
6530
|
if (output2 === null) {
|
|
@@ -6818,7 +6814,7 @@ var ResearchPaperSchema = z2.object({
|
|
|
6818
6814
|
/** arXiv ID (e.g., '2501.06322') */
|
|
6819
6815
|
arxiv_id: z2.string().optional(),
|
|
6820
6816
|
/** URL to the paper */
|
|
6821
|
-
url: z2.
|
|
6817
|
+
url: z2.url().optional(),
|
|
6822
6818
|
/** Publication date (YYYY-MM format) */
|
|
6823
6819
|
publication_date: z2.string().optional(),
|
|
6824
6820
|
/** Publication venue */
|
|
@@ -6865,7 +6861,7 @@ var ResearchTechniqueSchema = z2.object({
|
|
|
6865
6861
|
/** Tags for searching */
|
|
6866
6862
|
tags: z2.array(z2.string()).optional().default([]),
|
|
6867
6863
|
/** Metrics associated with this technique */
|
|
6868
|
-
metrics: z2.record(z2.string()).optional().default({}),
|
|
6864
|
+
metrics: z2.record(z2.string(), z2.string()).optional().default({}),
|
|
6869
6865
|
/** Implementation status (required) */
|
|
6870
6866
|
status: TechniqueStatusSchema,
|
|
6871
6867
|
/** Priority level */
|
|
@@ -6887,11 +6883,11 @@ var ResearchTechniqueSchema = z2.object({
|
|
|
6887
6883
|
});
|
|
6888
6884
|
var PapersRegistrySchema = z2.object({
|
|
6889
6885
|
schema_version: z2.string(),
|
|
6890
|
-
papers: z2.record(ResearchPaperSchema)
|
|
6886
|
+
papers: z2.record(z2.string(), ResearchPaperSchema)
|
|
6891
6887
|
});
|
|
6892
6888
|
var TechniquesRegistrySchema = z2.object({
|
|
6893
6889
|
schema_version: z2.string(),
|
|
6894
|
-
techniques: z2.record(ResearchTechniqueSchema)
|
|
6890
|
+
techniques: z2.record(z2.string(), ResearchTechniqueSchema)
|
|
6895
6891
|
});
|
|
6896
6892
|
function getIntegrationFilePath(file) {
|
|
6897
6893
|
if (typeof file === "string") {
|
|
@@ -7815,9 +7811,20 @@ async function researchIndexCommand(options) {
|
|
|
7815
7811
|
}
|
|
7816
7812
|
|
|
7817
7813
|
// src/cli/research-command.ts
|
|
7814
|
+
function optString(options, key) {
|
|
7815
|
+
const val = options[key];
|
|
7816
|
+
return typeof val === "string" ? val : void 0;
|
|
7817
|
+
}
|
|
7818
|
+
function optNumber(options, key) {
|
|
7819
|
+
const val = options[key];
|
|
7820
|
+
return typeof val === "number" ? val : void 0;
|
|
7821
|
+
}
|
|
7822
|
+
function optBoolean(options, key) {
|
|
7823
|
+
return options[key] === true;
|
|
7824
|
+
}
|
|
7818
7825
|
async function handleStatusCommand(args, options) {
|
|
7819
|
-
const status = options
|
|
7820
|
-
const format = options
|
|
7826
|
+
const status = optString(options, "status") ?? "all";
|
|
7827
|
+
const format = optString(options, "format") ?? "table";
|
|
7821
7828
|
const statusOptions = {
|
|
7822
7829
|
techniqueId: args[0],
|
|
7823
7830
|
status,
|
|
@@ -7831,10 +7838,10 @@ async function handleOverlapCommand(args, options) {
|
|
|
7831
7838
|
if (techniqueId === void 0 || techniqueId === "") {
|
|
7832
7839
|
return "Error: technique-id is required for overlap command";
|
|
7833
7840
|
}
|
|
7834
|
-
const format = options
|
|
7841
|
+
const format = optString(options, "format") ?? "table";
|
|
7835
7842
|
const overlapOptions = {
|
|
7836
7843
|
techniqueId,
|
|
7837
|
-
threshold: options
|
|
7844
|
+
threshold: optNumber(options, "threshold") ?? 0.3,
|
|
7838
7845
|
format
|
|
7839
7846
|
};
|
|
7840
7847
|
const result = await findOverlaps(overlapOptions);
|
|
@@ -7847,9 +7854,9 @@ async function handleAddCommand(args, options) {
|
|
|
7847
7854
|
}
|
|
7848
7855
|
const addOptions = {
|
|
7849
7856
|
arxivId,
|
|
7850
|
-
topic: options
|
|
7851
|
-
priority: options
|
|
7852
|
-
dryRun: options
|
|
7857
|
+
topic: optString(options, "topic"),
|
|
7858
|
+
priority: optString(options, "priority"),
|
|
7859
|
+
dryRun: optBoolean(options, "dryRun")
|
|
7853
7860
|
};
|
|
7854
7861
|
const result = await addResearchPaper(addOptions);
|
|
7855
7862
|
return result.message;
|
|
@@ -7898,23 +7905,23 @@ function formatDiscoverResults(topic, items, errors, maxResults) {
|
|
|
7898
7905
|
return lines.join("\n");
|
|
7899
7906
|
}
|
|
7900
7907
|
async function handleDiscoverCommand(args, options) {
|
|
7901
|
-
const topic = args[0] ?? options
|
|
7908
|
+
const topic = args[0] ?? optString(options, "topic");
|
|
7902
7909
|
if (topic === void 0 || topic === "") {
|
|
7903
7910
|
return "Error: --topic is required for discover command";
|
|
7904
7911
|
}
|
|
7905
|
-
const source = options
|
|
7906
|
-
const maxResults = options
|
|
7912
|
+
const source = optString(options, "source") ?? "all";
|
|
7913
|
+
const maxResults = optNumber(options, "maxResults") ?? 10;
|
|
7907
7914
|
const { results, errors } = await queryDiscoverSources(topic, source, maxResults);
|
|
7908
7915
|
return formatDiscoverResults(topic, results, errors, maxResults);
|
|
7909
7916
|
}
|
|
7910
7917
|
async function handleReviewCommand(args, options) {
|
|
7911
|
-
const topic = args[0] ?? options
|
|
7918
|
+
const topic = args[0] ?? optString(options, "topic");
|
|
7912
7919
|
if (topic === void 0 || topic === "") {
|
|
7913
7920
|
return "Error: --topic is required for review command";
|
|
7914
7921
|
}
|
|
7915
|
-
const maxResults = options
|
|
7916
|
-
const createIssues = options
|
|
7917
|
-
const vote = options
|
|
7922
|
+
const maxResults = optNumber(options, "maxResults") ?? 10;
|
|
7923
|
+
const createIssues = optBoolean(options, "createIssues");
|
|
7924
|
+
const vote = optBoolean(options, "vote");
|
|
7918
7925
|
const result = await executeReview(
|
|
7919
7926
|
{ topic, maxResults, createIssues, vote },
|
|
7920
7927
|
(t, max) => queryDiscoverSources(t, "all", max)
|
|
@@ -7922,10 +7929,89 @@ async function handleReviewCommand(args, options) {
|
|
|
7922
7929
|
return formatReviewResults(result);
|
|
7923
7930
|
}
|
|
7924
7931
|
async function handlePrioritizeCommand(args, options) {
|
|
7925
|
-
const topic = args[0] ?? options
|
|
7926
|
-
const vote = options
|
|
7932
|
+
const topic = args[0] ?? optString(options, "topic");
|
|
7933
|
+
const vote = optBoolean(options, "vote");
|
|
7927
7934
|
return executePrioritize({ topic, vote });
|
|
7928
7935
|
}
|
|
7936
|
+
async function handleSynthesizeCommand(args, options) {
|
|
7937
|
+
const topic = args[0] ?? optString(options, "topic");
|
|
7938
|
+
const result = await synthesizeResearch(topic);
|
|
7939
|
+
if (!result.ok) {
|
|
7940
|
+
return `Error: ${result.error.message}`;
|
|
7941
|
+
}
|
|
7942
|
+
return formatSynthesisResult(result.value);
|
|
7943
|
+
}
|
|
7944
|
+
function formatSynthesisResult(synthesis) {
|
|
7945
|
+
const lines = [
|
|
7946
|
+
`Research Synthesis: ${String(synthesis.totalPapers)} papers across ${String(synthesis.topicCount)} topics`,
|
|
7947
|
+
""
|
|
7948
|
+
];
|
|
7949
|
+
for (const cluster of synthesis.clusters) {
|
|
7950
|
+
formatCluster(cluster, lines);
|
|
7951
|
+
}
|
|
7952
|
+
if (synthesis.crossCuttingThemes.length > 0) {
|
|
7953
|
+
lines.push("## Cross-Cutting Themes");
|
|
7954
|
+
for (const theme of synthesis.crossCuttingThemes) {
|
|
7955
|
+
lines.push(` - ${theme}`);
|
|
7956
|
+
}
|
|
7957
|
+
lines.push("");
|
|
7958
|
+
}
|
|
7959
|
+
formatAlignmentSummary(synthesis.alignmentSummary, lines);
|
|
7960
|
+
formatFeatureGates(synthesis.featureGates, lines);
|
|
7961
|
+
return lines.join("\n");
|
|
7962
|
+
}
|
|
7963
|
+
function formatCluster(cluster, lines) {
|
|
7964
|
+
lines.push(`## ${cluster.topic} (${String(cluster.paperCount)} papers)`);
|
|
7965
|
+
lines.push(`Papers: ${cluster.papers.join(", ")}`);
|
|
7966
|
+
if (cluster.commonThemes.length > 0) lines.push(`Themes: ${cluster.commonThemes.join(", ")}`);
|
|
7967
|
+
if (cluster.keyInsights.length > 0) {
|
|
7968
|
+
lines.push("Key insights:");
|
|
7969
|
+
for (const insight of cluster.keyInsights.slice(0, 5)) lines.push(` - ${insight}`);
|
|
7970
|
+
}
|
|
7971
|
+
if (cluster.implementationOpportunities.length > 0) {
|
|
7972
|
+
lines.push(`Opportunities: ${cluster.implementationOpportunities.join(", ")}`);
|
|
7973
|
+
}
|
|
7974
|
+
if (cluster.gaps.length > 0) lines.push(`Gaps: ${cluster.gaps.join("; ")}`);
|
|
7975
|
+
const partial = cluster.alignedTechniques.filter((a) => a.status === "partial");
|
|
7976
|
+
if (partial.length > 0) {
|
|
7977
|
+
lines.push("Improvement opportunities:");
|
|
7978
|
+
for (const a of partial.slice(0, 3)) {
|
|
7979
|
+
const hint = a.improvementHint !== void 0 ? ` \u2014 ${a.improvementHint}` : "";
|
|
7980
|
+
lines.push(` - ${a.technique} (${a.canonicalPath ?? "unknown"})${hint}`);
|
|
7981
|
+
}
|
|
7982
|
+
}
|
|
7983
|
+
lines.push("");
|
|
7984
|
+
}
|
|
7985
|
+
function formatFeatureGates(gates, lines) {
|
|
7986
|
+
if (gates.length === 0) return;
|
|
7987
|
+
const linked = gates.filter((g) => g.linkedTechniqueCount > 0);
|
|
7988
|
+
const unlinked = gates.filter((g) => g.linkedTechniqueCount === 0);
|
|
7989
|
+
lines.push("");
|
|
7990
|
+
lines.push(
|
|
7991
|
+
`## Feature Gates (${String(gates.length)} total, ${String(linked.length)} research-linked)`
|
|
7992
|
+
);
|
|
7993
|
+
for (const g of linked) {
|
|
7994
|
+
lines.push(
|
|
7995
|
+
` ${g.envVar}=${g.defaultValue} \u2014 ${g.description} [${String(g.linkedTechniqueCount)} techniques]`
|
|
7996
|
+
);
|
|
7997
|
+
}
|
|
7998
|
+
if (unlinked.length > 0) {
|
|
7999
|
+
lines.push(
|
|
8000
|
+
` + ${String(unlinked.length)} infrastructure gates (auth, logging, rate limiting, etc.)`
|
|
8001
|
+
);
|
|
8002
|
+
}
|
|
8003
|
+
}
|
|
8004
|
+
function formatAlignmentSummary(summary, lines) {
|
|
8005
|
+
if (summary.total === 0) return;
|
|
8006
|
+
lines.push("## Alignment Summary");
|
|
8007
|
+
lines.push(
|
|
8008
|
+
`Implemented: ${String(summary.implemented)} | Partial: ${String(summary.partial)} | Not started: ${String(summary.notStarted)} | Total: ${String(summary.total)}`
|
|
8009
|
+
);
|
|
8010
|
+
if (summary.topOpportunities.length > 0) {
|
|
8011
|
+
lines.push("Top improvement opportunities:");
|
|
8012
|
+
for (const opp of summary.topOpportunities.slice(0, 5)) lines.push(` - ${opp}`);
|
|
8013
|
+
}
|
|
8014
|
+
}
|
|
7929
8015
|
var VALID_SUBCOMMANDS = [
|
|
7930
8016
|
"status",
|
|
7931
8017
|
"overlap",
|
|
@@ -7936,7 +8022,8 @@ var VALID_SUBCOMMANDS = [
|
|
|
7936
8022
|
"index",
|
|
7937
8023
|
"discover",
|
|
7938
8024
|
"review",
|
|
7939
|
-
"prioritize"
|
|
8025
|
+
"prioritize",
|
|
8026
|
+
"synthesize"
|
|
7940
8027
|
];
|
|
7941
8028
|
function isValidResearchSubcommand(value) {
|
|
7942
8029
|
return value !== void 0 && VALID_SUBCOMMANDS.includes(value);
|
|
@@ -7956,7 +8043,8 @@ var SUBCOMMAND_HANDLERS = {
|
|
|
7956
8043
|
index: (args) => handleIndexCommand(args),
|
|
7957
8044
|
discover: handleDiscoverCommand,
|
|
7958
8045
|
review: handleReviewCommand,
|
|
7959
|
-
prioritize: handlePrioritizeCommand
|
|
8046
|
+
prioritize: handlePrioritizeCommand,
|
|
8047
|
+
synthesize: handleSynthesizeCommand
|
|
7960
8048
|
};
|
|
7961
8049
|
async function researchCommand(subcommand, args, options) {
|
|
7962
8050
|
const handler = SUBCOMMAND_HANDLERS[subcommand];
|
|
@@ -9030,6 +9118,16 @@ function extractToolsFromFile(sourceFile, relativePath) {
|
|
|
9030
9118
|
}
|
|
9031
9119
|
return tools;
|
|
9032
9120
|
}
|
|
9121
|
+
function resolvePropertyValue(prop, sourceFile) {
|
|
9122
|
+
const propAssign = prop.asKind(SyntaxKind2.PropertyAssignment);
|
|
9123
|
+
if (propAssign !== void 0) return propAssign.getInitializer();
|
|
9124
|
+
const shorthand = prop.asKind(SyntaxKind2.ShorthandPropertyAssignment);
|
|
9125
|
+
if (shorthand !== void 0 && sourceFile !== void 0) {
|
|
9126
|
+
const varDecl = sourceFile.getVariableDeclaration(shorthand.getName());
|
|
9127
|
+
return varDecl?.getInitializer();
|
|
9128
|
+
}
|
|
9129
|
+
return void 0;
|
|
9130
|
+
}
|
|
9033
9131
|
function extractToolMeta(callText, args, _sourceFile) {
|
|
9034
9132
|
let description = "";
|
|
9035
9133
|
let schemaArg;
|
|
@@ -9040,14 +9138,12 @@ function extractToolMeta(callText, args, _sourceFile) {
|
|
|
9040
9138
|
if (configObj !== void 0) {
|
|
9041
9139
|
const descProp = configObj.getProperty("description");
|
|
9042
9140
|
if (descProp !== void 0) {
|
|
9043
|
-
const
|
|
9044
|
-
const init = propAssign?.getInitializer();
|
|
9141
|
+
const init = resolvePropertyValue(descProp, _sourceFile);
|
|
9045
9142
|
description = init?.getText().replace(/^['"]|['"]$/g, "") ?? "";
|
|
9046
9143
|
}
|
|
9047
9144
|
const schemaProp = configObj.getProperty("inputSchema");
|
|
9048
9145
|
if (schemaProp !== void 0) {
|
|
9049
|
-
|
|
9050
|
-
schemaArg = propAssign?.getInitializer();
|
|
9146
|
+
schemaArg = resolvePropertyValue(schemaProp, _sourceFile);
|
|
9051
9147
|
}
|
|
9052
9148
|
}
|
|
9053
9149
|
}
|
|
@@ -9514,8 +9610,9 @@ function getLinkType(url) {
|
|
|
9514
9610
|
}
|
|
9515
9611
|
return "internal";
|
|
9516
9612
|
}
|
|
9613
|
+
var DANGEROUS_SCHEME_REGEX = /^[\s\x00-\x1f\x7f]*(mailto|javascript|data|file|ftp)[\s\x00-\x1f\x7f]*:/i;
|
|
9517
9614
|
function shouldSkipUrl(url) {
|
|
9518
|
-
return
|
|
9615
|
+
return DANGEROUS_SCHEME_REGEX.test(url);
|
|
9519
9616
|
}
|
|
9520
9617
|
function buildReferenceMap(content) {
|
|
9521
9618
|
const references = /* @__PURE__ */ new Map();
|
|
@@ -9787,7 +9884,8 @@ async function getActualModules(srcPath) {
|
|
|
9787
9884
|
try {
|
|
9788
9885
|
const entries = await fs12.readdir(srcPath, { withFileTypes: true });
|
|
9789
9886
|
return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && !e.name.startsWith("__")).map((e) => e.name);
|
|
9790
|
-
} catch {
|
|
9887
|
+
} catch (error) {
|
|
9888
|
+
logger9.debug("Failed to read source modules", { srcPath, error: getErrorMessage(error) });
|
|
9791
9889
|
return [];
|
|
9792
9890
|
}
|
|
9793
9891
|
}
|
|
@@ -10249,6 +10347,8 @@ async function verifyCommand(options) {
|
|
|
10249
10347
|
}
|
|
10250
10348
|
|
|
10251
10349
|
// src/cli/swe-bench-command.ts
|
|
10350
|
+
import * as os2 from "os";
|
|
10351
|
+
import * as path19 from "path";
|
|
10252
10352
|
function runInfo(options) {
|
|
10253
10353
|
console.log(`
|
|
10254
10354
|
SWE-bench Dataset: ${options.variant}`);
|
|
@@ -10299,7 +10399,9 @@ function buildConfig(options) {
|
|
|
10299
10399
|
...DEFAULT_SWE_BENCH_CONFIG,
|
|
10300
10400
|
variant: options.variant,
|
|
10301
10401
|
output_path: options.output,
|
|
10302
|
-
resume: options.resume
|
|
10402
|
+
resume: options.resume,
|
|
10403
|
+
concurrency: options.concurrency,
|
|
10404
|
+
memory_dir: "/tmp/swe-bench-memory"
|
|
10303
10405
|
};
|
|
10304
10406
|
return options.limit !== void 0 ? { ...base, limit: options.limit } : base;
|
|
10305
10407
|
}
|
|
@@ -10332,7 +10434,10 @@ async function runBenchmark(options) {
|
|
|
10332
10434
|
console.log(`
|
|
10333
10435
|
SWE-bench Run: ${options.variant}`);
|
|
10334
10436
|
console.log("=".repeat(40));
|
|
10335
|
-
const executorResult = await createExecutor(
|
|
10437
|
+
const executorResult = await createExecutor({
|
|
10438
|
+
verbose: options.verbose,
|
|
10439
|
+
mcpEnabled: options.mcp
|
|
10440
|
+
});
|
|
10336
10441
|
if (!executorResult.ok) {
|
|
10337
10442
|
console.error(`
|
|
10338
10443
|
Error: ${executorResult.error.message}`);
|
|
@@ -10355,38 +10460,102 @@ Error: ${executorResult.error.message}`);
|
|
|
10355
10460
|
});
|
|
10356
10461
|
return { success: result.success, message: result.message, details: { ...result } };
|
|
10357
10462
|
}
|
|
10358
|
-
|
|
10359
|
-
|
|
10360
|
-
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
|
|
10364
|
-
|
|
10365
|
-
|
|
10463
|
+
function isValidRunId(runId) {
|
|
10464
|
+
return /^[a-zA-Z0-9_-]{1,64}$/.test(runId);
|
|
10465
|
+
}
|
|
10466
|
+
function isValidOutputDir(dir) {
|
|
10467
|
+
const resolved = path19.resolve(dir);
|
|
10468
|
+
return !resolved.includes("..") && resolved === path19.normalize(resolved);
|
|
10469
|
+
}
|
|
10470
|
+
function formatProgress(progress) {
|
|
10471
|
+
const pct = progress.totalCount > 0 ? Math.round(progress.completedCount / progress.totalCount * 100) : 0;
|
|
10472
|
+
const base = `[${String(progress.completedCount)}/${String(progress.totalCount)}] ${String(pct)}%`;
|
|
10473
|
+
if (progress.currentInstanceId !== void 0) {
|
|
10474
|
+
return `${base} - ${progress.currentInstanceId}`;
|
|
10475
|
+
}
|
|
10476
|
+
return base;
|
|
10477
|
+
}
|
|
10478
|
+
function buildHarnessConfig(options) {
|
|
10479
|
+
const predictionsPath = options.predictions ?? options.output;
|
|
10480
|
+
const runId = options.runId ?? `eval-${String(Date.now())}`;
|
|
10481
|
+
return {
|
|
10482
|
+
predictionsPath: path19.resolve(predictionsPath),
|
|
10483
|
+
datasetName: options.variant,
|
|
10484
|
+
maxWorkers: options.maxWorkers,
|
|
10485
|
+
runId,
|
|
10486
|
+
timeoutSeconds: 1800,
|
|
10487
|
+
outputDir: path19.resolve(options.outputDir),
|
|
10488
|
+
useDocker: true,
|
|
10489
|
+
cacheLevel: options.cacheLevel
|
|
10490
|
+
};
|
|
10491
|
+
}
|
|
10492
|
+
function validateEvaluateInputs(options) {
|
|
10493
|
+
if (options.runId !== void 0 && !isValidRunId(options.runId)) {
|
|
10494
|
+
return "Invalid run-id: alphanumeric, hyphens, underscores only";
|
|
10495
|
+
}
|
|
10496
|
+
if (!isValidOutputDir(options.outputDir)) {
|
|
10497
|
+
return "Invalid output-dir: path traversal detected";
|
|
10498
|
+
}
|
|
10499
|
+
return null;
|
|
10500
|
+
}
|
|
10501
|
+
function displayEvaluateResults(result, verbose) {
|
|
10502
|
+
console.log("\n");
|
|
10503
|
+
console.log(`Resolved: ${String(result.resolvedInstances)}/${String(result.totalInstances)}`);
|
|
10504
|
+
console.log(`Resolution rate: ${(result.resolutionRate * 100).toFixed(1)}%`);
|
|
10505
|
+
if (result.logPath !== void 0) console.log(`Logs: ${result.logPath}`);
|
|
10506
|
+
if (verbose && result.instanceResults.length > 0) {
|
|
10507
|
+
console.log("\nPer-instance results:");
|
|
10508
|
+
for (const inst of result.instanceResults) {
|
|
10509
|
+
console.log(` [${inst.resolved ? "PASS" : "FAIL"}] ${inst.instanceId}`);
|
|
10510
|
+
}
|
|
10366
10511
|
}
|
|
10367
10512
|
}
|
|
10368
10513
|
async function runEvaluate(options) {
|
|
10369
10514
|
console.log(`
|
|
10370
10515
|
SWE-bench Evaluate`);
|
|
10371
10516
|
console.log("=".repeat(40));
|
|
10372
|
-
const
|
|
10517
|
+
const predictionsPath = options.predictions ?? options.output;
|
|
10518
|
+
const idsResult = await getCompletedInstanceIds(predictionsPath);
|
|
10373
10519
|
if (!idsResult.ok) {
|
|
10374
10520
|
console.log('No predictions file. Run "nexus-agents swe-bench run" first.');
|
|
10375
10521
|
return { success: false, message: "No predictions file" };
|
|
10376
10522
|
}
|
|
10377
10523
|
const count = idsResult.value.size;
|
|
10378
10524
|
if (count === 0) return { success: false, message: "No predictions" };
|
|
10379
|
-
|
|
10380
|
-
|
|
10381
|
-
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10525
|
+
const inputError = validateEvaluateInputs(options);
|
|
10526
|
+
if (inputError !== null) return { success: false, message: inputError };
|
|
10527
|
+
console.log(`Predictions: ${String(count)} instances`);
|
|
10528
|
+
console.log(`Cache level: ${options.cacheLevel}`);
|
|
10529
|
+
console.log(`Max workers: ${String(options.maxWorkers)}`);
|
|
10530
|
+
const executor = createHarnessExecutor();
|
|
10531
|
+
const validation = await executor.validate();
|
|
10532
|
+
if (!validation.ready) {
|
|
10533
|
+
console.error("\nEnvironment not ready:");
|
|
10534
|
+
for (const err2 of validation.errors) console.error(` - ${err2}`);
|
|
10535
|
+
return { success: false, message: validation.errors.join("; ") };
|
|
10536
|
+
}
|
|
10537
|
+
console.log(
|
|
10538
|
+
`
|
|
10539
|
+
Environment OK (Python ${validation.pythonVersion ?? "?"}, Docker ${validation.dockerVersion ?? "?"})`
|
|
10540
|
+
);
|
|
10541
|
+
const config = buildHarnessConfig(options);
|
|
10542
|
+
console.log(`
|
|
10543
|
+
Running evaluation (run_id: ${config.runId})...`);
|
|
10544
|
+
const result = await executor.execute(config, (progress) => {
|
|
10545
|
+
if (progress.state === "running") process.stdout.write(`\r ${formatProgress(progress)}`);
|
|
10546
|
+
});
|
|
10547
|
+
displayEvaluateResults(result, options.verbose);
|
|
10548
|
+
const rateStr = (result.resolutionRate * 100).toFixed(1);
|
|
10549
|
+
return {
|
|
10550
|
+
success: true,
|
|
10551
|
+
message: `${String(result.resolvedInstances)}/${String(result.totalInstances)} resolved (${rateStr}%)`,
|
|
10552
|
+
details: {
|
|
10553
|
+
resolved: result.resolvedInstances,
|
|
10554
|
+
total: result.totalInstances,
|
|
10555
|
+
resolutionRate: result.resolutionRate,
|
|
10556
|
+
runId: result.runId
|
|
10557
|
+
}
|
|
10558
|
+
};
|
|
10390
10559
|
}
|
|
10391
10560
|
function parseSubcommand(arg) {
|
|
10392
10561
|
if (arg === "status") return "status";
|
|
@@ -10399,13 +10568,53 @@ function parseVariant(arg) {
|
|
|
10399
10568
|
if (v === "lite" || v === "verified" || v === "full") return v;
|
|
10400
10569
|
return "lite";
|
|
10401
10570
|
}
|
|
10571
|
+
var MAX_WORKERS_CAP = Math.min(Math.floor(os2.cpus().length * 0.75), 24);
|
|
10572
|
+
var VALID_CACHE_LEVELS = /* @__PURE__ */ new Set(["none", "base", "env", "instance"]);
|
|
10573
|
+
var BOOLEAN_FLAGS = {
|
|
10574
|
+
"--resume": "resume",
|
|
10575
|
+
"--verbose": "verbose",
|
|
10576
|
+
"-v": "verbose",
|
|
10577
|
+
"--mcp": "mcp"
|
|
10578
|
+
};
|
|
10579
|
+
function parseCacheLevel(value) {
|
|
10580
|
+
const level = value;
|
|
10581
|
+
return VALID_CACHE_LEVELS.has(level) ? level : "env";
|
|
10582
|
+
}
|
|
10583
|
+
function parseMaxWorkers(value) {
|
|
10584
|
+
const parsed = parseInt(value, 10);
|
|
10585
|
+
if (Number.isNaN(parsed) || parsed < 1) return 4;
|
|
10586
|
+
return Math.min(parsed, MAX_WORKERS_CAP);
|
|
10587
|
+
}
|
|
10588
|
+
var STRING_FLAGS = [
|
|
10589
|
+
["--output=", "output", (v) => v],
|
|
10590
|
+
["--predictions=", "predictions", (v) => v],
|
|
10591
|
+
["--run-id=", "runId", (v) => v],
|
|
10592
|
+
["--output-dir=", "outputDir", (v) => v],
|
|
10593
|
+
["--limit=", "limit", (v) => parseInt(v, 10)],
|
|
10594
|
+
["--concurrency=", "concurrency", (v) => Math.max(1, parseInt(v, 10) || 1)],
|
|
10595
|
+
["--cache-level=", "cacheLevel", parseCacheLevel],
|
|
10596
|
+
["--max-workers=", "maxWorkers", parseMaxWorkers]
|
|
10597
|
+
];
|
|
10402
10598
|
function parseArg(arg, state) {
|
|
10403
|
-
|
|
10404
|
-
|
|
10405
|
-
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10599
|
+
const boolKey = BOOLEAN_FLAGS[arg];
|
|
10600
|
+
if (boolKey !== void 0) {
|
|
10601
|
+
state[boolKey] = true;
|
|
10602
|
+
return;
|
|
10603
|
+
}
|
|
10604
|
+
if (arg.startsWith("--variant=")) {
|
|
10605
|
+
state.variant = parseVariant(arg);
|
|
10606
|
+
return;
|
|
10607
|
+
}
|
|
10608
|
+
if (arg.startsWith("--instance=")) {
|
|
10609
|
+
state.instances.push(arg.slice("--instance=".length));
|
|
10610
|
+
return;
|
|
10611
|
+
}
|
|
10612
|
+
for (const [prefix, key, transform] of STRING_FLAGS) {
|
|
10613
|
+
if (arg.startsWith(prefix)) {
|
|
10614
|
+
state[key] = transform(arg.slice(prefix.length));
|
|
10615
|
+
return;
|
|
10616
|
+
}
|
|
10617
|
+
}
|
|
10409
10618
|
}
|
|
10410
10619
|
function parseSweBenchArgs(args) {
|
|
10411
10620
|
const subcommand = parseSubcommand(args[0]);
|
|
@@ -10415,7 +10624,14 @@ function parseSweBenchArgs(args) {
|
|
|
10415
10624
|
output: "predictions.jsonl",
|
|
10416
10625
|
resume: false,
|
|
10417
10626
|
verbose: false,
|
|
10418
|
-
|
|
10627
|
+
concurrency: 1,
|
|
10628
|
+
instances: [],
|
|
10629
|
+
mcp: false,
|
|
10630
|
+
predictions: void 0,
|
|
10631
|
+
cacheLevel: "env",
|
|
10632
|
+
maxWorkers: 4,
|
|
10633
|
+
runId: void 0,
|
|
10634
|
+
outputDir: "./logs/run_evaluation"
|
|
10419
10635
|
};
|
|
10420
10636
|
for (const arg of args.slice(1)) parseArg(arg, state);
|
|
10421
10637
|
const base = {
|
|
@@ -10424,9 +10640,17 @@ function parseSweBenchArgs(args) {
|
|
|
10424
10640
|
output: state.output,
|
|
10425
10641
|
resume: state.resume,
|
|
10426
10642
|
verbose: state.verbose,
|
|
10427
|
-
|
|
10643
|
+
concurrency: state.concurrency,
|
|
10644
|
+
instances: state.instances,
|
|
10645
|
+
mcp: state.mcp,
|
|
10646
|
+
cacheLevel: state.cacheLevel,
|
|
10647
|
+
maxWorkers: state.maxWorkers,
|
|
10648
|
+
outputDir: state.outputDir,
|
|
10649
|
+
...state.limit !== void 0 ? { limit: state.limit } : {},
|
|
10650
|
+
...state.predictions !== void 0 ? { predictions: state.predictions } : {},
|
|
10651
|
+
...state.runId !== void 0 ? { runId: state.runId } : {}
|
|
10428
10652
|
};
|
|
10429
|
-
return
|
|
10653
|
+
return base;
|
|
10430
10654
|
}
|
|
10431
10655
|
function printSweBenchHelp() {
|
|
10432
10656
|
console.log(`
|
|
@@ -10444,7 +10668,16 @@ Options:
|
|
|
10444
10668
|
--output=<path> Output predictions file (default: predictions.jsonl)
|
|
10445
10669
|
--resume Skip already completed instances
|
|
10446
10670
|
--instance=<id> Run specific instance (can be repeated)
|
|
10671
|
+
--concurrency=<n> Parallel workers (default: 1, sequential)
|
|
10672
|
+
--mcp Enable MCP tools (memory, research) in child sessions
|
|
10447
10673
|
--verbose, -v Enable verbose output
|
|
10674
|
+
|
|
10675
|
+
Evaluate options:
|
|
10676
|
+
--predictions=<path> Predictions file (default: --output value)
|
|
10677
|
+
--cache-level=<level> Docker cache: none|base|env|instance (default: env)
|
|
10678
|
+
--max-workers=<n> Parallel Docker workers (default: 4, max: ${String(MAX_WORKERS_CAP)})
|
|
10679
|
+
--run-id=<id> Custom run identifier
|
|
10680
|
+
--output-dir=<path> Harness log directory (default: ./logs/run_evaluation)
|
|
10448
10681
|
`);
|
|
10449
10682
|
}
|
|
10450
10683
|
async function sweBenchCommand(args) {
|
|
@@ -10834,7 +11067,7 @@ function isValidConfigAction(value) {
|
|
|
10834
11067
|
|
|
10835
11068
|
// src/cli/config-command-helpers.ts
|
|
10836
11069
|
import * as fs13 from "fs/promises";
|
|
10837
|
-
import * as
|
|
11070
|
+
import * as path20 from "path";
|
|
10838
11071
|
import { existsSync as existsSync10 } from "fs";
|
|
10839
11072
|
|
|
10840
11073
|
// src/cli/config-command-formatting.ts
|
|
@@ -11102,10 +11335,10 @@ function parseValueFromString(stringValue, defaultValue) {
|
|
|
11102
11335
|
}
|
|
11103
11336
|
function resolveFilePath(filePath, allowedBase) {
|
|
11104
11337
|
const base = allowedBase ?? process.cwd();
|
|
11105
|
-
const resolved =
|
|
11106
|
-
const normalizedResolved =
|
|
11107
|
-
const normalizedBase =
|
|
11108
|
-
const isWithinBase = normalizedResolved === normalizedBase || normalizedResolved.startsWith(normalizedBase +
|
|
11338
|
+
const resolved = path20.isAbsolute(filePath) ? filePath : path20.resolve(base, filePath);
|
|
11339
|
+
const normalizedResolved = path20.normalize(resolved);
|
|
11340
|
+
const normalizedBase = path20.normalize(base);
|
|
11341
|
+
const isWithinBase = normalizedResolved === normalizedBase || normalizedResolved.startsWith(normalizedBase + path20.sep);
|
|
11109
11342
|
if (!isWithinBase) {
|
|
11110
11343
|
throw new ConfigCommandError(
|
|
11111
11344
|
"PATH_TRAVERSAL",
|
|
@@ -11116,7 +11349,7 @@ function resolveFilePath(filePath, allowedBase) {
|
|
|
11116
11349
|
}
|
|
11117
11350
|
function getDefaultExportPath(format) {
|
|
11118
11351
|
const extension = format === "json" ? "json" : "yaml";
|
|
11119
|
-
return
|
|
11352
|
+
return path20.resolve(process.cwd(), `nexus-config.${extension}`);
|
|
11120
11353
|
}
|
|
11121
11354
|
|
|
11122
11355
|
// src/cli/config-command-handlers.ts
|
|
@@ -11531,20 +11764,20 @@ var SessionEndInputSchema = HookInputBaseSchema.extend({
|
|
|
11531
11764
|
var PreToolUseInputSchema = HookInputBaseSchema.extend({
|
|
11532
11765
|
hook_event_name: z6.literal("PreToolUse"),
|
|
11533
11766
|
tool_name: z6.string(),
|
|
11534
|
-
tool_input: z6.record(z6.unknown()),
|
|
11767
|
+
tool_input: z6.record(z6.string(), z6.unknown()),
|
|
11535
11768
|
tool_use_id: z6.string()
|
|
11536
11769
|
});
|
|
11537
11770
|
var PostToolUseInputSchema = HookInputBaseSchema.extend({
|
|
11538
11771
|
hook_event_name: z6.literal("PostToolUse"),
|
|
11539
11772
|
tool_name: z6.string(),
|
|
11540
|
-
tool_input: z6.record(z6.unknown()),
|
|
11541
|
-
tool_response: z6.record(z6.unknown()),
|
|
11773
|
+
tool_input: z6.record(z6.string(), z6.unknown()),
|
|
11774
|
+
tool_response: z6.record(z6.string(), z6.unknown()),
|
|
11542
11775
|
tool_use_id: z6.string()
|
|
11543
11776
|
});
|
|
11544
11777
|
var PostToolUseFailureInputSchema = HookInputBaseSchema.extend({
|
|
11545
11778
|
hook_event_name: z6.literal("PostToolUseFailure"),
|
|
11546
11779
|
tool_name: z6.string(),
|
|
11547
|
-
tool_input: z6.record(z6.unknown()),
|
|
11780
|
+
tool_input: z6.record(z6.string(), z6.unknown()),
|
|
11548
11781
|
tool_use_id: z6.string(),
|
|
11549
11782
|
error: z6.string().optional()
|
|
11550
11783
|
});
|
|
@@ -11592,7 +11825,7 @@ var SubagentStartInputSchema = HookInputBaseSchema.extend({
|
|
|
11592
11825
|
var PermissionRequestInputSchema = HookInputBaseSchema.extend({
|
|
11593
11826
|
hook_event_name: z6.literal("PermissionRequest"),
|
|
11594
11827
|
tool_name: z6.string(),
|
|
11595
|
-
tool_input: z6.record(z6.unknown()),
|
|
11828
|
+
tool_input: z6.record(z6.string(), z6.unknown()),
|
|
11596
11829
|
tool_use_id: z6.string()
|
|
11597
11830
|
});
|
|
11598
11831
|
var HookInputSchema = z6.discriminatedUnion("hook_event_name", [
|
|
@@ -11623,7 +11856,7 @@ var PreToolUseOutputSchema = HookOutputBaseSchema.extend({
|
|
|
11623
11856
|
hookEventName: z6.literal("PreToolUse"),
|
|
11624
11857
|
permissionDecision: PermissionDecision.optional(),
|
|
11625
11858
|
permissionDecisionReason: z6.string().optional(),
|
|
11626
|
-
updatedInput: z6.record(z6.unknown()).optional(),
|
|
11859
|
+
updatedInput: z6.record(z6.string(), z6.unknown()).optional(),
|
|
11627
11860
|
additionalContext: z6.string().optional()
|
|
11628
11861
|
}).optional()
|
|
11629
11862
|
});
|
|
@@ -11658,7 +11891,7 @@ var PermissionRequestOutputSchema = HookOutputBaseSchema.extend({
|
|
|
11658
11891
|
hookEventName: z6.literal("PermissionRequest"),
|
|
11659
11892
|
decision: z6.object({
|
|
11660
11893
|
behavior: z6.enum(["allow", "deny"]),
|
|
11661
|
-
updatedInput: z6.record(z6.unknown()).optional(),
|
|
11894
|
+
updatedInput: z6.record(z6.string(), z6.unknown()).optional(),
|
|
11662
11895
|
message: z6.string().optional(),
|
|
11663
11896
|
interrupt: z6.boolean().optional()
|
|
11664
11897
|
})
|
|
@@ -11746,34 +11979,35 @@ function writeResultAndExit(result) {
|
|
|
11746
11979
|
|
|
11747
11980
|
// src/cli/hooks/hook-router.ts
|
|
11748
11981
|
async function readStdin() {
|
|
11749
|
-
return new Promise((
|
|
11982
|
+
return new Promise((resolve12, reject) => {
|
|
11750
11983
|
let data = "";
|
|
11751
11984
|
process.stdin.setEncoding("utf8");
|
|
11752
11985
|
process.stdin.on("readable", () => {
|
|
11753
11986
|
let chunk;
|
|
11754
11987
|
while ((chunk = process.stdin.read()) !== null) {
|
|
11988
|
+
if (typeof chunk !== "string") continue;
|
|
11755
11989
|
data += chunk;
|
|
11756
11990
|
}
|
|
11757
11991
|
});
|
|
11758
11992
|
process.stdin.on("end", () => {
|
|
11759
|
-
|
|
11993
|
+
resolve12(data);
|
|
11760
11994
|
});
|
|
11761
11995
|
process.stdin.on("error", (err2) => {
|
|
11762
11996
|
reject(err2);
|
|
11763
11997
|
});
|
|
11764
11998
|
if (process.stdin.isTTY) {
|
|
11765
|
-
|
|
11999
|
+
resolve12("");
|
|
11766
12000
|
}
|
|
11767
12001
|
});
|
|
11768
12002
|
}
|
|
11769
12003
|
async function readStdinWithTimeout(timeoutMs = 5e3) {
|
|
11770
|
-
return new Promise((
|
|
12004
|
+
return new Promise((resolve12, reject) => {
|
|
11771
12005
|
const timeout2 = setTimeout(() => {
|
|
11772
12006
|
reject(new Error(`Stdin read timeout after ${String(timeoutMs)}ms`));
|
|
11773
12007
|
}, timeoutMs);
|
|
11774
12008
|
readStdin().then((data) => {
|
|
11775
12009
|
clearTimeout(timeout2);
|
|
11776
|
-
|
|
12010
|
+
resolve12(data);
|
|
11777
12011
|
}).catch((err2) => {
|
|
11778
12012
|
clearTimeout(timeout2);
|
|
11779
12013
|
reject(err2 instanceof Error ? err2 : new Error(String(err2)));
|
|
@@ -11829,7 +12063,7 @@ async function processHook(handlers) {
|
|
|
11829
12063
|
return exitError(`Hook processing error: ${message}`);
|
|
11830
12064
|
}
|
|
11831
12065
|
}
|
|
11832
|
-
var
|
|
12066
|
+
var BOOLEAN_FLAGS2 = /* @__PURE__ */ new Map([
|
|
11833
12067
|
["--validate", "validate"],
|
|
11834
12068
|
["--load-context", "loadContext"],
|
|
11835
12069
|
["--track-metrics", "trackMetrics"],
|
|
@@ -11850,7 +12084,7 @@ function parseHookArgs(args) {
|
|
|
11850
12084
|
for (let i = 1; i < args.length; i++) {
|
|
11851
12085
|
const arg = args[i];
|
|
11852
12086
|
if (arg === void 0) continue;
|
|
11853
|
-
const booleanKey =
|
|
12087
|
+
const booleanKey = BOOLEAN_FLAGS2.get(arg);
|
|
11854
12088
|
if (booleanKey !== void 0) {
|
|
11855
12089
|
setBooleanOption(options, booleanKey);
|
|
11856
12090
|
continue;
|
|
@@ -13429,7 +13663,8 @@ function getLatestTag() {
|
|
|
13429
13663
|
try {
|
|
13430
13664
|
const result = execSync2("git describe --tags --abbrev=0", {
|
|
13431
13665
|
encoding: "utf-8",
|
|
13432
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
13666
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
13667
|
+
timeout: CLI_SUBPROCESS_TIMEOUTS.ghCommandMs
|
|
13433
13668
|
}).trim();
|
|
13434
13669
|
return result || void 0;
|
|
13435
13670
|
} catch {
|
|
@@ -13440,7 +13675,8 @@ function getCommitsBetween(from, to = "HEAD") {
|
|
|
13440
13675
|
try {
|
|
13441
13676
|
const result = execSync2(`git log ${from}..${to} --oneline --format="%h %s"`, {
|
|
13442
13677
|
encoding: "utf-8",
|
|
13443
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
13678
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
13679
|
+
timeout: CLI_SUBPROCESS_TIMEOUTS.ghCommandMs
|
|
13444
13680
|
}).trim();
|
|
13445
13681
|
return result ? result.split("\n").filter(Boolean) : [];
|
|
13446
13682
|
} catch {
|
|
@@ -13485,7 +13721,7 @@ function groupCommitsByCategory(commits) {
|
|
|
13485
13721
|
const categoryMap = /* @__PURE__ */ new Map();
|
|
13486
13722
|
for (const commit of commits) {
|
|
13487
13723
|
const category = mapTypeToCategory(commit.type);
|
|
13488
|
-
const existing = categoryMap.get(category)
|
|
13724
|
+
const existing = categoryMap.get(category) ?? [];
|
|
13489
13725
|
existing.push(commit);
|
|
13490
13726
|
categoryMap.set(category, existing);
|
|
13491
13727
|
}
|
|
@@ -13548,8 +13784,8 @@ function generateMarkdownFormat(version, categories) {
|
|
|
13548
13784
|
const lines = [];
|
|
13549
13785
|
lines.push(`# Release ${version}`);
|
|
13550
13786
|
lines.push("");
|
|
13551
|
-
const featCount = categories.find((c) => c.name === "Added")?.commits.length
|
|
13552
|
-
const fixCount = categories.find((c) => c.name === "Fixed")?.commits.length
|
|
13787
|
+
const featCount = categories.find((c) => c.name === "Added")?.commits.length ?? 0;
|
|
13788
|
+
const fixCount = categories.find((c) => c.name === "Fixed")?.commits.length ?? 0;
|
|
13553
13789
|
const totalCount = categories.reduce((sum, c) => sum + c.commits.length, 0);
|
|
13554
13790
|
lines.push("## Highlights");
|
|
13555
13791
|
lines.push("");
|
|
@@ -13695,7 +13931,8 @@ async function validateSecurity(options) {
|
|
|
13695
13931
|
try {
|
|
13696
13932
|
execSync3("npm audit --audit-level=high 2>/dev/null", {
|
|
13697
13933
|
encoding: "utf-8",
|
|
13698
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
13934
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
13935
|
+
timeout: CLI_SUBPROCESS_TIMEOUTS.ghCommandMs
|
|
13699
13936
|
});
|
|
13700
13937
|
} catch {
|
|
13701
13938
|
findings.push({
|
|
@@ -13718,7 +13955,11 @@ async function validateSecurity(options) {
|
|
|
13718
13955
|
try {
|
|
13719
13956
|
const result = execSync3(
|
|
13720
13957
|
'git diff HEAD~10..HEAD -- "*.ts" "*.js" | grep -iE "(api[_-]?key|secret|password|token)" | head -5',
|
|
13721
|
-
{
|
|
13958
|
+
{
|
|
13959
|
+
encoding: "utf-8",
|
|
13960
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
13961
|
+
timeout: CLI_SUBPROCESS_TIMEOUTS.ghCommandMs
|
|
13962
|
+
}
|
|
13722
13963
|
);
|
|
13723
13964
|
if (result.trim()) {
|
|
13724
13965
|
findings.push({
|
|
@@ -13745,10 +13986,11 @@ async function validateArchitecture2(options) {
|
|
|
13745
13986
|
try {
|
|
13746
13987
|
const result = execSync3("npx nexus-agents fitness-audit --format=json 2>/dev/null", {
|
|
13747
13988
|
encoding: "utf-8",
|
|
13748
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
13989
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
13990
|
+
timeout: CLI_SUBPROCESS_TIMEOUTS.releaseValidateMs
|
|
13749
13991
|
});
|
|
13750
13992
|
const audit = JSON.parse(result);
|
|
13751
|
-
const fitnessScore = audit
|
|
13993
|
+
const fitnessScore = typeof audit["score"] === "number" ? audit["score"] : 0;
|
|
13752
13994
|
if (fitnessScore < 90) {
|
|
13753
13995
|
findings.push({
|
|
13754
13996
|
severity: "error",
|
|
@@ -13765,13 +14007,14 @@ async function validateArchitecture2(options) {
|
|
|
13765
14007
|
description: "Fitness score meets release threshold."
|
|
13766
14008
|
});
|
|
13767
14009
|
}
|
|
13768
|
-
|
|
13769
|
-
|
|
14010
|
+
const auditFindings = audit["findings"];
|
|
14011
|
+
if (Array.isArray(auditFindings)) {
|
|
14012
|
+
for (const finding of auditFindings) {
|
|
13770
14013
|
findings.push({
|
|
13771
14014
|
severity: "info",
|
|
13772
14015
|
category: "architecture",
|
|
13773
|
-
title: finding
|
|
13774
|
-
description: finding
|
|
14016
|
+
title: typeof finding["message"] === "string" ? finding["message"] : "Fitness finding",
|
|
14017
|
+
description: typeof finding["suggestion"] === "string" ? finding["suggestion"] : ""
|
|
13775
14018
|
});
|
|
13776
14019
|
}
|
|
13777
14020
|
}
|
|
@@ -14080,7 +14323,7 @@ function getBlueskyConfig() {
|
|
|
14080
14323
|
}
|
|
14081
14324
|
async function loadAtproto() {
|
|
14082
14325
|
try {
|
|
14083
|
-
const mod = await import("./dist-
|
|
14326
|
+
const mod = await import("./dist-H5XNXVAV.js");
|
|
14084
14327
|
return { AtpAgent: mod.AtpAgent, RichText: mod.RichText };
|
|
14085
14328
|
} catch {
|
|
14086
14329
|
return void 0;
|
|
@@ -14146,9 +14389,9 @@ function generateBlogPost(options) {
|
|
|
14146
14389
|
return parseConventionalCommit(line.substring(0, spaceIndex), line.substring(spaceIndex + 1));
|
|
14147
14390
|
});
|
|
14148
14391
|
const categories = groupCommitsByCategory(parsedCommits);
|
|
14149
|
-
const featCount = categories.find((c) => c.name === "Added")?.commits.length
|
|
14150
|
-
const fixCount = categories.find((c) => c.name === "Fixed")?.commits.length
|
|
14151
|
-
const refactorCount = categories.find((c) => c.name === "Changed")?.commits.length
|
|
14392
|
+
const featCount = categories.find((c) => c.name === "Added")?.commits.length ?? 0;
|
|
14393
|
+
const fixCount = categories.find((c) => c.name === "Fixed")?.commits.length ?? 0;
|
|
14394
|
+
const refactorCount = categories.find((c) => c.name === "Changed")?.commits.length ?? 0;
|
|
14152
14395
|
const frontmatter = {
|
|
14153
14396
|
title: `nexus-agents v${options.version} Released: Multi-Agent Orchestration Improvements`,
|
|
14154
14397
|
date: today,
|
|
@@ -14413,7 +14656,7 @@ async function releaseAnnounceCommand(args) {
|
|
|
14413
14656
|
|
|
14414
14657
|
// src/cli/scaffold.ts
|
|
14415
14658
|
import * as fs15 from "fs";
|
|
14416
|
-
import * as
|
|
14659
|
+
import * as path21 from "path";
|
|
14417
14660
|
|
|
14418
14661
|
// src/cli/scaffold-templates.ts
|
|
14419
14662
|
function toolImportsAndSchema(name, pascal) {
|
|
@@ -14440,7 +14683,7 @@ import { createSecureHandler, type HandlerContext } from '../middleware/secure-h
|
|
|
14440
14683
|
*/
|
|
14441
14684
|
export const ${pascal}InputSchema = z.object({
|
|
14442
14685
|
input: z.string().min(1).describe('Primary input for ${name} operation'),
|
|
14443
|
-
options: z.record(z.unknown()).optional().describe('Additional options'),
|
|
14686
|
+
options: z.record(z.string(), z.unknown()).optional().describe('Additional options'),
|
|
14444
14687
|
});
|
|
14445
14688
|
|
|
14446
14689
|
export type ${pascal}Input = z.infer<typeof ${pascal}InputSchema>;
|
|
@@ -14749,8 +14992,8 @@ ${lines}`;
|
|
|
14749
14992
|
function writeFiles(files) {
|
|
14750
14993
|
const createdPaths = [];
|
|
14751
14994
|
for (const file of files) {
|
|
14752
|
-
const fullPath =
|
|
14753
|
-
const dir =
|
|
14995
|
+
const fullPath = path21.resolve(process.cwd(), file.path);
|
|
14996
|
+
const dir = path21.dirname(fullPath);
|
|
14754
14997
|
fs15.mkdirSync(dir, { recursive: true });
|
|
14755
14998
|
if (fs15.existsSync(fullPath)) {
|
|
14756
14999
|
return {
|
|
@@ -14865,7 +15108,7 @@ function getCliRole(cli, category) {
|
|
|
14865
15108
|
["devops", "gemini"],
|
|
14866
15109
|
["research", "claude"],
|
|
14867
15110
|
["documentation", "claude"],
|
|
14868
|
-
["exploration", "
|
|
15111
|
+
["exploration", "codex"]
|
|
14869
15112
|
]);
|
|
14870
15113
|
return cli === secondaryMap.get(category) ? "secondary" : "other";
|
|
14871
15114
|
}
|
|
@@ -14945,7 +15188,10 @@ function buildDetails(taskCount, counts, nonZero, score, passed) {
|
|
|
14945
15188
|
function runE2EEval(config, logger17) {
|
|
14946
15189
|
const log = logger17 ?? createLogger({ component: "e2e-eval" });
|
|
14947
15190
|
const taskCount = config?.taskCount ?? 50;
|
|
14948
|
-
if (config?.resetStore !== false)
|
|
15191
|
+
if (config?.resetStore !== false) {
|
|
15192
|
+
resetOutcomeStore();
|
|
15193
|
+
setOutcomeStore(new OutcomeStore());
|
|
15194
|
+
}
|
|
14949
15195
|
const counts = generateOutcomes(taskCount);
|
|
14950
15196
|
log.info("E2E eval: outcomes recorded", { taskCount });
|
|
14951
15197
|
const { bonuses, nonZeroCount } = checkAdaptiveBonuses();
|
|
@@ -15567,6 +15813,7 @@ COMMANDS:
|
|
|
15567
15813
|
visualize Generate Mermaid diagrams and ASCII dashboards (architecture, swarm, flow)
|
|
15568
15814
|
capabilities Show model capabilities matrix (modalities, tools, features)
|
|
15569
15815
|
status At-a-glance project health dashboard (fitness, adapters, version)
|
|
15816
|
+
health Swarm health metrics dashboard (utilization, routing accuracy, failures)
|
|
15570
15817
|
auth Manage MCP authentication tokens (init, show, rotate)
|
|
15571
15818
|
|
|
15572
15819
|
OPTIONS:
|
|
@@ -15887,6 +16134,8 @@ EXAMPLES:
|
|
|
15887
16134
|
nexus-agents capabilities list --format=json Output capabilities as JSON
|
|
15888
16135
|
nexus-agents status Show project health dashboard
|
|
15889
16136
|
nexus-agents status --format=json Output status as JSON
|
|
16137
|
+
nexus-agents health Show swarm health metrics
|
|
16138
|
+
nexus-agents health --format=json Output health metrics as JSON
|
|
15890
16139
|
nexus-agents auth init Generate initial auth token
|
|
15891
16140
|
nexus-agents auth show Check token status
|
|
15892
16141
|
nexus-agents auth rotate Rotate to new token
|
|
@@ -16033,6 +16282,33 @@ var PARSE_ARGS_CONFIG = {
|
|
|
16033
16282
|
type: "boolean",
|
|
16034
16283
|
default: false
|
|
16035
16284
|
},
|
|
16285
|
+
concurrency: {
|
|
16286
|
+
type: "string",
|
|
16287
|
+
default: "1"
|
|
16288
|
+
},
|
|
16289
|
+
mcp: {
|
|
16290
|
+
type: "boolean",
|
|
16291
|
+
default: false
|
|
16292
|
+
},
|
|
16293
|
+
// SWE-bench evaluate options
|
|
16294
|
+
predictions: {
|
|
16295
|
+
type: "string"
|
|
16296
|
+
},
|
|
16297
|
+
"cache-level": {
|
|
16298
|
+
type: "string",
|
|
16299
|
+
default: "env"
|
|
16300
|
+
},
|
|
16301
|
+
"max-workers": {
|
|
16302
|
+
type: "string",
|
|
16303
|
+
default: "4"
|
|
16304
|
+
},
|
|
16305
|
+
"run-id": {
|
|
16306
|
+
type: "string"
|
|
16307
|
+
},
|
|
16308
|
+
"output-dir": {
|
|
16309
|
+
type: "string",
|
|
16310
|
+
default: "./logs/run_evaluation"
|
|
16311
|
+
},
|
|
16036
16312
|
// Learning-metrics command options
|
|
16037
16313
|
period: {
|
|
16038
16314
|
type: "string",
|
|
@@ -16138,7 +16414,8 @@ function isValidCommand(value) {
|
|
|
16138
16414
|
"warm-up",
|
|
16139
16415
|
"e2e-eval",
|
|
16140
16416
|
"routing-ab",
|
|
16141
|
-
"memory-eval"
|
|
16417
|
+
"memory-eval",
|
|
16418
|
+
"health"
|
|
16142
16419
|
];
|
|
16143
16420
|
return validCommands.includes(value);
|
|
16144
16421
|
}
|
|
@@ -16453,6 +16730,10 @@ function registerResearchTools(ctx) {
|
|
|
16453
16730
|
...researchDeps,
|
|
16454
16731
|
rateLimiter: ctx.rateLimiterFactory.getForTool("research_catalog_review")
|
|
16455
16732
|
});
|
|
16733
|
+
registerResearchSynthesizeTool(ctx.server, {
|
|
16734
|
+
...researchDeps,
|
|
16735
|
+
rateLimiter: ctx.rateLimiterFactory.getForTool("research_synthesize")
|
|
16736
|
+
});
|
|
16456
16737
|
}
|
|
16457
16738
|
function registerMemoryTools(ctx) {
|
|
16458
16739
|
const memoryDeps = {
|
|
@@ -16736,7 +17017,7 @@ function logFinalEventBusStats(logger17) {
|
|
|
16736
17017
|
// src/cli-orchestrator.ts
|
|
16737
17018
|
import * as readline2 from "readline";
|
|
16738
17019
|
function runOrchestratorRepl(options, logger17) {
|
|
16739
|
-
return new Promise((
|
|
17020
|
+
return new Promise((resolve12) => {
|
|
16740
17021
|
const rl = readline2.createInterface({
|
|
16741
17022
|
input: process.stdin,
|
|
16742
17023
|
output: process.stdout,
|
|
@@ -16772,7 +17053,7 @@ function runOrchestratorRepl(options, logger17) {
|
|
|
16772
17053
|
});
|
|
16773
17054
|
rl.on("close", () => {
|
|
16774
17055
|
logger17.info("Orchestrator REPL closed");
|
|
16775
|
-
|
|
17056
|
+
resolve12();
|
|
16776
17057
|
});
|
|
16777
17058
|
});
|
|
16778
17059
|
}
|
|
@@ -17919,7 +18200,7 @@ function initializeFeedbackIntegration(options) {
|
|
|
17919
18200
|
|
|
17920
18201
|
// src/cli-server-rest.ts
|
|
17921
18202
|
import * as fs16 from "fs";
|
|
17922
|
-
import * as
|
|
18203
|
+
import * as path22 from "path";
|
|
17923
18204
|
import * as crypto3 from "crypto";
|
|
17924
18205
|
import { homedir as homedir3 } from "os";
|
|
17925
18206
|
var DEFAULT_REST_CONFIG = {
|
|
@@ -17955,12 +18236,12 @@ function extractRestConfig(_config) {
|
|
|
17955
18236
|
var AUTH_DIR = "auth";
|
|
17956
18237
|
var API_KEY_FILE = "rest-api-key";
|
|
17957
18238
|
function getAuthDir(baseDir) {
|
|
17958
|
-
const home = baseDir ??
|
|
17959
|
-
return
|
|
18239
|
+
const home = baseDir ?? path22.join(homedir3(), ".nexus-agents");
|
|
18240
|
+
return path22.join(home, AUTH_DIR);
|
|
17960
18241
|
}
|
|
17961
18242
|
function loadOrGenerateApiKey(logger17, baseDir) {
|
|
17962
18243
|
const authDir = getAuthDir(baseDir);
|
|
17963
|
-
const keyPath =
|
|
18244
|
+
const keyPath = path22.join(authDir, API_KEY_FILE);
|
|
17964
18245
|
if (fs16.existsSync(keyPath)) {
|
|
17965
18246
|
const key2 = fs16.readFileSync(keyPath, "utf-8").trim();
|
|
17966
18247
|
if (key2.length > 0) {
|
|
@@ -18611,31 +18892,32 @@ async function handleOrchestrateCommand(args) {
|
|
|
18611
18892
|
});
|
|
18612
18893
|
process.exit(exitCode === 0 ? EXIT_CODES.SUCCESS : EXIT_CODES.SERVER_START_FAILED);
|
|
18613
18894
|
}
|
|
18614
|
-
|
|
18615
|
-
const
|
|
18616
|
-
const
|
|
18617
|
-
|
|
18618
|
-
|
|
18619
|
-
|
|
18620
|
-
|
|
18621
|
-
|
|
18622
|
-
|
|
18623
|
-
|
|
18624
|
-
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
|
|
18629
|
-
|
|
18630
|
-
|
|
18631
|
-
subArgs.push("--verbose");
|
|
18632
|
-
}
|
|
18633
|
-
if (args.options.instance !== void 0) {
|
|
18634
|
-
for (const inst of args.options.instance) {
|
|
18635
|
-
subArgs.push(`--instance=${inst}`);
|
|
18636
|
-
}
|
|
18895
|
+
function buildSweBenchSubArgs(args) {
|
|
18896
|
+
const opts = args.options;
|
|
18897
|
+
const subArgs = [args.positionals[1] ?? "run"];
|
|
18898
|
+
const valueFlags = [
|
|
18899
|
+
["variant", "variant"],
|
|
18900
|
+
["limit", "limit"],
|
|
18901
|
+
["output", "output"],
|
|
18902
|
+
["concurrency", "concurrency"],
|
|
18903
|
+
["predictions", "predictions"],
|
|
18904
|
+
["cacheLevel", "cache-level"],
|
|
18905
|
+
["maxWorkers", "max-workers"],
|
|
18906
|
+
["runId", "run-id"],
|
|
18907
|
+
["outputDir", "output-dir"]
|
|
18908
|
+
];
|
|
18909
|
+
for (const [key, flag] of valueFlags) {
|
|
18910
|
+
const val = opts[key];
|
|
18911
|
+
if (val !== void 0) subArgs.push(`--${flag}=${String(val)}`);
|
|
18637
18912
|
}
|
|
18638
|
-
|
|
18913
|
+
if (opts.resume) subArgs.push("--resume");
|
|
18914
|
+
if (opts.verbose) subArgs.push("--verbose");
|
|
18915
|
+
if (opts.mcp === true) subArgs.push("--mcp");
|
|
18916
|
+
for (const inst of opts.instance ?? []) subArgs.push(`--instance=${inst}`);
|
|
18917
|
+
return subArgs;
|
|
18918
|
+
}
|
|
18919
|
+
async function handleSweBenchCommand(args) {
|
|
18920
|
+
const exitCode = await sweBenchCommand(buildSweBenchSubArgs(args));
|
|
18639
18921
|
process.exit(exitCode === 0 ? EXIT_CODES.SUCCESS : EXIT_CODES.SERVER_START_FAILED);
|
|
18640
18922
|
}
|
|
18641
18923
|
|
|
@@ -18827,7 +19109,7 @@ async function handleVerifyCommand(args) {
|
|
|
18827
19109
|
async function handleDoctorCommand(args) {
|
|
18828
19110
|
const exitCode = await doctorCommand({ fix: args.options.fix });
|
|
18829
19111
|
if (args.options.deep) {
|
|
18830
|
-
const { runDeepDiagnostics: runDeepDiagnostics2, formatDeepDiagnostics: formatDeepDiagnostics2 } = await import("./doctor-deep-
|
|
19112
|
+
const { runDeepDiagnostics: runDeepDiagnostics2, formatDeepDiagnostics: formatDeepDiagnostics2 } = await import("./doctor-deep-BDE2PHVX.js");
|
|
18831
19113
|
const diag = runDeepDiagnostics2();
|
|
18832
19114
|
process.stdout.write(formatDeepDiagnostics2(diag) + "\n");
|
|
18833
19115
|
}
|
|
@@ -19079,13 +19361,13 @@ function handleScaffoldCommand(args) {
|
|
|
19079
19361
|
|
|
19080
19362
|
// src/cli/visualize-summary.ts
|
|
19081
19363
|
import * as fs17 from "fs";
|
|
19082
|
-
import * as
|
|
19364
|
+
import * as path23 from "path";
|
|
19083
19365
|
import { fileURLToPath } from "url";
|
|
19084
19366
|
function findPackageRoot(startDir) {
|
|
19085
19367
|
let dir = startDir;
|
|
19086
19368
|
for (let i = 0; i < 5; i++) {
|
|
19087
|
-
if (fs17.existsSync(
|
|
19088
|
-
const parent =
|
|
19369
|
+
if (fs17.existsSync(path23.join(dir, "package.json"))) return dir;
|
|
19370
|
+
const parent = path23.dirname(dir);
|
|
19089
19371
|
if (parent === dir) break;
|
|
19090
19372
|
dir = parent;
|
|
19091
19373
|
}
|
|
@@ -19096,7 +19378,7 @@ function countFiles(dir, pattern) {
|
|
|
19096
19378
|
let count = 0;
|
|
19097
19379
|
for (const entry of fs17.readdirSync(dir, { withFileTypes: true })) {
|
|
19098
19380
|
if (entry.isDirectory() && entry.name !== "node_modules" && entry.name !== "dist") {
|
|
19099
|
-
count += countFiles(
|
|
19381
|
+
count += countFiles(path23.join(dir, entry.name), pattern);
|
|
19100
19382
|
} else if (entry.isFile() && pattern.test(entry.name)) {
|
|
19101
19383
|
count++;
|
|
19102
19384
|
}
|
|
@@ -19105,7 +19387,7 @@ function countFiles(dir, pattern) {
|
|
|
19105
19387
|
}
|
|
19106
19388
|
function readVersion(pkgRoot) {
|
|
19107
19389
|
try {
|
|
19108
|
-
const raw = fs17.readFileSync(
|
|
19390
|
+
const raw = fs17.readFileSync(path23.join(pkgRoot, "package.json"), "utf-8");
|
|
19109
19391
|
const pkg = JSON.parse(raw);
|
|
19110
19392
|
return pkg.version ?? "unknown";
|
|
19111
19393
|
} catch {
|
|
@@ -19126,13 +19408,13 @@ var LAYER_DIRS = [
|
|
|
19126
19408
|
];
|
|
19127
19409
|
function gatherSystemSummary() {
|
|
19128
19410
|
const thisFile = fileURLToPath(import.meta.url);
|
|
19129
|
-
const pkgRoot = findPackageRoot(
|
|
19130
|
-
const srcDir =
|
|
19411
|
+
const pkgRoot = findPackageRoot(path23.dirname(thisFile));
|
|
19412
|
+
const srcDir = path23.resolve(pkgRoot, "src");
|
|
19131
19413
|
const allTs = countFiles(srcDir, /\.ts$/);
|
|
19132
19414
|
const testTs = countFiles(srcDir, /\.test\.ts$/);
|
|
19133
19415
|
const layers = LAYER_DIRS.map(({ name, dir }) => ({
|
|
19134
19416
|
name,
|
|
19135
|
-
files: countFiles(
|
|
19417
|
+
files: countFiles(path23.join(srcDir, dir), /\.ts$/)
|
|
19136
19418
|
})).filter((l) => l.files > 0);
|
|
19137
19419
|
return {
|
|
19138
19420
|
version: readVersion(pkgRoot),
|
|
@@ -20281,7 +20563,7 @@ function handleStatusCommand2(args) {
|
|
|
20281
20563
|
|
|
20282
20564
|
// src/cli/scenario-command.ts
|
|
20283
20565
|
import { readdir as readdir4 } from "fs/promises";
|
|
20284
|
-
import { join as join19, resolve as
|
|
20566
|
+
import { join as join19, resolve as resolve11 } from "path";
|
|
20285
20567
|
|
|
20286
20568
|
// src/testing/e2e/scenario-runner.ts
|
|
20287
20569
|
import { readFile as readFile6 } from "fs/promises";
|
|
@@ -20412,9 +20694,9 @@ function checkCircularDependencies(workflow) {
|
|
|
20412
20694
|
for (const step of workflow.steps) {
|
|
20413
20695
|
stepMap.set(step.id, step);
|
|
20414
20696
|
}
|
|
20415
|
-
const visit = (stepId,
|
|
20697
|
+
const visit = (stepId, path24) => {
|
|
20416
20698
|
if (visiting.has(stepId)) {
|
|
20417
|
-
errors.push(`Circular dependency detected: ${[...
|
|
20699
|
+
errors.push(`Circular dependency detected: ${[...path24, stepId].join(" -> ")}`);
|
|
20418
20700
|
return false;
|
|
20419
20701
|
}
|
|
20420
20702
|
if (visited.has(stepId)) return true;
|
|
@@ -20422,7 +20704,7 @@ function checkCircularDependencies(workflow) {
|
|
|
20422
20704
|
const step = stepMap.get(stepId);
|
|
20423
20705
|
if (step?.dependsOn) {
|
|
20424
20706
|
for (const dep of step.dependsOn) {
|
|
20425
|
-
if (!visit(dep, [...
|
|
20707
|
+
if (!visit(dep, [...path24, stepId])) {
|
|
20426
20708
|
return false;
|
|
20427
20709
|
}
|
|
20428
20710
|
}
|
|
@@ -20441,7 +20723,7 @@ function checkCircularDependencies(workflow) {
|
|
|
20441
20723
|
var defaultStubFactory = {
|
|
20442
20724
|
createAgentStub(agentType, action) {
|
|
20443
20725
|
return async (inputs) => {
|
|
20444
|
-
await new Promise((
|
|
20726
|
+
await new Promise((resolve12) => setTimeout(resolve12, 10));
|
|
20445
20727
|
return {
|
|
20446
20728
|
stepId: `${agentType}-${action}`,
|
|
20447
20729
|
status: "success",
|
|
@@ -20466,8 +20748,8 @@ var ScenarioRunner = class {
|
|
|
20466
20748
|
/**
|
|
20467
20749
|
* Load a scenario fixture from a YAML file.
|
|
20468
20750
|
*/
|
|
20469
|
-
async loadFixture(
|
|
20470
|
-
const content = await readFile6(
|
|
20751
|
+
async loadFixture(path24) {
|
|
20752
|
+
const content = await readFile6(path24, "utf-8");
|
|
20471
20753
|
const data = yaml7.parse(content);
|
|
20472
20754
|
return ScenarioFixtureSchema.parse(data);
|
|
20473
20755
|
}
|
|
@@ -20600,7 +20882,7 @@ function createScenarioRunner(stubFactory) {
|
|
|
20600
20882
|
}
|
|
20601
20883
|
|
|
20602
20884
|
// src/cli/scenario-command.ts
|
|
20603
|
-
var FIXTURES_DIR =
|
|
20885
|
+
var FIXTURES_DIR = resolve11(import.meta.dirname, "../testing/e2e/fixtures");
|
|
20604
20886
|
var SCENARIO_SUFFIX = ".scenario.yaml";
|
|
20605
20887
|
async function listScenarios() {
|
|
20606
20888
|
try {
|
|
@@ -20681,6 +20963,137 @@ async function handleScenarioCommand(args) {
|
|
|
20681
20963
|
process.exit(EXIT_CODES.SERVER_START_FAILED);
|
|
20682
20964
|
}
|
|
20683
20965
|
|
|
20966
|
+
// src/cli/health-command.ts
|
|
20967
|
+
function collectHealth() {
|
|
20968
|
+
const report = generateWeatherReport({});
|
|
20969
|
+
return {
|
|
20970
|
+
swarmHealth: report.swarmHealth,
|
|
20971
|
+
overallSuccessRate: report.overall.successRate,
|
|
20972
|
+
totalTasks: report.overall.totalTasks,
|
|
20973
|
+
failureBreakdown: report.failureBreakdown ?? [],
|
|
20974
|
+
cliCount: report.cliWeather.length,
|
|
20975
|
+
cliHealth: report.cliWeather.map(toCliSummary),
|
|
20976
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
20977
|
+
};
|
|
20978
|
+
}
|
|
20979
|
+
function toCliSummary(cw) {
|
|
20980
|
+
return {
|
|
20981
|
+
cli: cw.cli,
|
|
20982
|
+
successRate: cw.successRate,
|
|
20983
|
+
totalTasks: cw.totalTasks,
|
|
20984
|
+
avgDurationMs: cw.avgDurationMs
|
|
20985
|
+
};
|
|
20986
|
+
}
|
|
20987
|
+
function renderMetricBar(value, max) {
|
|
20988
|
+
const width = 20;
|
|
20989
|
+
const filled = Math.round(value / max * width);
|
|
20990
|
+
const bar = "\u2588".repeat(filled) + "\u2591".repeat(width - filled);
|
|
20991
|
+
return bar;
|
|
20992
|
+
}
|
|
20993
|
+
function renderSwarmMetrics(w, health) {
|
|
20994
|
+
const c = colors;
|
|
20995
|
+
const pct = (v) => `${(v * 100).toFixed(1)}%`;
|
|
20996
|
+
w(` ${c.bold}Swarm Health Metrics${c.reset}
|
|
20997
|
+
`);
|
|
20998
|
+
w(
|
|
20999
|
+
` Agent Utilization: ${renderMetricBar(health.agentUtilization, 1)} ${pct(health.agentUtilization)}
|
|
21000
|
+
`
|
|
21001
|
+
);
|
|
21002
|
+
w(
|
|
21003
|
+
` Collaboration Efficiency:${renderMetricBar(health.collaborationEfficiency, 1)} ${pct(health.collaborationEfficiency)}
|
|
21004
|
+
`
|
|
21005
|
+
);
|
|
21006
|
+
w(
|
|
21007
|
+
` Routing Accuracy: ${renderMetricBar(health.routingAccuracy, 1)} ${pct(health.routingAccuracy)}
|
|
21008
|
+
`
|
|
21009
|
+
);
|
|
21010
|
+
w(` Weekly Regret: ${health.weeklyRegret.toFixed(3)}
|
|
21011
|
+
`);
|
|
21012
|
+
w(` Adaptation Speed: ${String(health.adaptationSpeed)} tasks
|
|
21013
|
+
`);
|
|
21014
|
+
w(` Observed Categories: ${String(health.observedCategories)}
|
|
21015
|
+
`);
|
|
21016
|
+
w(` Observed Roles: ${String(health.observedRoles)}
|
|
21017
|
+
`);
|
|
21018
|
+
w("\n");
|
|
21019
|
+
}
|
|
21020
|
+
function renderCliHealth(w, entries) {
|
|
21021
|
+
const c = colors;
|
|
21022
|
+
w(` ${c.bold}Per-CLI Performance${c.reset}
|
|
21023
|
+
`);
|
|
21024
|
+
for (const entry of entries) {
|
|
21025
|
+
const rateColor = entry.successRate >= 0.8 ? c.green : entry.successRate >= 0.6 ? c.yellow : c.red;
|
|
21026
|
+
const pct = `${(entry.successRate * 100).toFixed(0)}%`;
|
|
21027
|
+
const dur = entry.avgDurationMs >= 1e3 ? `${(entry.avgDurationMs / 1e3).toFixed(1)}s` : `${String(Math.round(entry.avgDurationMs))}ms`;
|
|
21028
|
+
w(
|
|
21029
|
+
` ${entry.cli.padEnd(12)} ${rateColor}${pct.padStart(4)}${c.reset} ${String(entry.totalTasks).padStart(5)} tasks ${c.dim}avg ${dur}${c.reset}
|
|
21030
|
+
`
|
|
21031
|
+
);
|
|
21032
|
+
}
|
|
21033
|
+
w("\n");
|
|
21034
|
+
}
|
|
21035
|
+
function renderFailureBreakdown(w, entries) {
|
|
21036
|
+
const c = colors;
|
|
21037
|
+
if (entries.length === 0) {
|
|
21038
|
+
w(` ${c.green}No failures recorded${c.reset}
|
|
21039
|
+
|
|
21040
|
+
`);
|
|
21041
|
+
return;
|
|
21042
|
+
}
|
|
21043
|
+
w(` ${c.bold}Failure Breakdown${c.reset}
|
|
21044
|
+
`);
|
|
21045
|
+
for (const entry of entries) {
|
|
21046
|
+
const color2 = entry.category === "unknown" ? c.yellow : c.dim;
|
|
21047
|
+
w(
|
|
21048
|
+
` ${color2}${entry.category.padEnd(22)}${c.reset} ${String(entry.count).padStart(4)} (${String(entry.percentage)}%)
|
|
21049
|
+
`
|
|
21050
|
+
);
|
|
21051
|
+
}
|
|
21052
|
+
w("\n");
|
|
21053
|
+
}
|
|
21054
|
+
function renderTable2(health) {
|
|
21055
|
+
const c = colors;
|
|
21056
|
+
const s = symbols;
|
|
21057
|
+
const w = process.stdout.write.bind(process.stdout);
|
|
21058
|
+
w(`
|
|
21059
|
+
${c.bold}nexus-agents${c.reset}`);
|
|
21060
|
+
w(` ${c.dim}\u2014 Swarm Health Dashboard${c.reset}
|
|
21061
|
+
|
|
21062
|
+
`);
|
|
21063
|
+
const rateColor = health.overallSuccessRate >= 0.8 ? c.green : health.overallSuccessRate >= 0.6 ? c.yellow : c.red;
|
|
21064
|
+
const rateSym = health.overallSuccessRate >= 0.8 ? s.check : s.warn;
|
|
21065
|
+
const pctStr = `${(health.overallSuccessRate * 100).toFixed(1)}%`;
|
|
21066
|
+
w(` Success Rate: ${rateColor}${pctStr}${c.reset} ${rateSym}
|
|
21067
|
+
`);
|
|
21068
|
+
w(` Total Tasks: ${c.cyan}${String(health.totalTasks)}${c.reset}
|
|
21069
|
+
`);
|
|
21070
|
+
w(` Active CLIs: ${c.cyan}${String(health.cliCount)}${c.reset}
|
|
21071
|
+
|
|
21072
|
+
`);
|
|
21073
|
+
if (health.cliHealth.length > 0) {
|
|
21074
|
+
renderCliHealth(w, health.cliHealth);
|
|
21075
|
+
}
|
|
21076
|
+
if (health.swarmHealth !== void 0) {
|
|
21077
|
+
renderSwarmMetrics(w, health.swarmHealth);
|
|
21078
|
+
} else {
|
|
21079
|
+
w(` ${c.dim}No swarm metrics available (requires task history)${c.reset}
|
|
21080
|
+
|
|
21081
|
+
`);
|
|
21082
|
+
}
|
|
21083
|
+
renderFailureBreakdown(w, health.failureBreakdown);
|
|
21084
|
+
}
|
|
21085
|
+
function renderJson2(health) {
|
|
21086
|
+
process.stdout.write(JSON.stringify(health, null, 2) + "\n");
|
|
21087
|
+
}
|
|
21088
|
+
function handleHealthCommand(args) {
|
|
21089
|
+
const health = collectHealth();
|
|
21090
|
+
if (args.options.format === "json") {
|
|
21091
|
+
renderJson2(health);
|
|
21092
|
+
} else {
|
|
21093
|
+
renderTable2(health);
|
|
21094
|
+
}
|
|
21095
|
+
}
|
|
21096
|
+
|
|
20684
21097
|
// src/cli-commands.ts
|
|
20685
21098
|
function printHelp() {
|
|
20686
21099
|
process.stdout.write(HELP_TEXT + "\n");
|
|
@@ -20714,7 +21127,9 @@ var SYNC_COMMAND_HANDLERS = {
|
|
|
20714
21127
|
"warm-up": handleWarmUpCommand,
|
|
20715
21128
|
"e2e-eval": handleE2EEvalCommand,
|
|
20716
21129
|
"routing-ab": handleRoutingABCommand,
|
|
20717
|
-
"memory-eval": handleMemoryEvalCommand
|
|
21130
|
+
"memory-eval": handleMemoryEvalCommand,
|
|
21131
|
+
// Issue #1403: Health Command
|
|
21132
|
+
health: handleHealthCommand
|
|
20718
21133
|
};
|
|
20719
21134
|
function handleSyncCommand(args) {
|
|
20720
21135
|
if (args.command === "help") {
|
|
@@ -20769,6 +21184,7 @@ async function handleAsyncCommand(args) {
|
|
|
20769
21184
|
}
|
|
20770
21185
|
}
|
|
20771
21186
|
async function dispatchCommand(args) {
|
|
21187
|
+
initDataDirectories();
|
|
20772
21188
|
if (!handleSyncCommand(args)) {
|
|
20773
21189
|
await handleAsyncCommand(args);
|
|
20774
21190
|
}
|
|
@@ -21051,16 +21467,28 @@ function parseSweBenchVariant(value) {
|
|
|
21051
21467
|
}
|
|
21052
21468
|
return void 0;
|
|
21053
21469
|
}
|
|
21470
|
+
var SWE_BENCH_STRING_MAPPINGS = [
|
|
21471
|
+
["predictions", "predictions"],
|
|
21472
|
+
["cache-level", "cacheLevel"],
|
|
21473
|
+
["max-workers", "maxWorkers"],
|
|
21474
|
+
["run-id", "runId"],
|
|
21475
|
+
["output-dir", "outputDir"]
|
|
21476
|
+
];
|
|
21054
21477
|
function buildSweBenchOptions(values) {
|
|
21055
21478
|
const variant = parseSweBenchVariant(values.variant);
|
|
21056
21479
|
const limit = parseNumericOption(values.limit);
|
|
21057
|
-
const
|
|
21058
|
-
|
|
21059
|
-
};
|
|
21480
|
+
const concurrency = parseNumericOption(values.concurrency);
|
|
21481
|
+
const base = { resume: values.resume };
|
|
21060
21482
|
if (variant !== void 0) base.variant = variant;
|
|
21061
21483
|
if (limit !== void 0) base.limit = limit;
|
|
21484
|
+
if (concurrency !== void 0) base.concurrency = concurrency;
|
|
21485
|
+
if (values.mcp) base.mcp = true;
|
|
21486
|
+
for (const [src, tgt] of SWE_BENCH_STRING_MAPPINGS) {
|
|
21487
|
+
const val = values[src];
|
|
21488
|
+
if (val !== void 0) base[tgt] = val;
|
|
21489
|
+
}
|
|
21062
21490
|
if (values.instance !== void 0 && values.instance.length > 0) {
|
|
21063
|
-
|
|
21491
|
+
base.instance = values.instance;
|
|
21064
21492
|
}
|
|
21065
21493
|
return base;
|
|
21066
21494
|
}
|