@danmoisan/drm-copilot-mcp 1.1.11 → 1.1.14

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 (66) hide show
  1. package/out/mcp-server.js +368 -209
  2. package/package.json +2 -2
  3. package/resources/claude-customizations/.claude/agents/epic-orchestrator.md +1 -1
  4. package/resources/claude-customizations/.claude/agents/epic-planner.md +4 -1
  5. package/resources/claude-customizations/.claude/agents/parallel-planner.md +18 -1
  6. package/resources/claude-customizations/.claude/agents/pr-author.md +15 -0
  7. package/resources/claude-customizations/.claude/hooks/enforce-completion-consistency.ps1 +16 -8
  8. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-authorization.ps1 +443 -0
  9. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +33 -37
  10. package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +120 -5
  11. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +127 -0
  12. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +172 -24
  13. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +14 -27
  14. package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +66 -5
  15. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +134 -10
  16. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.epic-base-branch.ps1 +37 -8
  17. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.ps1 +3 -1
  18. package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner-helpers.ps1 +332 -0
  19. package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner.ps1 +211 -182
  20. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadius.psm1 +43 -6
  21. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusScheduling.psm1 +486 -0
  22. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusValidation.psm1 +5 -2
  23. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusWriteIntent.psm1 +446 -0
  24. package/resources/claude-customizations/.claude/lib/codex-routing/CodexDeployment.psm1 +1 -0
  25. package/resources/claude-customizations/.claude/lib/worktree-resolution/EpicScopeReadiness.psm1 +176 -0
  26. package/resources/claude-customizations/.claude/lib/worktree-resolution/EpicScopeResolution.psm1 +369 -0
  27. package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeItemResolution.psm1 +392 -0
  28. package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeResolution.psm1 +500 -0
  29. package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeTargetResolution.psm1 +347 -0
  30. package/resources/claude-customizations/.claude/rules/orchestrator-state.md +27 -0
  31. package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +150 -2
  32. package/resources/claude-customizations/.claude/rules/plan-acceptance-gates.md +5 -5
  33. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +12 -0
  34. package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +14 -1
  35. package/resources/claude-customizations/.claude/skills/epic-plan/SKILL.md +15 -0
  36. package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +4 -1
  37. package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +32 -17
  38. package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +39 -6
  39. package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +39 -10
  40. package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +15 -0
  41. package/resources/claude-customizations/.claude/skills/quota-throttling/SKILL.md +221 -0
  42. package/resources/claude-customizations/config/blast-radius.json +14 -1
  43. package/resources/claude-customizations/pack-manifests/core.json +11 -0
  44. package/resources/codex-and-agents-customizations/.agents/skills/codex-model-routing/SKILL.md +13 -14
  45. package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
  46. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate.ps1 +193 -0
  47. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-planning-only.ps1 +15 -5
  48. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-resolution.ps1 +493 -0
  49. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +189 -0
  50. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +172 -24
  51. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +14 -27
  52. package/resources/codex-and-agents-customizations/.codex/scripts/Resolve-CodexDeployment.ps1 +87 -0
  53. package/resources/codex-and-agents-customizations/.codex/scripts/Resolve-CodexTopology.ps1 +96 -0
  54. package/resources/codex-and-agents-customizations/.codex/scripts/codex-routing-cli-common.ps1 +370 -0
  55. package/resources/codex-and-agents-customizations/.codex/scripts/epic-child-launch-contract.ps1 +475 -0
  56. package/resources/codex-and-agents-customizations/.codex/scripts/epic-child-launch-runtime.ps1 +445 -0
  57. package/resources/codex-and-agents-customizations/.codex/scripts/epic-child-persistence-runtime.ps1 +118 -0
  58. package/resources/codex-and-agents-customizations/.codex/scripts/epic-child-sandbox-preflight.ps1 +69 -0
  59. package/resources/codex-and-agents-customizations/.codex/scripts/launch-epic-child-wave.ps1 +471 -0
  60. package/resources/codex-and-agents-customizations/.codex/scripts/post-codex-worktree-session.ps1 +280 -0
  61. package/resources/codex-and-agents-customizations/.codex/scripts/resume-epic-child.ps1 +263 -0
  62. package/resources/codex-and-agents-customizations/.codex-variants/csharp-legacy/agents/csharp-typed-engineer.toml +2 -1
  63. package/resources/codex-and-agents-customizations/pack-manifests/core.json +20 -1
  64. package/resources/lib/codex-routing/CodexDeployment.psm1 +315 -0
  65. package/resources/lib/codex-routing/CodexTopology.psm1 +394 -0
  66. package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +37 -0
package/out/mcp-server.js CHANGED
@@ -16321,12 +16321,14 @@ function resolveCollectCommitContextToolInput(rawInput, fallbackWorkspaceRoot) {
16321
16321
  }
16322
16322
  function resolveCollectPrContextToolInput(rawInput, fallbackWorkspaceRoot) {
16323
16323
  const args = asToolArgumentObject(rawInput);
16324
+ const targetRef = normalizeOptionalText(args["target_ref"], "target_ref");
16324
16325
  return {
16325
16326
  workspaceRoot: normalizeWorkspaceRoot(
16326
16327
  args["workspace_root"],
16327
16328
  fallbackWorkspaceRoot
16328
16329
  ),
16329
- base: normalizeRequiredText(args["base"], "base")
16330
+ base: normalizeRequiredText(args["base"], "base"),
16331
+ ...targetRef === void 0 ? {} : { targetRef }
16330
16332
  };
16331
16333
  }
16332
16334
  function resolveRunCodexNativeConverterToolInput(rawInput, fallbackWorkspaceRoot) {
@@ -17163,6 +17165,10 @@ var REPO_AUTOMATION_TOOL_DEFINITIONS = [
17163
17165
  base: {
17164
17166
  type: "string",
17165
17167
  description: "Explicit base branch or ref used for PR context collection."
17168
+ },
17169
+ target_ref: {
17170
+ type: "string",
17171
+ description: "Optional explicit head ref naming the branch to collect PR context for. When omitted, the invoking session's current HEAD is used as a fallback, and the fallback is recorded on the returned result and in the summary artifact."
17166
17172
  }
17167
17173
  },
17168
17174
  required: ["workspace_root", "base"],
@@ -17880,6 +17886,9 @@ function toMcpToolResult(result) {
17880
17886
  ...result.destinationPath === void 0 ? {} : { destination_path: result.destinationPath },
17881
17887
  ...result.renderedTree === void 0 ? {} : { rendered_tree: result.renderedTree },
17882
17888
  ...result.targetRepository === void 0 ? {} : { target_repository: result.targetRepository },
17889
+ ...result.targetResolution === void 0 ? {} : { target_resolution: result.targetResolution },
17890
+ ...result.resolvedHeadRef === void 0 ? {} : { resolved_head_ref: result.resolvedHeadRef },
17891
+ ...result.resolvedHeadSha === void 0 ? {} : { resolved_head_sha: result.resolvedHeadSha },
17883
17892
  ...result.warnings === void 0 ? {} : { warnings: result.warnings }
17884
17893
  };
17885
17894
  }
