nexus-agents 4.3.6 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -52,7 +52,7 @@ import {
52
52
  } from "./chunk-OQLFRJCW.js";
53
53
 
54
54
  // src/version.ts
55
- var VERSION = true ? "4.3.6" : "dev";
55
+ var VERSION = true ? "4.4.0" : "dev";
56
56
 
57
57
  // src/config/schemas-core.ts
58
58
  import { z } from "zod";
@@ -2339,7 +2339,7 @@ async function runDoctorFix(result) {
2339
2339
  writeLine2("\u2500".repeat(40));
2340
2340
  let fixCount = 0;
2341
2341
  if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
2342
- const { runSetup } = await import("./setup-command-TLIVUIVE.js");
2342
+ const { runSetup } = await import("./setup-command-4RQUTUDI.js");
2343
2343
  const setupResult = runSetup({
2344
2344
  skipMcp: true,
2345
2345
  skipRules: true,
@@ -2452,4 +2452,4 @@ export {
2452
2452
  startStdioServer,
2453
2453
  closeServer
2454
2454
  };
2455
- //# sourceMappingURL=chunk-CDLXONR6.js.map
2455
+ //# sourceMappingURL=chunk-4KDZ4Q6B.js.map
@@ -8,7 +8,7 @@ import {
8
8
  checkSqlite,
9
9
  defaultConfig,
10
10
  initDataDirectories
11
- } from "./chunk-CDLXONR6.js";
11
+ } from "./chunk-4KDZ4Q6B.js";
12
12
  import {
13
13
  BUILT_IN_EXPERTS
14
14
  } from "./chunk-YPNQPT2F.js";
@@ -2001,4 +2001,4 @@ export {
2001
2001
  setupCommand,
2002
2002
  setupCommandAsync
2003
2003
  };
2004
- //# sourceMappingURL=chunk-NXGHNZJV.js.map
2004
+ //# sourceMappingURL=chunk-FLCUFTXF.js.map
@@ -22,7 +22,7 @@ import {
22
22
  DEFAULT_TASK_TTL_MS,
23
23
  DEFAULT_TOOL_RATE_LIMITS,
24
24
  clampTaskTtl
25
- } from "./chunk-CDLXONR6.js";
25
+ } from "./chunk-4KDZ4Q6B.js";
26
26
  import {
27
27
  executeExpert
28
28
  } from "./chunk-QTP4AIVR.js";
@@ -54497,4 +54497,4 @@ export {
54497
54497
  shutdownFeedbackSubscriber,
54498
54498
  createEventBusBridge
54499
54499
  };
54500
- //# sourceMappingURL=chunk-K6VI5GUF.js.map
54500
+ //# sourceMappingURL=chunk-YBGX57DL.js.map
package/dist/cli.js CHANGED
@@ -18,7 +18,7 @@ import "./chunk-TKFWYFBD.js";
18
18
  import {
19
19
  setupCommandAsync,
20
20
  verifyCommand
21
- } from "./chunk-NXGHNZJV.js";
21
+ } from "./chunk-FLCUFTXF.js";
22
22
  import "./chunk-YIV4GQHK.js";
23
23
  import {
24
24
  AuthHandler,
@@ -139,7 +139,7 @@ import {
139
139
  validateCommand,
140
140
  validateWorkflow,
141
141
  wrapInMarkdownFence
142
- } from "./chunk-K6VI5GUF.js";
142
+ } from "./chunk-YBGX57DL.js";
143
143
  import "./chunk-SHG3MYMD.js";
144
144
  import "./chunk-HFOQKCD2.js";
145
145
  import "./chunk-RSMG2DPB.js";
