@algosuite/vo-mcp 0.2.0-beta.59 → 0.2.0-beta.61

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.
@@ -106643,6 +106643,81 @@ if (process.argv[1] && import.meta.url === pathToFileURL(path.resolve(process.ar
106643
106643
  process.exitCode = exitCode;
106644
106644
  }
106645
106645
 
106646
+ // ../../scripts/virtual-office/code-runner/self-claim-identity.mjs
106647
+ var CODE_TASK_BRANCH_RE = /^(?:refs\/heads\/)?vo\/code-task-([0-9a-z]{8,})-/iu;
106648
+ var CODE_TASK_MARKER_RE = /(?:^|[\s[(])code-task:([0-9a-z][0-9a-z-]{7,63})/iu;
106649
+ var MIN_TASK_ID_TOKEN_LENGTH = 8;
106650
+ var MAX_TASK_ID_LENGTH = 36;
106651
+ var TASK_ID_CHARS_RE = /^[0-9a-z][0-9a-z-]*$/u;
106652
+ function normalizeTaskId(value) {
106653
+ return String(value ?? "").trim().toLowerCase();
106654
+ }
106655
+ function taskIdFromCodeTaskBranch(branch) {
106656
+ const match = CODE_TASK_BRANCH_RE.exec(String(branch ?? "").trim());
106657
+ return match ? match[1].toLowerCase() : "";
106658
+ }
106659
+ function taskIdFromClaimMarker(currentTask) {
106660
+ const match = CODE_TASK_MARKER_RE.exec(String(currentTask ?? ""));
106661
+ return match ? match[1].toLowerCase() : "";
106662
+ }
106663
+ function resolvePublishingTaskId({ taskId = "", branch = "", env = {} } = {}) {
106664
+ const none = { taskId: "", token: "", source: "none", exact: false };
106665
+ const fromBranch = taskIdFromCodeTaskBranch(branch);
106666
+ const branchToken = fromBranch.length >= MIN_TASK_ID_TOKEN_LENGTH ? fromBranch : "";
106667
+ const explicit = normalizeTaskId(taskId);
106668
+ if (explicit.length >= MIN_TASK_ID_TOKEN_LENGTH && TASK_ID_CHARS_RE.test(explicit)) {
106669
+ return { taskId: explicit, token: explicit.slice(0, MIN_TASK_ID_TOKEN_LENGTH), source: "explicit", exact: true };
106670
+ }
106671
+ const fromEnv = normalizeTaskId(env?.VO_CODE_TASK_ID);
106672
+ if (fromEnv.length >= MIN_TASK_ID_TOKEN_LENGTH && TASK_ID_CHARS_RE.test(fromEnv)) {
106673
+ if (branchToken && !fromEnv.startsWith(branchToken)) {
106674
+ return { ...none, source: "conflict" };
106675
+ }
106676
+ return { taskId: fromEnv, token: fromEnv.slice(0, MIN_TASK_ID_TOKEN_LENGTH), source: "env", exact: true };
106677
+ }
106678
+ if (branchToken) return { taskId: branchToken, token: branchToken, source: "branch", exact: false };
106679
+ return none;
106680
+ }
106681
+ function matchesPublishingTask(candidate, publishing) {
106682
+ const value = normalizeTaskId(candidate);
106683
+ if (!publishing?.token) return false;
106684
+ if (value.length < MIN_TASK_ID_TOKEN_LENGTH || value.length > MAX_TASK_ID_LENGTH) return false;
106685
+ if (!TASK_ID_CHARS_RE.test(value)) return false;
106686
+ if (!value.startsWith(publishing.token)) return false;
106687
+ if (publishing.exact) return publishing.taskId.startsWith(value) || value.startsWith(publishing.taskId);
106688
+ return true;
106689
+ }
106690
+ function claimTaskId(conflict, publishing) {
106691
+ if (!publishing?.token) return "";
106692
+ const marked = taskIdFromClaimMarker(conflict?.currentTask);
106693
+ if (marked && matchesPublishingTask(marked, publishing)) return marked;
106694
+ const agentId = String(conflict?.agentId ?? "").trim().toLowerCase();
106695
+ if (!agentId) return "";
106696
+ const index = agentId.lastIndexOf(`-${publishing.token}`);
106697
+ if (index < 0) return "";
106698
+ const tail = agentId.slice(index + 1);
106699
+ return matchesPublishingTask(tail, publishing) ? tail : "";
106700
+ }
106701
+ function claimBelongsToTask(conflict, publishing) {
106702
+ return claimTaskId(conflict, publishing) !== "";
106703
+ }
106704
+ function partitionSelfClaims(conflicts = [], publishing = { token: "" }) {
106705
+ const self2 = [];
106706
+ const foreign = [];
106707
+ for (const conflict of conflicts) {
106708
+ (claimBelongsToTask(conflict, publishing) ? self2 : foreign).push(conflict);
106709
+ }
106710
+ return { self: self2, foreign };
106711
+ }
106712
+ function describeSelfClaimExclusion(self2 = [], publishing = { token: "" }) {
106713
+ if (self2.length === 0) return "";
106714
+ const files = [...new Set(self2.map((conflict) => conflict?.matchedFile || conflict?.file || "?"))];
106715
+ return [
106716
+ `Self-claims ignored: ${self2.length} live whiteboard claim(s) held by this publishing task (task ${publishing.taskId || publishing.token}, matched via ${publishing.source}).`,
106717
+ ...files.map((file) => `- ${file}`)
106718
+ ].join("\n");
106719
+ }
106720
+
106646
106721
  // ../../scripts/ci/check-local-pr-overlap.mjs
106647
106722
  function normalizeFileList(files = []) {
106648
106723
  return [...new Set(files.flatMap((file) => String(file || "").split(/\r?\n/)).map((file) => file.trim().replaceAll("\\", "/")).filter(Boolean))];
@@ -106728,7 +106803,10 @@ function evaluateOverlapGate({
106728
106803
  whiteboardReason = "",
106729
106804
  requireWhiteboard = true,
106730
106805
  allowOverlap = false,
106731
- prLabel = "local branch"
106806
+ prLabel = "local branch",
106807
+ // Never silent: when the publishing task's OWN claims were dropped, say so and
106808
+ // name them. A gate that quietly ignores claims cannot be told from a broken one.
106809
+ selfClaimNote = ""
106732
106810
  } = {}) {
106733
106811
  const files = normalizeFileList(changedFiles);
106734
106812
  const overlaps = classifyOverlaps(files, otherPrs || []);
@@ -106740,6 +106818,7 @@ function evaluateOverlapGate({
106740
106818
  lines.push(`Local overlap gate for ${prLabel}`);
106741
106819
  lines.push(`Changed files: ${files.length}`);
106742
106820
  if (otherPrs?.length) lines.push(`Compared against open PRs: ${otherPrs.length}`);
106821
+ if (selfClaimNote) lines.push(selfClaimNote);
106743
106822
  if (directOverlap || overlaps.packageOverlaps.length || overlaps.sharedDepOverlaps.length) {
106744
106823
  lines.push("");
106745
106824
  lines.push(buildOverlapReport(overlaps, 0));
@@ -106780,6 +106859,32 @@ function evaluateOverlapGate({
106780
106859
  report: lines.join("\n")
106781
106860
  };
106782
106861
  }
106862
+ function decideOverlapGate({
106863
+ changedFiles,
106864
+ otherPrs = [],
106865
+ busResult = { available: true, conflicts: [] },
106866
+ taskId = "",
106867
+ branch = "",
106868
+ env = process.env,
106869
+ requireWhiteboard = true,
106870
+ allowOverlap = false,
106871
+ prLabel = branch || "local branch"
106872
+ } = {}) {
106873
+ const publishing = resolvePublishingTaskId({ taskId, branch, env });
106874
+ const { self: self2, foreign } = partitionSelfClaims(busResult?.conflicts || [], publishing);
106875
+ const evaluated = evaluateOverlapGate({
106876
+ changedFiles,
106877
+ otherPrs,
106878
+ busConflicts: foreign,
106879
+ whiteboardAvailable: busResult?.available !== false,
106880
+ whiteboardReason: busResult?.reason || "",
106881
+ requireWhiteboard,
106882
+ allowOverlap,
106883
+ prLabel,
106884
+ selfClaimNote: describeSelfClaimExclusion(self2, publishing)
106885
+ });
106886
+ return { ...evaluated, publishing, selfClaims: self2 };
106887
+ }
106783
106888
  async function main() {
106784
106889
  const { values: args } = parseArgs({
106785
106890
  options: {
@@ -106788,7 +106893,10 @@ async function main() {
106788
106893
  branch: { type: "string", default: "" },
106789
106894
  stdin: { type: "boolean", default: false },
106790
106895
  "exclude-pr": { type: "string", default: "" },
106791
- "agent-id": { type: "string", default: process.env.AGENT_ID || "" }
106896
+ "agent-id": { type: "string", default: process.env.AGENT_ID || "" },
106897
+ // The publishing code task. Explicit beats VO_CODE_TASK_ID beats the
106898
+ // `vo/code-task-<id8>-…` branch; absent everywhere ⇒ nothing is excluded.
106899
+ "task-id": { type: "string", default: "" }
106792
106900
  }
106793
106901
  });
106794
106902
  const changedFiles = args.stdin ? readFilesFromStdin() : readChangedFiles({ base: args.base, head: args.head });
@@ -106815,12 +106923,12 @@ async function main() {
106815
106923
  return 2;
106816
106924
  }
106817
106925
  const busResult = await checkForConflicts(changedFiles, { excludeAgentId: args["agent-id"] });
106818
- const result = evaluateOverlapGate({
106926
+ const result = decideOverlapGate({
106819
106927
  changedFiles,
106820
106928
  otherPrs,
106821
- busConflicts: busResult.conflicts || [],
106822
- whiteboardAvailable: busResult.available !== false,
106823
- whiteboardReason: busResult.reason || "",
106929
+ busResult,
106930
+ taskId: args["task-id"],
106931
+ branch: args.branch,
106824
106932
  requireWhiteboard: process.env.VO_ALLOW_WHITEBOARD_UNAVAILABLE !== "1",
106825
106933
  allowOverlap: process.env.VO_ALLOW_PR_OVERLAP === "1",
106826
106934
  prLabel: args.branch || "local branch"
@@ -106831,6 +106939,7 @@ async function main() {
106831
106939
  var __test3 = {
106832
106940
  HOSTILE_WORKTREE_GIT_GUARDS,
106833
106941
  gitText,
106942
+ decideOverlapGate,
106834
106943
  evaluateOverlapGate,
106835
106944
  isPrDiffTooLargeError,
106836
106945
  normalizeFileList,
@@ -106842,7 +106951,8 @@ if (process.argv[1] && import.meta.url === pathToFileURL2(path2.resolve(process.
106842
106951
  process.exit(await main());
106843
106952
  }
106844
106953
  export {
106845
- __test3 as __test
106954
+ __test3 as __test,
106955
+ decideOverlapGate
106846
106956
  };
106847
106957
  /*! Bundled license information:
106848
106958