@@ -18922,9 +18931,32 @@ var ARTIFACT_DIRECTORY3 = "artifacts/codex-and-agents-customizations";
18922
18931
  var ROOT_FOLDERS = [".codex", ".agents"];
18923
18932
  var PACK_MANIFEST_SUBDIR = "pack-manifests";
18924
18933
  var ROUTING_CONFIG_RELATIVE_PATH = "config/orchestration-routing.json";
18934
+ var VIRTUAL_RESOURCE_PAIRS = [
18935
+ [ROUTING_CONFIG_RELATIVE_PATH, ROUTING_CONFIG_RELATIVE_PATH],
18936
+ [
18937
+ "config/orchestration-handoff-registry.json",
18938
+ "config/orchestration-handoff-registry.json"
18939
+ ],
18940
+ [
18941
+ "config/orchestration-handoff.schema.json",
18942
+ "config/orchestration-handoff.schema.json"
18943
+ ],
18944
+ [
18945
+ ".codex/lib/codex-routing/CodexTopology.psm1",
18946
+ "lib/codex-routing/CodexTopology.psm1"
18947
+ ],
18948
+ [
18949
+ ".codex/lib/codex-routing/CodexDeployment.psm1",
18950
+ "lib/codex-routing/CodexDeployment.psm1"
18951
+ ]
18952
+ ];
18953
+ var VIRTUAL_ROOT_FOLDERS = [
18954
+ "config",
18955
+ ".codex/lib/codex-routing"
18956
+ ];
18925
18957
  var PUBLISHED_ROOT_FOLDERS = [
18926
18958
  ...ROOT_FOLDERS,
18927
- "config"
18959
+ ...VIRTUAL_ROOT_FOLDERS
18928
18960
  ];