@@ -166,7 +166,7 @@ import {
166
166
  loadConfig,
167
167
  runDoctor,
168
168
  validateNexusEnv
169
- } from "./chunk-CDLXONR6.js";
169
+ } from "./chunk-4KDZ4Q6B.js";
170
170
  import {
171
171
  buildOpenAICompatAdapters,
172
172
  readOpenAICompatEnv
@@ -14806,13 +14806,36 @@ async function releaseNotesCommand(args) {
14806
14806
  import { readFileSync as readFileSync10 } from "fs";
14807
14807
 
14808
14808
  // src/cli/release-validate-helpers.ts
14809
- import { execSync as execSync2 } from "child_process";
14809
+ import { execSync as execSync3 } from "child_process";
14810
14810
  import { existsSync as existsSync14, readFileSync as readFileSync9 } from "fs";
14811
+
14812
+ // src/cli/release-secret-scan.ts
14813
+ import { execSync as execSync2 } from "child_process";
14814
+ var SECRET_LINE_PATTERN = /api[_-]?key|secret|password|token/i;
14815
+ var MAX_REPORTED_MATCHES = 5;
14816
+ function scanRecentCommitsForSecrets(options = {}) {
14817
+ const range = options.range ?? "HEAD~10..HEAD";
14818
+ let diff;
14819
+ try {
14820
+ diff = execSync2(`git diff ${range} -- "*.ts" "*.js"`, {
14821
+ encoding: "utf-8",
14822
+ stdio: ["pipe", "pipe", "pipe"],
14823
+ timeout: CLI_SUBPROCESS_TIMEOUTS.ghCommandMs,
14824
+ ...options.cwd === void 0 ? {} : { cwd: options.cwd }
14825
+ });
14826
+ } catch (error) {
14827
+ return { ok: false, reason: error instanceof Error ? error.message : String(error) };
14828
+ }
14829
+ const matches = diff.split("\n").filter((line) => SECRET_LINE_PATTERN.test(line)).slice(0, MAX_REPORTED_MATCHES);
14830
+ return { ok: true, matches };
14831
+ }
14832
+
14833
+ // src/cli/release-validate-helpers.ts
14811
14834
  async function validateSecurity(options) {
14812
14835
  const startTime = Date.now();
14813
14836
  const findings = [];
14814
14837
  try {
14815
- execSync2("npm audit --audit-level=high 2>/dev/null", {
14838
+ execSync3("npm audit --audit-level=high 2>/dev/null", {
14816
14839
  encoding: "utf-8",
14817
14840
  stdio: ["pipe", "pipe", "pipe"],
14818
14841
  timeout: CLI_SUBPROCESS_TIMEOUTS.ghCommandMs
@@ -14835,37 +14858,29 @@ async function validateSecurity(options) {
14835
14858
  remediation: "Ensure .env is in .gitignore and not committed."
14836
14859
  });
14837
14860
  }
14838
- try {
14839
- const result = execSync2(
14840
- 'git diff HEAD~10..HEAD -- "*.ts" "*.js" | grep -iE "(api[_-]?key|secret|password|token)" | head -5',
14841
- {
14842
- encoding: "utf-8",
14843
- stdio: ["pipe", "pipe", "pipe"],
14844
- timeout: CLI_SUBPROCESS_TIMEOUTS.ghCommandMs
14845
- }
14846
- );
14847
- if (result.trim()) {
14848
- findings.push({
14849
- severity: "warning",
14850
- category: "security",
14851
- title: "Potential secrets in recent commits",
14852
- description: "Recent commits may contain hardcoded secrets.",
14853
- remediation: "Review commits for any exposed credentials."
14854
- });
14855
- }
14856
- } catch {
14861
+ const scan = scanRecentCommitsForSecrets();
14862
+ if (!scan.ok) {
14857
14863
  findings.push({
14858
14864
  severity: "warning",
14859
14865
  category: "security",
14860
14866
  title: "Secret scan did not run",
14861
- description: "The hardcoded-secret scan over recent commits failed to execute.",
14867
+ description: `The hardcoded-secret scan over recent commits failed to execute: ${scan.reason}`,
14862
14868
  remediation: "Re-run with a full git history available, then review the output."
14863
14869
  });
14870
+ } else if (scan.matches.length > 0) {
14871
+ findings.push({
14872
+ severity: "warning",
14873
+ category: "security",
14874
+ title: "Potential secrets in recent commits",
14875
+ description: "Recent commits may contain hardcoded secrets.",
14876
+ remediation: "Review commits for any exposed credentials."
14877
+ });
14864
14878
  }
14865
14879
  return {
14866
14880
  expert: "security",
14867
- // whenEmpty = false: with the failure above recorded as a finding, an empty
14868
- // list now genuinely means "scanned, nothing found" (#4581).
14881
+ // whenEmpty = false: an empty list genuinely means "scanned, nothing
14882
+ // found" — every check above records a finding when it cannot run, which
14883
+ // for the secret scan required #4839 as well as #4581.
14869
14884
  passed: !anyOf(findings, (f) => f.severity === "error", false),
14870
14885
  confidence: 0.85,
14871
14886
  findings,
@@ -14876,7 +14891,7 @@ async function validateArchitecture2(options) {
14876
14891
  const startTime = Date.now();
14877
14892
  const findings = [];
14878
14893
  try {
14879
- const result = execSync2("npx nexus-agents fitness-audit --format=json 2>/dev/null", {
14894
+ const result = execSync3("npx nexus-agents fitness-audit --format=json 2>/dev/null", {
14880
14895
  encoding: "utf-8",
14881
14896
  stdio: ["pipe", "pipe", "pipe"],
14882
14897
  timeout: CLI_SUBPROCESS_TIMEOUTS.releaseValidateMs
@@ -14997,7 +15012,7 @@ async function validateDevOps(options) {
14997
15012
  const startTime = Date.now();
14998
15013
  const findings = [];
14999
15014
  try {
15000
- execSync2("pnpm build 2>/dev/null", {
15015
+ execSync3("pnpm build 2>/dev/null", {
15001
15016
  encoding: "utf-8",
15002
15017
  stdio: ["pipe", "pipe", "pipe"],
15003
15018
  timeout: CLI_SUBPROCESS_TIMEOUTS.releaseValidateMs
@@ -15018,7 +15033,7 @@ async function validateDevOps(options) {
15018
15033
  });
15019
15034
  }
15020
15035
  try {
15021
- execSync2("pnpm lint 2>/dev/null", {
15036
+ execSync3("pnpm lint 2>/dev/null", {
15022
15037
  encoding: "utf-8",
15023
15038
  stdio: ["pipe", "pipe", "pipe"],
15024
15039
  timeout: CLI_SUBPROCESS_TIMEOUTS.releaseBuildMs
@@ -15039,7 +15054,7 @@ async function validateDevOps(options) {
15039
15054
  });
15040
15055
  }
15041
15056
  try {
15042
- execSync2("pnpm typecheck 2>/dev/null", {
15057
+ execSync3("pnpm typecheck 2>/dev/null", {
15043
15058
  encoding: "utf-8",
15044
15059
  stdio: ["pipe", "pipe", "pipe"],
15045
15060
  timeout: CLI_SUBPROCESS_TIMEOUTS.releaseValidateMs
@@ -16300,6 +16315,7 @@ Winner (by success rate): ${report.winnerBySuccessRate}`);
16300
16315
  }
16301
16316
 
16302
16317
  // src/cli/memory-eval.ts
16318
+ var TOP_K = 5;
16303
16319
  function generateEvalDataset(size = 50) {
16304
16320
  const pairs = [];
16305
16321
  const sources = ["session", "belief", "agentic", "typed"];
@@ -16315,16 +16331,19 @@ function generateEvalDataset(size = 50) {
16315
16331
  { query: "logging best practices", content: "Structured JSON logs with correlation IDs" },
16316
16332
  { query: "security vulnerability scan", content: "Dependabot and CodeQL automated scans" }
16317
16333
  ];
16334
+ const queryCount = Math.max(1, Math.min(topics.length, Math.floor(size / (TOP_K * 2))));
16318
16335
  for (let i = 0; i < size; i++) {
16319
- const topicIdx = i % topics.length;
16336
+ const topicIdx = i % queryCount;
16320
16337
  const topic = topics[topicIdx];
16321
16338
  const source = sources[i % sources.length] ?? "session";
16322
16339
  const isRelevant = i % 3 !== 0;
16323
- if (topic !== void 0) {
16340
+ const offset = 1 + i % (topics.length - 1);
16341
+ const contentTopic = isRelevant ? topic : topics[(topicIdx + offset) % topics.length];
16342
+ if (topic !== void 0 && contentTopic !== void 0) {
16324
16343
  pairs.push({
16325
- query: isRelevant ? topic.query : `unrelated query ${String(i)}`,
16344
+ query: topic.query,
16326
16345
  memoryKey: `mem-${String(i)}-${source}`,
16327
- memoryContent: topic.content,
16346
+ memoryContent: contentTopic.content,
16328
16347
  source,
16329
16348
  expectedRelevant: isRelevant
16330
16349
  });
@@ -16374,8 +16393,9 @@ function expandKeywords(query) {
16374
16393
  return result;
16375
16394
  }
16376
16395
  function evaluateScorer(dataset, scorer) {
16377
- const k = 5;
16396
+ const k = TOP_K;
16378
16397
  let totalRecall = 0;
16398
+ let recallQueries = 0;
16379
16399
  let totalPrecision = 0;
16380
16400
  let totalMrr = 0;
16381
16401
  const latencies = [];
@@ -16393,7 +16413,10 @@ function evaluateScorer(dataset, scorer) {
16393
16413
  const topK = scored.slice(0, k);
16394
16414
  const relevantInTopK = topK.filter((s) => s.relevant).length;
16395
16415
  const totalRelevant = pairs.filter((p) => p.expectedRelevant).length;
16396
- totalRecall += totalRelevant > 0 ? relevantInTopK / totalRelevant : 1;
16416
+ if (totalRelevant > 0) {
16417
+ totalRecall += relevantInTopK / totalRelevant;
16418
+ recallQueries += 1;
16419
+ }
16397
16420
  totalPrecision += topK.length > 0 ? relevantInTopK / topK.length : 0;
16398
16421
  const firstRelevantIdx = scored.findIndex((s) => s.relevant);
16399
16422
  totalMrr += firstRelevantIdx >= 0 ? 1 / (firstRelevantIdx + 1) : 0;
@@ -16402,12 +16425,13 @@ function evaluateScorer(dataset, scorer) {
16402
16425
  latencies.sort((a, b) => a - b);
16403
16426
  const p95Idx = Math.floor(latencies.length * 0.95);
16404
16427
  return {
16405
- recallAt5: n > 0 ? round(totalRecall / n) : 0,
16428
+ recallAt5: recallQueries > 0 ? round(totalRecall / recallQueries) : 0,
16406
16429
  precisionAt5: n > 0 ? round(totalPrecision / n) : 0,
16407
16430
  mrr: n > 0 ? round(totalMrr / n) : 0,
16408
16431
  avgLatencyMs: round(average(latencies)),
16409
16432
  p95LatencyMs: round(latencies[p95Idx] ?? 0),
16410
- totalQueries: n
16433
+ totalQueries: n,
16434
+ recallQueries
16411
16435
  };
16412
16436
  }
16413
16437
  function groupByQuery(dataset) {
@@ -16446,6 +16470,11 @@ function formatMemoryEvalReport(report) {
16446
16470
  }
16447
16471
  function formatEvalDetails(baseline, reflective, improvement, datasetSize) {
16448
16472
  const lines = [`Dataset: ${String(datasetSize)} query-memory pairs`];
16473
+ if (baseline.recallQueries < baseline.totalQueries) {
16474
+ lines.push(
16475
+ `Recall measured over ${String(baseline.recallQueries)} of ${String(baseline.totalQueries)} queries \u2014 the rest had no relevant memory.`
16476
+ );
16477
+ }
16449
16478
  lines.push("\nBaseline (keyword search):");
16450
16479
  lines.push(` Recall@5: ${baseline.recallAt5.toFixed(3)}`);
16451
16480
  lines.push(` Precision@5: ${baseline.precisionAt5.toFixed(3)}`);