nexus-agents 8.133.5 → 8.134.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.
Files changed (26) hide show
  1. package/dist/{chunk-J466LJ35.js → chunk-GN3OLNPH.js} +96 -15
  2. package/dist/chunk-GN3OLNPH.js.map +1 -0
  3. package/dist/{chunk-DKO2UVFI.js → chunk-LO53UJFH.js} +2 -2
  4. package/dist/{chunk-WWHTLQWO.js → chunk-LVQLLB2I.js} +8 -8
  5. package/dist/{chunk-SQ76KQRG.js → chunk-OF6F5ZGV.js} +2 -2
  6. package/dist/{chunk-CPG2YZ44.js → chunk-SBDWDV62.js} +2 -2
  7. package/dist/{chunk-BPEUNLUO.js → chunk-T7MEIXWY.js} +3 -3
  8. package/dist/cli.d.ts +3 -1
  9. package/dist/cli.js +20 -7
  10. package/dist/cli.js.map +1 -1
  11. package/dist/{consensus-vote-NVDH66XO.js → consensus-vote-35OIKULP.js} +4 -4
  12. package/dist/{consensus-vote-types-331PZ3Vk.d.ts → consensus-vote-types-Coff77gH.d.ts} +1 -0
  13. package/dist/{improvement-review-GBYOUVNK.js → improvement-review-WMCUNTA5.js} +4 -4
  14. package/dist/index.d.ts +2 -2
  15. package/dist/index.js +6 -6
  16. package/dist/{setup-data-dir-Z4ZQTRTH.js → setup-data-dir-RQRZTOOH.js} +3 -3
  17. package/package.json +1 -1
  18. package/dist/chunk-J466LJ35.js.map +0 -1
  19. /package/dist/{chunk-DKO2UVFI.js.map → chunk-LO53UJFH.js.map} +0 -0
  20. /package/dist/{chunk-WWHTLQWO.js.map → chunk-LVQLLB2I.js.map} +0 -0
  21. /package/dist/{chunk-SQ76KQRG.js.map → chunk-OF6F5ZGV.js.map} +0 -0
  22. /package/dist/{chunk-CPG2YZ44.js.map → chunk-SBDWDV62.js.map} +0 -0
  23. /package/dist/{chunk-BPEUNLUO.js.map → chunk-T7MEIXWY.js.map} +0 -0
  24. /package/dist/{consensus-vote-NVDH66XO.js.map → consensus-vote-35OIKULP.js.map} +0 -0
  25. /package/dist/{improvement-review-GBYOUVNK.js.map → improvement-review-WMCUNTA5.js.map} +0 -0
  26. /package/dist/{setup-data-dir-Z4ZQTRTH.js.map → setup-data-dir-RQRZTOOH.js.map} +0 -0
@@ -21,7 +21,7 @@ import {
21
21
  toolSuccessStructured,
22
22
  withProgressHeartbeat,
23
23
  wrapToolWithTimeout
24
- } from "./chunk-CPG2YZ44.js";
24
+ } from "./chunk-SBDWDV62.js";
25
25
  import {
26
26
  getToolMemory
27
27
  } from "./chunk-KJI4SNSK.js";
@@ -30,7 +30,7 @@ import {
30
30
  } from "./chunk-EZNIYU5T.js";
31
31
  import {
32
32
  VERSION
33
- } from "./chunk-DKO2UVFI.js";
33
+ } from "./chunk-LO53UJFH.js";
34
34
  import {
35
35
  isGatewayModelAdapter
36
36
  } from "./chunk-BGHKG77F.js";