18929
18961
  function passthroughRewrite(text2) {
18930
18962
  return [text2, 0, 0, []];
@@ -19010,36 +19042,46 @@ var CodexFilteringFileSystem = class {
19010
19042
  var RoutingConfigFileSystem = class {
19011
19043
  constructor(inner, options) {
19012
19044
  this.inner = inner;
19013
- this.virtualPath = joinPosix4(
19014
- options.sourceRoot,
19015
- ROUTING_CONFIG_RELATIVE_PATH
19045
+ const resourceRoot = parentPosix(options.bundleRoot);
19046
+ this.virtualPaths = new Map(
19047
+ VIRTUAL_RESOURCE_PAIRS.map(
19048
+ ([destination, resource]) => [
19049
+ joinPosix4(options.sourceRoot, destination),
19050
+ joinPosix4(resourceRoot, resource)
19051
+ ]
19052
+ )
19016
19053
  );
19017
- this.virtualRoot = joinPosix4(options.sourceRoot, "config");
19018
- this.resourcePath = joinPosix4(
19019
- parentPosix(options.bundleRoot),
19020
- ROUTING_CONFIG_RELATIVE_PATH
19054
+ this.virtualRoots = new Set(
19055
+ VIRTUAL_ROOT_FOLDERS.map((root) => joinPosix4(options.sourceRoot, root))
19021
19056
  );
19022
19057
  }
19023
19058
  inner;
19024
- virtualPath;
19025
- virtualRoot;
19026
- resourcePath;
19059
+ virtualPaths;
19060
+ virtualRoots;
19061
+ resolve(path16) {
19062
+ return this.virtualPaths.get(normalizePosix(path16)) ?? path16;
19063
+ }
19027
19064
  listFiles(root) {
19028
- if (normalizePosix(root) === this.virtualRoot) {
19029
- return this.inner.isFile(this.resourcePath) ? [this.virtualPath] : [];
19065
+ const normalizedRoot = normalizePosix(root);
19066
+ if (!this.virtualRoots.has(normalizedRoot)) {
19067
+ return this.inner.listFiles(root);
19030
19068
  }
19031
- return this.inner.listFiles(root);
19069
+ const listed = [];
19070
+ for (const [virtualPath, resourcePath] of this.virtualPaths) {
19071
+ if (parentPosix(virtualPath) === normalizedRoot && this.inner.isFile(resourcePath)) {
19072
+ listed.push(virtualPath);
19073
+ }
19074
+ }
19075
+ return listed;
19032
19076
  }
19033
19077
  isDir(path16) {
19034
19078
  return this.inner.isDir(path16);
19035
19079
  }
19036
19080
  isFile(path16) {
19037
- return normalizePosix(path16) === this.virtualPath ? this.inner.isFile(this.resourcePath) : this.inner.isFile(path16);
19081
+ return this.inner.isFile(this.resolve(path16));
19038
19082
  }
19039
19083
  readTextFile(path16) {
19040
- return this.inner.readTextFile(
19041
- normalizePosix(path16) === this.virtualPath ? this.resourcePath : path16
19042
- );
19084
+ return this.inner.readTextFile(this.resolve(path16));
19043
19085
  }
19044
19086
  writeTextFile(path16, content) {
19045
19087
  this.inner.writeTextFile(path16, content);
@@ -19686,7 +19728,10 @@ var CARRIED_KEYS = [
19686
19728
  "shared_surface_globs",
19687
19729
  "over_breadth_fraction",
19688
19730
  "mandate_reads",
19689
- "mergeable_paths"
19731
+ "mergeable_paths",
19732
+ "conflict_tolerance",
19733
+ "write_intent_extraction",
19734
+ "path_roots"
19690
19735
  ];
19691
19736
  var BlastRadiusDeriveError = class extends Error {
19692
19737
  /** Destination-relative path of the document that failed to parse. */
@@ -19793,6 +19838,9 @@ function deriveDestinationModuleMap(observations, sourceDocumentText) {
19793
19838
  shared_surface_globs: source[CARRIED_KEYS[2]],
19794
19839
  mandate_reads: source[CARRIED_KEYS[4]],
19795
19840
  mergeable_paths: source[CARRIED_KEYS[5]],
19841
+ conflict_tolerance: source[CARRIED_KEYS[6]],
19842
+ write_intent_extraction: source[CARRIED_KEYS[7]],
19843
+ path_roots: source[CARRIED_KEYS[8]],
19796
19844
  modules,
19797
19845
  over_breadth_fraction: source[CARRIED_KEYS[3]]
19798
19846
  };
@@ -31774,8 +31822,8 @@ function isInsidersSession(envLookup) {
31774
31822
  return false;
31775
31823
  }
31776
31824
  function resolveCodeCli(whichLookup, envLookup) {
31777
- const candidateNames = isInsidersSession(envLookup) ? ["code-insiders", "code"] : ["code", "code-insiders"];
31778
- for (const candidateName of candidateNames) {
31825
+ const candidateNames2 = isInsidersSession(envLookup) ? ["code-insiders", "code"] : ["code", "code-insiders"];
31826
+ for (const candidateName of candidateNames2) {
31779
31827
  const resolvedCommand = whichLookup(candidateName);
31780
31828
  if (resolvedCommand) {
31781
31829
  return resolvedCommand;
@@ -31894,7 +31942,56 @@ function newPotentialBugEntryServiceCall(input) {
31894
31942
  }
31895
31943
 
31896
31944
  // ../../extensions/drm-copilot/src/lib/pr-context/pr-context-service-call.ts
31945
+ var import_node_path2 = require("node:path");
31946
+
31947
+ // ../../extensions/drm-copilot/src/lib/executable-resolver.ts
31948
+ var import_node_fs = require("node:fs");
31897
31949
  var import_node_path = require("node:path");
31950
+ var DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD";
31951
+ function splitNonEmpty(value, delimiter4) {
31952
+ return value.split(delimiter4).filter((entry) => entry.length > 0);
31953
+ }
31954
+ function candidateNames(name, platform, pathExtValue) {
31955
+ if (platform !== "win32") {
31956
+ return [name];
31957
+ }
31958
+ const extensions = splitNonEmpty(
31959
+ pathExtValue === void 0 || pathExtValue === "" ? DEFAULT_PATHEXT : pathExtValue,
31960
+ ";"
31961
+ );
31962
+ const lowerName = name.toLowerCase();
31963
+ const hasKnownExtension = extensions.some(
31964
+ (ext) => lowerName.endsWith(ext.toLowerCase())
31965
+ );
31966
+ const withExtensions = extensions.map((ext) => `${name}${ext}`);
31967
+ return hasKnownExtension ? [name, ...withExtensions] : withExtensions;
31968
+ }
31969
+ function resolveExecutableOnPath(options) {
31970
+ const { name, pathValue, pathExtValue, platform, exists } = options;
31971
+ if (pathValue === void 0 || pathValue === "") {
31972
+ return void 0;
31973
+ }
31974
+ const pathApi = platform === "win32" ? import_node_path.win32 : import_node_path.posix;
31975
+ const names = candidateNames(name, platform, pathExtValue);
31976
+ for (const directory of splitNonEmpty(pathValue, pathApi.delimiter)) {
31977
+ for (const candidateName of names) {
31978
+ const candidate = pathApi.join(directory, candidateName);
31979
+ if (exists(candidate)) {
31980
+ return candidate;
31981
+ }
31982
+ }
31983
+ }
31984
+ return void 0;
31985
+ }
31986
+ function defaultWhichGh() {
31987
+ return resolveExecutableOnPath({
31988
+ name: "gh",
31989
+ pathValue: process.env["PATH"],
31990
+ pathExtValue: process.env["PATHEXT"],
31991
+ platform: process.platform,
31992
+ exists: import_node_fs.existsSync
31993
+ });
31994
+ }
31898
31995
 
31899
31996
  // ../../extensions/drm-copilot/src/lib/pr-context/models.ts
31900
31997
  var SECTION_LINE = "===== {title} =====";
@@ -31910,6 +32007,9 @@ var CONVENTIONAL_TYPES = [
31910
32007
  "ci",
31911
32008
  "style"
31912
32009
  ];
32010
+ var ISSUE_REFERENCE_PATTERN = /(?<!\w)#\d+(?!\w)/u;
32011
+ var AUTOCLOSE_UNVERIFIED_ANNOTATION = "Unverified: the issues listed above come from feature metadata only and were not checked against GitHub (GitHub CLI unavailable).";
32012
+ var AUTOCLOSE_PENDING_NOT_OPEN_TEXT = "None (deterministic pending issue is not an open issue)";
31913
32013
  function section(title) {
31914
32014
  return "\n" + SECTION_LINE.replace("{title}", title) + "\n";
31915
32015
  }
@@ -31973,6 +32073,15 @@ function formatList(values, emptyText) {
31973
32073
  }
31974
32074
  return valuesList.map((item) => `- ${item}`).join("\n");
31975
32075
  }
32076
+ function compareCodePoint(left, right) {
32077
+ if (left < right) {
32078
+ return -1;
32079
+ }
32080
+ if (left > right) {
32081
+ return 1;
32082
+ }
32083
+ return 0;
32084
+ }
31976
32085
 
31977
32086
  // ../../extensions/drm-copilot/src/lib/pr-context/git-client.ts
31978
32087
  var GitClient = class {
@@ -32167,15 +32276,6 @@ function extractClosingNumbers(raw) {
32167
32276
  function sortedSet(values) {
32168
32277
  return [...new Set(values)].sort(compareCodePoint);
32169
32278
  }
32170
- function compareCodePoint(left, right) {
32171
- if (left < right) {
32172
- return -1;
32173
- }
32174
- if (left > right) {
32175
- return 1;
32176
- }
32177
- return 0;
32178
- }
32179
32279
  function authorLogin(record3, key) {
32180
32280
  const raw = record3[key];
32181
32281
  if (isRecord5(raw)) {
@@ -32658,6 +32758,140 @@ function isRecord5(value) {
32658
32758
  return typeof value === "object" && value !== null && !Array.isArray(value);
32659
32759
  }
32660
32760
 
32761
+ // ../../extensions/drm-copilot/src/lib/pr-context/autoclose.ts
32762
+ function classifyReferences(options) {
32763
+ const {
32764
+ gh,
32765
+ ghAvailable,
32766
+ featureIssueRefs,
32767
+ branchRefs,
32768
+ pathRefs,
32769
+ referencedIssuesSet,
32770
+ referencedPrsSet,
32771
+ invalidRefsSet
32772
+ } = options;
32773
+ if (ghAvailable) {
32774
+ for (const ref of featureIssueRefs) {
32775
+ classifyOne(
32776
+ gh,
32777
+ ref,
32778
+ referencedIssuesSet,
32779
+ referencedPrsSet,
32780
+ invalidRefsSet
32781
+ );
32782
+ }
32783
+ for (const ref of [...branchRefs, ...pathRefs]) {
32784
+ classifyOne(
32785
+ gh,
32786
+ ref,
32787
+ referencedIssuesSet,
32788
+ referencedPrsSet,
32789
+ invalidRefsSet
32790
+ );
32791
+ }
32792
+ } else {
32793
+ for (const ref of featureIssueRefs) {
32794
+ referencedIssuesSet.add(formatRef(ref));
32795
+ }
32796
+ for (const ref of [...branchRefs, ...pathRefs]) {
32797
+ referencedIssuesSet.add(formatRef(ref));
32798
+ }
32799
+ }
32800
+ }
32801
+ function classifyOne(gh, ref, issuesSet, prsSet, invalidSet) {
32802
+ const formatted = formatRef(ref);
32803
+ const entity = gh.classifyEntity(ref.replace(/^#+/u, ""));
32804
+ if (entity === "issue") {
32805
+ issuesSet.add(formatted);
32806
+ } else if (entity === "pull") {
32807
+ prsSet.add(formatted);
32808
+ } else {
32809
+ invalidSet.add(formatted);
32810
+ }
32811
+ }
32812
+ function formatRef(ref) {
32813
+ return ref.startsWith("#") ? ref : `#${ref}`;
32814
+ }
32815
+ function selectPendingPrimary(options) {
32816
+ const { gh, ghAvailable, pendingPrimary } = options;
32817
+ if (!ghAvailable) {
32818
+ return {
32819
+ kept: [...pendingPrimary],
32820
+ excluded: false,
32821
+ fetchedDetails: /* @__PURE__ */ new Map()
32822
+ };
32823
+ }
32824
+ const kept = [];
32825
+ const fetchedDetails = /* @__PURE__ */ new Map();
32826
+ let excluded = false;
32827
+ for (const ref of pendingPrimary) {
32828
+ const numberRef = normalizeReference(ref);
32829
+ if (gh.classifyEntity(numberRef) !== "issue") {
32830
+ excluded = true;
32831
+ continue;
32832
+ }
32833
+ const details = gh.issueDetails(numberRef);
32834
+ fetchedDetails.set(ref, details);
32835
+ if (details.state.toLowerCase() === "open") {
32836
+ kept.push(ref);
32837
+ } else {
32838
+ excluded = true;
32839
+ }
32840
+ }
32841
+ return { kept, excluded, fetchedDetails };
32842
+ }
32843
+ function buildCloseCandidatesSection(params) {
32844
+ const { verified, authorAsserted, referenced, verifiedReason, authorReason } = params;
32845
+ const authorAutoClose = [...new Set(authorAsserted)].sort(compareCodePoint);
32846
+ const closing = /* @__PURE__ */ new Set([...verified, ...authorAsserted]);
32847
+ const referencedOnly = [...new Set(referenced)].filter((ref) => !closing.has(ref)).sort(compareCodePoint);
32848
+ return [
32849
+ section("Close candidates"),
32850
+ "Auto-close issues (verified from GitHub PR metadata):",
32851
+ formatList(verified, verifiedReason),
32852
+ "",
32853
+ "Auto-close issues (author asserted):",
32854
+ formatList(authorAutoClose, authorReason),
32855
+ "",
32856
+ "Referenced issues (detected):",
32857
+ formatList(referencedOnly, "(none)")
32858
+ ].join("\n");
32859
+ }
32860
+ function buildIssuesToAutocloseSection(params) {
32861
+ const {
32862
+ verified,
32863
+ pendingPrimary,
32864
+ readinessSignals,
32865
+ ghAvailable = true,
32866
+ pendingPrimaryExcluded = false
32867
+ } = params;
32868
+ const ordered = [];
32869
+ for (const issue2 of [...verified, ...pendingPrimary]) {
32870
+ if (issue2 && !ordered.includes(issue2)) {
32871
+ ordered.push(issue2);
32872
+ }
32873
+ }
32874
+ let body;
32875
+ if (ordered.length > 0) {
32876
+ body = formatList(ordered, "(none)");
32877
+ if (!ghAvailable) {
32878
+ body = `${body}
32879
+ ${AUTOCLOSE_UNVERIFIED_ANNOTATION}`;
32880
+ }
32881
+ } else if (!ghAvailable) {
32882
+ body = "None (GitHub CLI unavailable; closing issues not verified)";
32883
+ } else if (pendingPrimaryExcluded) {
32884
+ body = AUTOCLOSE_PENDING_NOT_OPEN_TEXT;
32885
+ } else if (readinessSignals.some((signal) => signal === "PASS")) {
32886
+ body = "None (no verified closing issues and no deterministic pending issue)";
32887
+ } else {
32888
+ body = "None (no verified closing issues and readiness not PASS)";
32889
+ }
32890
+ return [section("Issues to autoclose (verified or pending)"), body].join(
32891
+ "\n"
32892
+ );
32893
+ }
32894
+
32661
32895
  // ../../extensions/drm-copilot/src/lib/pr-context/render-pr-helpers.ts
32662
32896
  var DEFAULT_BASE_CANDIDATES = [
32663
32897
  "origin/main",
@@ -32724,14 +32958,14 @@ function extensionSummary(files) {
32724
32958
  const ext = suffix2 ? suffix2 : "(noext)";
32725
32959
  counts.set(ext, (counts.get(ext) ?? 0) + 1);
32726
32960
  }
32727
- const lines = [...counts.keys()].sort(compareCodePoint2).map((key) => `${padCount(counts.get(key))} ${key}`);
32961
+ const lines = [...counts.keys()].sort(compareCodePoint).map((key) => `${padCount(counts.get(key))} ${key}`);
32728
32962
  return lines.join("\n");
32729
32963
  }
32730
32964
  function extractIssueReferences(text2) {
32731
32965
  if (!text2) {
32732
32966
  return [];
32733
32967
  }
32734
- const matches = text2.match(/(?<!\w)#\d+|\b[A-Z][A-Z0-9]+-\d+\b/gu) ?? [];
32968
+ const matches = text2.match(new RegExp(ISSUE_REFERENCE_PATTERN, "gu")) ?? [];
32735
32969
  const seen = /* @__PURE__ */ new Set();
32736
32970
  const ordered = [];
32737
32971
  for (const item of matches) {
@@ -32751,7 +32985,7 @@ function extractMergePrNumbers(subjects) {
32751
32985
  numbers.add(`#${match[1]}`);
32752
32986
  }
32753
32987
  }
32754
- return [...numbers].sort(compareCodePoint2);
32988
+ return [...numbers].sort(compareCodePoint);
32755
32989
  }
32756
32990
  function summarizeConventionalCommits(subjects) {
32757
32991
  const counts = /* @__PURE__ */ new Map();
@@ -32775,43 +33009,6 @@ function summarizeConventionalCommits(subjects) {
32775
33009
  }
32776
33010
  return nonZero.map(([name, value]) => `${padName(name)} : ${value}`).join("\n");
32777
33011
  }
32778
- function buildCloseCandidatesSection(params) {
32779
- const { verified, authorAsserted, referenced, verifiedReason, authorReason } = params;
32780
- const allAutoClose = /* @__PURE__ */ new Set([...verified, ...authorAsserted, ...referenced]);
32781
- const authorAutoClose = [...allAutoClose].sort(compareCodePoint2);
32782
- const referencedOnly = referenced.filter((ref) => !allAutoClose.has(ref)).filter((ref, index, arr) => arr.indexOf(ref) === index).sort(compareCodePoint2);
32783
- return [
32784
- section("Close candidates"),
32785
- "Auto-close issues (verified from GitHub PR metadata):",
32786
- formatList(verified, verifiedReason),
32787
- "",
32788
- "Auto-close issues (author asserted):",
32789
- formatList(authorAutoClose, authorReason),
32790
- "",
32791
- "Referenced issues (detected):",
32792
- formatList(referencedOnly, "(none)")
32793
- ].join("\n");
32794
- }
32795
- function buildIssuesToAutocloseSection(params) {
32796
- const { verified, pendingPrimary, readinessSignals } = params;
32797
- const ordered = [];
32798
- for (const issue2 of [...verified, ...pendingPrimary]) {
32799
- if (issue2 && !ordered.includes(issue2)) {
32800
- ordered.push(issue2);
32801
- }
32802
- }
32803
- let body;
32804
- if (ordered.length > 0) {
32805
- body = formatList(ordered, "(none)");
32806
- } else if (readinessSignals.some((signal) => signal === "PASS")) {
32807
- body = "None (no verified closing issues and no deterministic pending issue)";
32808
- } else {
32809
- body = "None (no verified closing issues and readiness not PASS)";
32810
- }
32811
- return [section("Issues to autoclose (verified or pending)"), body].join(
32812
- "\n"
32813
- );
32814
- }
32815
33012
  function extractChangedPaths(contextText) {
32816
33013
  const paths = [];
32817
33014
  let capture = false;
@@ -32852,15 +33049,6 @@ function padName(name) {
32852
33049
  function isDigits(value) {
32853
33050
  return value.length > 0 && /^\d+$/u.test(value);
32854
33051
  }
32855
- function compareCodePoint2(left, right) {
32856
- if (left < right) {
32857
- return -1;
32858
- }
32859
- if (left > right) {
32860
- return 1;
32861
- }
32862
- return 0;
32863
- }
32864
33052
  function splitLines4(value) {
32865
33053
  if (value === "") {
32866
33054
  return [];
@@ -33087,16 +33275,7 @@ function errorMessage(exc) {
33087
33275
  return exc instanceof Error ? exc.message : String(exc);
33088
33276
  }
33089
33277
  function sortedSet2(values) {
33090
- return [...new Set(values)].sort(compareCodePoint3);
33091
- }
33092
- function compareCodePoint3(left, right) {
33093
- if (left < right) {
33094
- return -1;
33095
- }
33096
- if (left > right) {
33097
- return 1;
33098
- }
33099
- return 0;
33278
+ return [...new Set(values)].sort(compareCodePoint);
33100
33279
  }
33101
33280
  function splitLines5(value) {
33102
33281
  if (value === "") {
@@ -33139,7 +33318,7 @@ function extractIssueReferences2(text2) {
33139
33318
  if (!text2) {
33140
33319
  return [];
33141
33320
  }
33142
- const matches = text2.match(/(?<!\w)#\d+|\b[A-Z][A-Z0-9]+-\d+\b/gu) ?? [];
33321
+ const matches = text2.match(new RegExp(ISSUE_REFERENCE_PATTERN, "gu")) ?? [];
33143
33322
  const seen = /* @__PURE__ */ new Set();
33144
33323
  const ordered = [];
33145
33324
  for (const item of matches) {
@@ -33184,7 +33363,7 @@ function readText(fs12, path16) {
33184
33363
  return fs12.exists(path16) ? fs12.readTextFile(path16) : "";
33185
33364
  }
33186
33365
  function latestGlobPath(fs12, directory, pattern) {
33187
- const matches = [...fs12.glob(directory, pattern)].sort(compareCodePoint4);
33366
+ const matches = [...fs12.glob(directory, pattern)].sort(compareCodePoint);
33188
33367
  return matches.length > 0 ? matches[matches.length - 1] : null;
33189
33368
  }
33190
33369
  function verificationText(planText) {
@@ -33228,7 +33407,7 @@ function parseReadinessValue(text2) {
33228
33407
  }
33229
33408
  function resolveReadinessSignal(fs12, featureDir) {
33230
33409
  const auditFiles = [...fs12.glob(featureDir, "feature-audit.*.md")].sort(
33231
- compareCodePoint4
33410
+ compareCodePoint
33232
33411
  );
33233
33412
  for (let index = auditFiles.length - 1; index >= 0; index -= 1) {
33234
33413
  const auditPath = auditFiles[index];
@@ -33247,15 +33426,6 @@ function relativeToPosix6(root, path16) {
33247
33426
  }
33248
33427
  return normalized.replace(/^\/+/u, "");
33249
33428
  }
33250
- function compareCodePoint4(left, right) {
33251
- if (left < right) {
33252
- return -1;
33253
- }
33254
- if (left > right) {
33255
- return 1;
33256
- }
33257
- return 0;
33258
- }
33259
33429
  function escapeRegExp4(value) {
33260
33430
  return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
33261
33431
  }
@@ -33285,7 +33455,7 @@ function discoverCanonicalEvidenceFiles(fs12, root, feature) {
33285
33455
  }
33286
33456
  }
33287
33457
  }
33288
- return [...discovered].sort(compareCodePoint5);
33458
+ return [...discovered].sort(compareCodePoint);
33289
33459
  }
33290
33460
  function parseVerificationEvidenceMarkdown(params) {
33291
33461
  const { feature, sourceFile, markdown } = params;
@@ -33381,15 +33551,6 @@ function relativeToPosix7(root, absolute) {
33381
33551
  }
33382
33552
  return normalized.replace(/^\/+/u, "");
33383
33553
  }
33384
- function compareCodePoint5(left, right) {
33385
- if (left < right) {
33386
- return -1;
33387
- }
33388
- if (left > right) {
33389
- return 1;
33390
- }
33391
- return 0;
33392
- }
33393
33554
  function splitLines6(value) {
33394
33555
  if (value === "") {
33395
33556
  return [];
@@ -33429,7 +33590,7 @@ function gatherFeatureExcerpts2(fs12, root, changedFiles) {
33429
33590
  const excerpts = [];
33430
33591
  const baseDir = `${normalizedRoot}/docs/features/active`;
33431
33592
  const promotedDir = `${normalizedRoot}/docs/features/potential/promoted`;
33432
- for (const feature of [...features].sort(compareCodePoint4)) {
33593
+ for (const feature of [...features].sort(compareCodePoint)) {
33433
33594
  const featureDir = resolveFeatureDir2(fs12, baseDir, feature);
33434
33595
  const promotedFeatureDir = resolveFeatureDir2(fs12, promotedDir, feature);
33435
33596
  if (featureDir === null && promotedFeatureDir === null) {
@@ -33583,7 +33744,7 @@ function buildContextFiles(params) {
33583
33744
  feature
33584
33745
  );
33585
33746
  return [.../* @__PURE__ */ new Set([...contextFiles, ...evidenceContextFiles])].sort(
33586
- compareCodePoint4
33747
+ compareCodePoint
33587
33748
  );
33588
33749
  }
33589
33750
 
@@ -33884,6 +34045,29 @@ function bucketText(name, entries) {
33884
34045
  ];
33885
34046
  return lines.join("\n");
33886
34047
  }
34048
+ function buildBaseHeadSection(ctx, head, workspaceRoot) {
34049
+ const lines = [
34050
+ section("Base/Head"),
34051
+ `Base ref (requested): ${ctx.baseRef ?? "(default)"}`,
34052
+ `Base ref (resolved): ${ctx.resolvedBase ?? "(unknown)"} @ ${ctx.baseSha ?? "(unknown)"}`,
34053
+ `Head ref (resolved): ${ctx.headRef ?? head ?? "(unknown)"} @ ${ctx.headSha ?? "(unknown)"}`,
34054
+ renderHeadRefSourceLine(head, workspaceRoot),
34055
+ `Merge base: ${ctx.mergeBase ?? "(unknown)"}`,
34056
+ `Range: ${ctx.revRange ?? "(unknown)"}`
34057
+ ];
34058
+ if (ctx.baseRef && ctx.resolvedBase && !ctx.resolvedBase.startsWith("origin/")) {
34059
+ lines.push(
34060
+ `WARNING: Requested base is local and may be stale; prefer origin/${ctx.baseRef}`
34061
+ );
34062
+ }
34063
+ return lines;
34064
+ }
34065
+ function renderHeadRefSourceLine(head, workspaceRoot) {
34066
+ if (head !== null) {
34067
+ return `Head ref (source): explicit target '${head}'`;
34068
+ }
34069
+ return `Head ref (source): session fallback (no target_ref supplied; derived from workspace root '${workspaceRoot}')`;
34070
+ }
33887
34071
  function parseSection3(markdown, heading) {
33888
34072
  const escaped = heading.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
33889
34073
  const pattern = new RegExp(
@@ -33996,11 +34180,11 @@ function collectPrContext(options) {
33996
34180
  referencedPrsSet,
33997
34181
  invalidRefsSet
33998
34182
  });
33999
- const referencedIssues = [...referencedIssuesSet].sort(compareCodePoint6);
34000
- const referencedPrs = [...referencedPrsSet].sort(compareCodePoint6);
34001
- const invalidRefs = [...invalidRefsSet].sort(compareCodePoint6);
34002
- let authorAsserted = [];
34003
- const authorReasonInitial = "None (author has not asserted autoclose issues)";
34183
+ const referencedIssues = [...referencedIssuesSet].sort(compareCodePoint);
34184
+ const referencedPrs = [...referencedPrsSet].sort(compareCodePoint);
34185
+ const invalidRefs = [...invalidRefsSet].sort(compareCodePoint);
34186
+ const authorAsserted = [];
34187
+ const authorReason = "None (author has not asserted autoclose issues)";
34004
34188
  const verified = ghAvailable ? contextResult.verifiedClosing : [];
34005
34189
  let verifiedReason;
34006
34190
  if (!ghAvailable) {
@@ -34012,11 +34196,6 @@ function collectPrContext(options) {
34012
34196
  } else {
34013
34197
  verifiedReason = "(verified from GitHub PR metadata)";
34014
34198
  }
34015
- let authorReason = authorReasonInitial;
34016
- if (referencedIssues.length > 0) {
34017
- authorAsserted = sortedSet3([...authorAsserted, ...referencedIssues]);
34018
- authorReason = "Detected issue references (classified)";
34019
- }
34020
34199
  const pendingPrimary = [];
34021
34200
  for (const featureDoc of featureDocs) {
34022
34201
  if (featureDoc.readinessSignal !== "PASS") {
@@ -34032,20 +34211,25 @@ function collectPrContext(options) {
34032
34211
  const readinessSignals = sortedSet3(
34033
34212
  featureDocs.map((doc) => doc.readinessSignal).filter((signal) => Boolean(signal))
34034
34213
  );
34214
+ const selection = selectPendingPrimary({ gh, ghAvailable, pendingPrimary });
34035
34215
  const issuesToAutocloseSection = buildIssuesToAutocloseSection({
34036
34216
  verified,
34037
- pendingPrimary,
34038
- readinessSignals
34217
+ pendingPrimary: selection.kept,
34218
+ readinessSignals,
34219
+ ghAvailable,
34220
+ pendingPrimaryExcluded: selection.excluded
34039
34221
  });
34040
34222
  const issuesToFetch = sortedSet3([
34041
34223
  ...verified,
34042
- ...authorAsserted,
34043
- ...referencedIssues
34224
+ ...referencedIssues,
34225
+ ...selection.kept
34044
34226
  ]);
34045
34227
  const issueDetails = [];
34046
34228
  if (ghAvailable) {
34047
34229
  for (const ref of issuesToFetch) {
34048
- issueDetails.push(gh.issueDetails(ref.replace(/^#+/u, "")));
34230
+ issueDetails.push(
34231
+ selection.fetchedDetails.get(ref) ?? gh.issueDetails(ref.replace(/^#+/u, ""))
34232
+ );
34049
34233
  }
34050
34234
  }
34051
34235
  const prDetailsList = [];
@@ -34141,73 +34325,11 @@ function collectPrContext(options) {
34141
34325
  head
34142
34326
  };
34143
34327
  }
34144
- function classifyReferences(options) {
34145
- const {
34146
- gh,
34147
- ghAvailable,
34148
- featureIssueRefs,
34149
- branchRefs,
34150
- pathRefs,
34151
- referencedIssuesSet,
34152
- referencedPrsSet,
34153
- invalidRefsSet
34154
- } = options;
34155
- if (ghAvailable) {
34156
- for (const ref of featureIssueRefs) {
34157
- classifyOne(
34158
- gh,
34159
- ref,
34160
- referencedIssuesSet,
34161
- referencedPrsSet,
34162
- invalidRefsSet
34163
- );
34164
- }
34165
- for (const ref of [...branchRefs, ...pathRefs]) {
34166
- classifyOne(
34167
- gh,
34168
- ref,
34169
- referencedIssuesSet,
34170
- referencedPrsSet,
34171
- invalidRefsSet
34172
- );
34173
- }
34174
- } else {
34175
- for (const ref of featureIssueRefs) {
34176
- referencedIssuesSet.add(formatRef(ref));
34177
- }
34178
- for (const ref of [...branchRefs, ...pathRefs]) {
34179
- referencedIssuesSet.add(formatRef(ref));
34180
- }
34181
- }
34182
- }
34183
- function classifyOne(gh, ref, issuesSet, prsSet, invalidSet) {
34184
- const formatted = formatRef(ref);
34185
- const entity = gh.classifyEntity(ref.replace(/^#+/u, ""));
34186
- if (entity === "issue") {
34187
- issuesSet.add(formatted);
34188
- } else if (entity === "pull") {
34189
- prsSet.add(formatted);
34190
- } else {
34191
- invalidSet.add(formatted);
34192
- }
34193
- }
34194
- function formatRef(ref) {
34195
- return ref.startsWith("#") ? ref : `#${ref}`;
34196
- }
34197
34328
  function errorMessage2(exc) {
34198
34329
  return exc instanceof Error ? exc.message : String(exc);
34199
34330
  }
34200
34331
  function sortedSet3(values) {
34201
- return [...new Set(values)].sort(compareCodePoint6);
34202
- }
34203
- function compareCodePoint6(left, right) {
34204
- if (left < right) {
34205
- return -1;
34206
- }
34207
- if (left > right) {
34208
- return 1;
34209
- }
34210
- return 0;
34332
+ return [...new Set(values)].sort(compareCodePoint);
34211
34333
  }
34212
34334
 
34213
34335
  // ../../extensions/drm-copilot/src/lib/pr-context/collector-output.ts
@@ -34273,18 +34395,8 @@ function buildSummaryText(collected, fs12, appendixPath, generatedSection) {
34273
34395
  section("GitHub CLI status"),
34274
34396
  ghStatusText,
34275
34397
  intentBlock,
34276
- section("Base/Head"),
34277
- `Base ref (requested): ${ctx.baseRef ?? "(default)"}`,
34278
- `Base ref (resolved): ${ctx.resolvedBase ?? "(unknown)"} @ ${ctx.baseSha ?? "(unknown)"}`,
34279
- `Head ref (resolved): ${ctx.headRef ?? collected.head ?? "(unknown)"} @ ${ctx.headSha ?? "(unknown)"}`,
34280
- `Merge base: ${ctx.mergeBase ?? "(unknown)"}`,
34281
- `Range: ${ctx.revRange ?? "(unknown)"}`
34398
+ ...buildBaseHeadSection(ctx, collected.head, collected.resolvedRoot)
34282
34399
  ];
34283
- if (ctx.baseRef && ctx.resolvedBase && !ctx.resolvedBase.startsWith("origin/")) {
34284
- summarySections.push(
34285
- `WARNING: Requested base is local and may be stale; prefer origin/${ctx.baseRef}`
34286
- );
34287
- }
34288
34400
  const issueDigests = collected.issueDetails.map((detail) => issueDigest(detail)).join("\n\n");
34289
34401
  const prDigests = collected.prDetailsList.map((detail) => prDigest(detail)).join("\n\n");
34290
34402
  const featureSummary = buildFeatureSummary(collected.featureDocs);
@@ -34405,7 +34517,16 @@ function collectAndWrite(options) {
34405
34517
  const log = options.log ?? (() => void 0);
34406
34518
  log(`Wrote context summary to: ${options.out}`);
34407
34519
  log(`Wrote context appendix to: ${options.appendixOut}`);
34408
- return { summaryText, appendixText };
34520
+ const ctx = collected.contextResult;
34521
+ return {
34522
+ summaryText,
34523
+ appendixText,
34524
+ mergeBase: ctx.mergeBase,
34525
+ headSha: ctx.headSha,
34526
+ resolvedHeadRef: ctx.headRef ?? collected.head ?? null,
34527
+ resolvedBase: ctx.resolvedBase,
34528
+ changedFileCount: collected.bucketCore.length + collected.bucketRenames.length + collected.bucketDocs.length
34529
+ };
34409
34530
  }
34410
34531
  function resolveGhStatusText(collected) {
34411
34532
  let ghStatusText = collected.ghStatusOverride || collected.ghStatusMessage || "GitHub CLI authenticated.";
@@ -34474,6 +34595,25 @@ function parentDir(path16) {
34474
34595
  return index <= 0 ? "" : normalized.slice(0, index);
34475
34596
  }
34476
34597
 
34598
+ // ../../extensions/drm-copilot/src/lib/pr-context/diff-emptiness.ts
34599
+ function classifyPrContextDiffState(input) {
34600
+ if (input.mergeBase === null || input.headSha === null) {
34601
+ const attemptedHead = input.attemptedHeadRef ?? "(session HEAD)";
34602
+ const underlyingFailure = input.resolvedBase === null ? `base '${input.requestedBase}' did not resolve to a commit` : `head '${attemptedHead}' did not resolve to a commit`;
34603
+ return {
34604
+ kind: "refs-unresolved",
34605
+ message: `Could not resolve PR context refs for requested base '${input.requestedBase}' and attempted head '${attemptedHead}': ${underlyingFailure}. Correct the 'base' argument (or 'target_ref', if supplied) and retry.`
34606
+ };
34607
+ }
34608
+ if (input.changedFileCount === 0) {
34609
+ return {
34610
+ kind: "refs-resolved-no-change",
34611
+ message: `PR context diff is empty: resolved head ref '${input.resolvedHeadRef ?? "(unknown)"}' at head SHA '${input.headSha}' has no changes relative to merge base '${input.mergeBase}' and resolved base '${input.resolvedBase ?? "(unknown)"}'. This guard cannot detect a wrong target whose branch has commits ahead of the base; supply or correct 'target_ref' if this diff was not expected to be empty. The working-tree sections and the current-PR lookup remain scoped to 'workspace_root' even when 'target_ref' is supplied.`
34612
+ };
34613
+ }
34614
+ return { kind: "populated" };
34615
+ }
34616
+
34477
34617
  // ../../extensions/drm-copilot/src/lib/pr-context/pr-context-service-call.ts
34478
34618
  var SUMMARY_OUT = "artifacts/pr_context.summary.txt";
34479
34619
  var APPENDIX_OUT = "artifacts/pr_context.appendix.txt";
@@ -34496,10 +34636,10 @@ function verifyWrittenArtifact(fileSystem, artifactPath, expected) {
34496
34636
  }
34497
34637
  function collectPrContextServiceCall(input) {
34498
34638
  const summaryOut = normalizeGeneratedPath(
34499
- (0, import_node_path.join)(input.workspaceRoot, SUMMARY_OUT)
34639
+ (0, import_node_path2.join)(input.workspaceRoot, SUMMARY_OUT)
34500
34640
  );
34501
34641
  const appendixOut = normalizeGeneratedPath(
34502
- (0, import_node_path.join)(input.workspaceRoot, APPENDIX_OUT)
34642
+ (0, import_node_path2.join)(input.workspaceRoot, APPENDIX_OUT)
34503
34643
  );
34504
34644
  const rendered = collectAndWrite({
34505
34645
  base: input.base,
@@ -34510,15 +34650,33 @@ function collectPrContextServiceCall(input) {
34510
34650
  includeUntracked: true,
34511
34651
  fs: input.fileSystem,
34512
34652
  runner: input.runner,
34653
+ whichGh: input.whichGh ?? defaultWhichGh,
34654
+ ...input.targetRef === void 0 ? {} : { head: input.targetRef },
34513
34655
  ...input.log === void 0 ? {} : { log: input.log }
34514
34656
  });
34515
34657
  verifyWrittenArtifact(input.fileSystem, summaryOut, rendered.summaryText);
34516
34658
  verifyWrittenArtifact(input.fileSystem, appendixOut, rendered.appendixText);
34659
+ const targetResolution = input.targetRef === void 0 ? "session-fallback" : "explicit";
34660
+ const diffState = classifyPrContextDiffState({
34661
+ mergeBase: rendered.mergeBase,
34662
+ headSha: rendered.headSha,
34663
+ resolvedHeadRef: rendered.resolvedHeadRef,
34664
+ resolvedBase: rendered.resolvedBase,
34665
+ changedFileCount: rendered.changedFileCount,
34666
+ requestedBase: input.base,
34667
+ attemptedHeadRef: input.targetRef ?? null
34668
+ });
34669
+ if (diffState.kind !== "populated") {
34670
+ throw new Error(diffState.message);
34671
+ }
34517
34672
  return {
34518
34673
  tool: "collect_pr_context",
34519
34674
  workspaceRoot: input.workspaceRoot,
34520
34675
  summary: `Collected PR context against base '${input.base}'.`,
34521
- artifacts: [summaryOut, appendixOut]
34676
+ artifacts: [summaryOut, appendixOut],
34677
+ targetResolution,
34678
+ resolvedHeadRef: rendered.resolvedHeadRef,
34679
+ resolvedHeadSha: rendered.headSha
34522
34680
  };
34523
34681
  }
34524
34682
 
@@ -35676,8 +35834,8 @@ function isInsidersSession2(envLookup = defaultEnvLookup2) {
35676
35834
  return false;
35677
35835
  }
35678
35836
  function resolveCodeCli2(whichLookup = defaultWhichLookup2, envLookup = defaultEnvLookup2) {
35679
- const candidateNames = isInsidersSession2(envLookup) ? ["code-insiders", "code"] : ["code", "code-insiders"];
35680
- for (const candidateName of candidateNames) {
35837
+ const candidateNames2 = isInsidersSession2(envLookup) ? ["code-insiders", "code"] : ["code", "code-insiders"];
35838
+ for (const candidateName of candidateNames2) {
35681
35839
  const resolvedCommand = whichLookup(candidateName);
35682
35840
  if (resolvedCommand) {
35683
35841
  return resolvedCommand;
@@ -36998,6 +37156,7 @@ var DefaultRepoAutomationService = class {
36998
37156
  fileSystem: this.fileSystem,
36999
37157
  workspaceRoot: input.workspaceRoot,
37000
37158
  base: input.base,
37159
+ ...input.targetRef === void 0 ? {} : { targetRef: input.targetRef },
37001
37160
  log: (message) => this.output.appendLine(message)
37002
37161
  });
37003
37162
  }