@@ -112,6 +112,7 @@ import {
112
112
  readVoteRecords,
113
113
  recordUsageEvent,
114
114
  registerPersistentOutcomeStoreFactory,
115
+ resolveInsideRoot,
115
116
  resolveModelIdentitySync,
116
117
  resolveVoteRecordsPath,
117
118
  servedCostDetail,
@@ -140,6 +141,7 @@ import {
140
141
 
141
142
  // src/mcp/tools/consensus-vote.ts
142
143
  import { randomUUID as randomUUID4 } from "node:crypto";
144
+ import { basename as basename2 } from "node:path";
143
145
  import { z as z15 } from "zod";
144
146
 
145
147
  // src/mcp/tools/async-dispatch-input.ts
@@ -2400,6 +2402,54 @@ async function collectRealVotes(options) {
2400
2402
  return results;
2401
2403
  }
2402
2404
 
2405
+ // src/cli/vote-artifact.ts
2406
+ import { createHash } from "node:crypto";
2407
+ import { constants } from "node:fs";
2408
+ import { open } from "node:fs/promises";
2409
+ import { basename } from "node:path";
2410
+ var MAX_VOTE_ARTIFACT_BYTES = 256 * 1024;
2411
+ function oversizedArtifact(bytes) {
2412
+ return new Error(
2413
+ `Vote artifact is ${String(bytes)} bytes; cap is ${String(MAX_VOTE_ARTIFACT_BYTES)} bytes`
2414
+ );
2415
+ }
2416
+ async function readBoundedArtifact(artifactPath) {
2417
+ const file = await open(artifactPath, constants.O_RDONLY | constants.O_NONBLOCK);
2418
+ try {
2419
+ const stat = await file.stat();
2420
+ if (!stat.isFile()) throw new Error("Vote artifact must be a regular file");
2421
+ if (stat.size > MAX_VOTE_ARTIFACT_BYTES) throw oversizedArtifact(stat.size);
2422
+ const buffer = Buffer.alloc(MAX_VOTE_ARTIFACT_BYTES + 1);
2423
+ let size = 0;
2424
+ while (size < buffer.length) {
2425
+ const { bytesRead } = await file.read(buffer, size, buffer.length - size, null);
2426
+ if (bytesRead === 0) break;
2427
+ size += bytesRead;
2428
+ }
2429
+ if (size > MAX_VOTE_ARTIFACT_BYTES) {
2430
+ throw oversizedArtifact(Math.max(size, (await file.stat()).size));
2431
+ }
2432
+ return buffer.subarray(0, size);
2433
+ } finally {
2434
+ await file.close();
2435
+ }
2436
+ }
2437
+ async function inlineVoteArtifact(proposal, artifactPath, displayName) {
2438
+ if (artifactPath === void 0) return proposal;
2439
+ const bytes = await readBoundedArtifact(artifactPath);
2440
+ if (bytes.length === 0) throw new Error("Vote artifact is empty; an artifact must have content");
2441
+ if (bytes.includes(0)) throw new Error("Vote artifact is binary (contains a NUL byte)");
2442
+ const content = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
2443
+ const digest = createHash("sha256").update(bytes).digest("hex");
2444
+ const header = `Artifact: ${displayName ?? basename(artifactPath)} sha256:${digest} ${String(bytes.length)} bytes`;
2445
+ return `${proposal}
2446
+
2447
+ ${header}
2448
+ ===== BEGIN ARTIFACT =====
2449
+ ${content}
2450
+ ===== END ARTIFACT =====`;
2451
+ }
2452
+
2403
2453
  // src/cli/voter-project.ts
2404
2454
  import { readFileSync, statSync } from "node:fs";
2405
2455
  import { dirname, isAbsolute, join, resolve } from "node:path";
@@ -6154,6 +6204,9 @@ var ConsensusVoteInputSchema = z8.object({
6154
6204
  proposal: z8.string().min(1).max(MAX_PROPOSAL_LENGTH).describe(
6155
6205
  'Proposal text to vote on. If the proposal asks voters to choose among named alternatives, declare them in `options` (#4472) \u2014 otherwise the tally records approve/reject/abstain only, so every voter who engages returns `approve` and a 6-1 split on WHICH option persists as 7-0, 100% (#4452). This is ENFORCED AS A WARNING, not a refusal: a heuristic over the proposal text flags an apparent multi-option proposal with no `options` and says so on `panelWarning` (#5360). The wording says "declare", not "MUST", because the warning is what the code actually holds \u2014 it is tightened back only in the same change that promotes the warning to a refusal.'
6156
6206
  ),
6207
+ artifactPath: z8.string().min(1).max(4096).optional().describe(
6208
+ "UTF-8 artifact file within the repository root (server cwd). Its content is inlined into every seat's proposal with a SHA-256 digest; maximum 256 KiB. Missing, empty, binary (NUL byte), oversized, and escaping paths are rejected. Seats read the inlined text, not the tree."
6209
+ ),
6157
6210
  options: z8.array(z8.string().min(1).max(200)).min(2).max(10).optional().describe(
6158
6211
  "Named alternatives for a multi-option proposal (#4472). When present, the threshold must ALSO be cleared by the leading option, in addition to the ordinary approve/reject bar: `unanimous` requires every approver to have chosen the SAME option, and `supermajority`/`majority` measure the leading option's share of approvers. An approving voter whose selection is absent or matches no declared option stays in the denominator and credits no option, so a degraded response can only lower the leading share, never raise it. Omit for an ordinary yes/no vote \u2014 behaviour is then unchanged."
6159
6212
  ),
@@ -6726,7 +6779,7 @@ function jobIdSchema(description) {
6726
6779
  }
6727
6780
 
6728
6781
  // src/mcp/jobs/job-idempotency.ts
6729
- import { createHash, randomUUID as randomUUID2 } from "node:crypto";
6782
+ import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
6730
6783
  import { existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync } from "node:fs";
6731
6784
  import { z as z11 } from "zod";
6732
6785
  var logger6 = createLogger({ component: "job-idempotency" });
@@ -6744,7 +6797,7 @@ var IdempotencyIndexEntrySchema = z11.object({
6744
6797
  createdAt: z11.iso.datetime()
6745
6798
  });
6746
6799
  function sha256Hex(input) {
6747
- return createHash("sha256").update(input).digest("hex");
6800
+ return createHash2("sha256").update(input).digest("hex");
6748
6801
  }
6749
6802
  function canonicalJsonStringify(value) {
6750
6803
  if (value === null || typeof value !== "object") return JSON.stringify(value);
@@ -9320,6 +9373,32 @@ async function runSyncConsensusVote(deps, notifier, args) {
9320
9373
  });
9321
9374
  return toolSuccessStructured({ ...result.value });
9322
9375
  }
9376
+ async function prepareVoteArtifact(input) {
9377
+ if (input.artifactPath === void 0) return { ok: true, value: input };
9378
+ const resolved = resolveInsideRoot(input.artifactPath);
9379
+ if (resolved === null) {
9380
+ return {
9381
+ ok: false,
9382
+ error: toolStructuredError({
9383
+ errorCategory: "permission",
9384
+ message: "Path traversal denied: artifactPath must be within the repository root."
9385
+ })
9386
+ };
9387
+ }
9388
+ try {
9389
+ const proposal = await inlineVoteArtifact(
9390
+ input.proposal,
9391
+ resolved,
9392
+ basename2(input.artifactPath)
9393
+ );
9394
+ return { ok: true, value: { ...input, proposal } };
9395
+ } catch (error) {
9396
+ return {
9397
+ ok: false,
9398
+ error: toolStructuredError({ errorCategory: "validation", message: getErrorMessage(error) })
9399
+ };
9400
+ }
9401
+ }
9323
9402
  function createConsensusVoteHandler(deps) {
9324
9403
  const notifier = deps.notifier ?? NOOP_NOTIFIER;
9325
9404
  return async (args, ctx) => {
@@ -9334,31 +9413,32 @@ function createConsensusVoteHandler(deps) {
9334
9413
  const simCheck = checkSimulationAllowed("consensus_vote", ctx.logger);
9335
9414
  if (!simCheck.allowed) return simulationDeniedResult(simCheck.reason);
9336
9415
  }
9337
- const strategy = validationResult.data.strategy ?? "simple_majority";
9338
- const dispatch = resolveDispatch(validationResult.data);
9339
- const modeWarning = deprecatedModeWarning(validationResult.data);
9416
+ const prepared = await prepareVoteArtifact(validationResult.data);
9417
+ if (!prepared.ok) return prepared.error;
9418
+ const input = prepared.value;
9419
+ const strategy = input.strategy ?? "simple_majority";
9420
+ const dispatch = resolveDispatch(input);
9421
+ const modeWarning = deprecatedModeWarning(input);
9340
9422
  ctx.logger.debug("Starting consensus vote", {
9341
9423
  strategy,
9342
- quickMode: validationResult.data.quickMode,
9424
+ quickMode: input.quickMode,
9343
9425
  ...dispatch !== void 0 ? { dispatch } : {}
9344
9426
  });
9345
9427
  notifier.info("consensus_vote", {
9346
9428
  event: "vote_start",
9347
- proposalLength: validationResult.data.proposal.length,
9429
+ proposalLength: input.proposal.length,
9348
9430
  strategy
9349
9431
  });
9350
9432
  if (dispatch === "async") {
9351
- const asyncResult = dispatchAsyncConsensusVote(deps, validationResult.data);
9433
+ const asyncResult = dispatchAsyncConsensusVote(deps, input);
9352
9434
  notifier.info("consensus_vote", {
9353
9435
  event: "vote_dispatched_async",
9354
- proposalLength: validationResult.data.proposal.length,
9436
+ proposalLength: input.proposal.length,
9355
9437
  strategy
9356
9438
  });
9357
9439
  return withWarnings(asyncResult, [modeWarning]);
9358
9440
  }
9359
- return withWarnings(await runSyncConsensusVote(deps, notifier, validationResult.data), [
9360
- modeWarning
9361
- ]);
9441
+ return withWarnings(await runSyncConsensusVote(deps, notifier, input), [modeWarning]);
9362
9442
  };
9363
9443
  }
9364
9444
  var ASYNC_ENVELOPES = {
@@ -9598,6 +9678,7 @@ export {
9598
9678
  resolveAdapter,
9599
9679
  assignPanelSeats,
9600
9680
  collectRealVotes,
9681
+ inlineVoteArtifact,
9601
9682
  VoterProjectInputSchema,
9602
9683
  resolveAndLogVoterProject,
9603
9684
  VotingRoundPhaseSchema,
@@ -9669,4 +9750,4 @@ export {
9669
9750
  CONSENSUS_VOTE_TOOL_SCHEMA,
9670
9751
  registerConsensusVoteTool
9671
9752
  };
9672
- //# sourceMappingURL=chunk-J466LJ35.js.map
9753
+ //# sourceMappingURL=chunk-GN3OLNPH.js.map