@danmoisan/drm-copilot-mcp 1.0.1 → 1.0.8

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 (69) hide show
  1. package/out/mcp-server.js +896 -202
  2. package/package.json +1 -1
  3. package/resources/claude-customizations/.claude/agents/atomic-executor.md +1 -0
  4. package/resources/claude-customizations/.claude/agents/atomic-planner.md +1 -0
  5. package/resources/claude-customizations/.claude/agents/commit-message.md +42 -0
  6. package/resources/claude-customizations/.claude/agents/csharp-typed-engineer.md +1 -0
  7. package/resources/claude-customizations/.claude/agents/epic-orchestrator.md +128 -0
  8. package/resources/claude-customizations/.claude/agents/epic-review.md +1 -0
  9. package/resources/claude-customizations/.claude/agents/feature-review.md +1 -0
  10. package/resources/claude-customizations/.claude/agents/human-exception-runbook.md +48 -0
  11. package/resources/claude-customizations/.claude/agents/orchestrator.md +80 -2
  12. package/resources/claude-customizations/.claude/agents/powershell-typed-engineer.md +1 -0
  13. package/resources/claude-customizations/.claude/agents/pr-author.md +37 -21
  14. package/resources/claude-customizations/.claude/agents/prd-feature.md +1 -0
  15. package/resources/claude-customizations/.claude/agents/python-typed-engineer.md +1 -0
  16. package/resources/claude-customizations/.claude/agents/staged-review.md +1 -0
  17. package/resources/claude-customizations/.claude/agents/status-updater.md +1 -0
  18. package/resources/claude-customizations/.claude/agents/typescript-engineer.md +1 -0
  19. package/resources/claude-customizations/.claude/hooks/check-powershell-test-purity.ps1 +103 -65
  20. package/resources/claude-customizations/.claude/hooks/check-python-test-purity.ps1 +12 -9
  21. package/resources/claude-customizations/.claude/hooks/enforce-checkpoint-monotonic.ps1 +24 -16
  22. package/resources/claude-customizations/.claude/hooks/enforce-completion-consistency.ps1 +19 -13
  23. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +304 -0
  24. package/resources/claude-customizations/.claude/hooks/enforce-epic-wave-barrier.ps1 +304 -0
  25. package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +237 -0
  26. package/resources/claude-customizations/.claude/hooks/enforce-evidence-locations.ps1 +16 -12
  27. package/resources/claude-customizations/.claude/hooks/enforce-feature-folder-order.ps1 +14 -10
  28. package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +182 -0
  29. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +35 -8
  30. package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +17 -14
  31. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.epic-base-branch.ps1 +104 -0
  32. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.ps1 +268 -93
  33. package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner.ps1 +19 -11
  34. package/resources/claude-customizations/.claude/hooks/enforce-promotion-mcp-only.ps1 +28 -6
  35. package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +17 -14
  36. package/resources/claude-customizations/.claude/hooks/validate-bash.ps1 +146 -36
  37. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +27 -7
  38. package/resources/claude-customizations/.claude/rules/orchestrator-state.md +53 -0
  39. package/resources/claude-customizations/.claude/settings.json +38 -1
  40. package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +252 -0
  41. package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +59 -13
  42. package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +28 -0
  43. package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +22 -18
  44. package/resources/claude-customizations/pack-manifests/core.json +9 -0
  45. package/resources/codex-and-agents-customizations/.agents/skills/feature-promotion-lifecycle/SKILL.md +8 -2
  46. package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +24 -3
  47. package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +13 -0
  48. package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +1 -1
  49. package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp/SKILL.md +65 -0
  50. package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +79 -0
  51. package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/invoke-csharp-engineer/SKILL.md +66 -0
  52. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +15 -14
  53. package/resources/codex-and-agents-customizations/.codex/config.toml +1 -25
  54. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-consistency.ps1 +144 -28
  55. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-helpers.ps1 +163 -0
  56. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-pr-author-skill.ps1 +257 -93
  57. package/resources/codex-and-agents-customizations/.codex-variants/csharp-legacy/agents/csharp-typed-engineer.toml +98 -0
  58. package/resources/codex-and-agents-customizations/pack-manifests/core.json +24 -0
  59. package/resources/codex-and-agents-customizations/pack-manifests/csharp-legacy.json +11 -0
  60. package/resources/codex-and-agents-customizations/pack-manifests/csharp-modern.json +10 -0
  61. package/resources/codex-and-agents-customizations/pack-manifests/powershell.json +15 -0
  62. package/resources/codex-and-agents-customizations/pack-manifests/python.json +15 -0
  63. package/resources/codex-and-agents-customizations/pack-manifests/typescript.json +9 -0
  64. package/resources/config/orchestration-routing.json +92 -0
  65. package/resources/customizations/.github/agents/pr-author.agent.md +24 -18
  66. package/resources/icon.png +0 -0
  67. package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +11 -0
  68. package/resources/codex-and-agents-customizations/.github/workflows/_validate-orchestrator-state.yml +0 -68
  69. package/resources/codex-and-agents-customizations/.github/workflows/validate-orchestrator-state.yml +0 -15
package/out/mcp-server.js CHANGED
@@ -8964,13 +8964,13 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
8964
8964
  }
8965
8965
  return propValues;
8966
8966
  });
8967
- const isObject7 = isObject;
8967
+ const isObject8 = isObject;
8968
8968
  const catchall = def.catchall;
8969
8969
  let value;
8970
8970
  inst._zod.parse = (payload, ctx) => {
8971
8971
  value ?? (value = _normalized.value);
8972
8972
  const input = payload.value;
8973
- if (!isObject7(input)) {
8973
+ if (!isObject8(input)) {
8974
8974
  payload.issues.push({
8975
8975
  expected: "object",
8976
8976
  code: "invalid_type",
@@ -9097,7 +9097,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
9097
9097
  return (payload, ctx) => fn(shape, payload, ctx);
9098
9098
  };
9099
9099
  let fastpass;
9100
- const isObject7 = isObject;
9100
+ const isObject8 = isObject;
9101
9101
  const jit = !globalConfig.jitless;
9102
9102
  const allowsEval2 = allowsEval;
9103
9103
  const fastEnabled = jit && allowsEval2.value;
@@ -9106,7 +9106,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
9106
9106
  inst._zod.parse = (payload, ctx) => {
9107
9107
  value ?? (value = _normalized.value);
9108
9108
  const input = payload.value;
9109
- if (!isObject7(input)) {
9109
+ if (!isObject8(input)) {
9110
9110
  payload.issues.push({
9111
9111
  expected: "object",
9112
9112
  code: "invalid_type",
@@ -15504,9 +15504,15 @@ function createBufferedOutput() {
15504
15504
  };
15505
15505
  }
15506
15506
  function executableExists(executable) {
15507
+ return findExecutableOnPath(executable) !== void 0;
15508
+ }
15509
+ function getPathExtensions() {
15510
+ return process.platform === "win32" ? (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").split(";").filter((part) => part.length > 0) : [""];
15511
+ }
15512
+ function findExecutableOnPath(executable) {
15507
15513
  const pathValue = process.env["PATH"] ?? "";
15508
15514
  const pathParts = pathValue.split(path.delimiter).filter((part) => part.length > 0);
15509
- const pathExtensions = process.platform === "win32" ? (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").split(";").filter((part) => part.length > 0) : [""];
15515
+ const pathExtensions = getPathExtensions();
15510
15516
  for (const directory of pathParts) {
15511
15517
  for (const extension of pathExtensions) {
15512
15518
  const candidate = path.join(
@@ -15514,11 +15520,11 @@ function executableExists(executable) {
15514
15520
  process.platform === "win32" ? `${executable}${extension}` : executable
15515
15521
  );
15516
15522
  if (fs.existsSync(candidate)) {
15517
- return true;
15523
+ return candidate.replace(/\\/g, "/");
15518
15524
  }
15519
15525
  }
15520
15526
  }
15521
- return false;
15527
+ return void 0;
15522
15528
  }
15523
15529
  function detectRuntime(runtimeKind) {
15524
15530
  void runtimeKind;
@@ -15660,6 +15666,54 @@ function getStderrExcerpt(error2) {
15660
15666
  return trimmed.length > 0 ? trimmed : void 0;
15661
15667
  }
15662
15668
 
15669
+ // ../../extensions/drm-copilot/src/mcp-push-down-schema-properties.ts
15670
+ var workspaceRootProperty = {
15671
+ type: "string",
15672
+ description: "Target workspace root. Defaults to process.cwd() when omitted."
15673
+ };
15674
+ var codexPacksProperty = {
15675
+ type: "array",
15676
+ items: {
15677
+ type: "string"
15678
+ },
15679
+ description: "Optional Codex language pack names to publish. When omitted, the full tree is published. 'core' is always included."
15680
+ };
15681
+ var codexCsharpVariantProperty = {
15682
+ type: "string",
15683
+ enum: ["modern", "legacy"],
15684
+ description: "Optional Codex C# toolchain variant to source ('modern' default or 'legacy')."
15685
+ };
15686
+ var codexMemoryModeProperty = {
15687
+ type: "string",
15688
+ enum: ["overwrite", "merge", "skip"],
15689
+ description: "Optional inert Codex memory parity field: 'overwrite' (default), 'merge', or 'skip'."
15690
+ };
15691
+ var codexPushDownSelectionProperties = {
15692
+ packs: codexPacksProperty,
15693
+ csharp_variant: codexCsharpVariantProperty,
15694
+ memory_mode: codexMemoryModeProperty
15695
+ };
15696
+ var copilotPushDownSelectionProperties = {};
15697
+ var claudePushDownSelectionProperties = {
15698
+ packs: {
15699
+ type: "array",
15700
+ items: {
15701
+ type: "string"
15702
+ },
15703
+ description: "Optional language pack names to publish (for example 'core', 'typescript'). When omitted, the full tree is published. 'core' is always included."
15704
+ },
15705
+ csharp_variant: {
15706
+ type: "string",
15707
+ enum: ["modern", "legacy"],
15708
+ description: "Optional C# toolchain variant to source ('modern' default or 'legacy')."
15709
+ },
15710
+ memory_mode: {
15711
+ type: "string",
15712
+ enum: ["overwrite", "merge", "skip"],
15713
+ description: "Optional agent-memory handling mode: 'overwrite' (default), 'merge', or 'skip'."
15714
+ }
15715
+ };
15716
+
15663
15717
  // ../../extensions/drm-copilot/src/workflow-command-arguments.ts
15664
15718
  var path2 = __toESM(require("node:path"));
15665
15719
  var SHORT_NAME_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;
@@ -15771,10 +15825,6 @@ function normalizeWorkspaceDestinationPath(value, workspaceRoot, fieldName) {
15771
15825
  }
15772
15826
 
15773
15827
  // ../../extensions/drm-copilot/src/mcp-repo-automation-tool-definitions.ts
15774
- var workspaceRootProperty = {
15775
- type: "string",
15776
- description: "Target workspace root. Defaults to process.cwd() when omitted."
15777
- };
15778
15828
  var REPO_AUTOMATION_TOOL_DEFINITIONS = [
15779
15829
  {
15780
15830
  name: "collect_commit_context",
@@ -15852,7 +15902,8 @@ var REPO_AUTOMATION_TOOL_DEFINITIONS = [
15852
15902
  inputSchema: {
15853
15903
  type: "object",
15854
15904
  properties: {
15855
- workspace_root: workspaceRootProperty
15905
+ workspace_root: workspaceRootProperty,
15906
+ ...copilotPushDownSelectionProperties
15856
15907
  },
15857
15908
  additionalProperties: false
15858
15909
  }
@@ -15863,7 +15914,8 @@ var REPO_AUTOMATION_TOOL_DEFINITIONS = [
15863
15914
  inputSchema: {
15864
15915
  type: "object",
15865
15916
  properties: {
15866
- workspace_root: workspaceRootProperty
15917
+ workspace_root: workspaceRootProperty,
15918
+ ...codexPushDownSelectionProperties
15867
15919
  },
15868
15920
  additionalProperties: false
15869
15921
  }
@@ -15875,23 +15927,7 @@ var REPO_AUTOMATION_TOOL_DEFINITIONS = [
15875
15927
  type: "object",
15876
15928
  properties: {
15877
15929
  workspace_root: workspaceRootProperty,
15878
- packs: {
15879
- type: "array",
15880
- items: {
15881
- type: "string"
15882
- },
15883
- description: "Optional language pack names to publish (for example 'core', 'typescript'). When omitted, the full tree is published. 'core' is always included."
15884
- },
15885
- csharp_variant: {
15886
- type: "string",
15887
- enum: ["modern", "legacy"],
15888
- description: "Optional C# toolchain variant to source ('modern' default or 'legacy')."
15889
- },
15890
- memory_mode: {
15891
- type: "string",
15892
- enum: ["overwrite", "merge", "skip"],
15893
- description: "Optional agent-memory handling mode: 'overwrite' (default), 'merge', or 'skip'."
15894
- }
15930
+ ...claudePushDownSelectionProperties
15895
15931
  },
15896
15932
  additionalProperties: false
15897
15933
  }
@@ -16172,6 +16208,10 @@ var REPO_AUTOMATION_TOOL_DEFINITIONS = [
16172
16208
  require_complete: {
16173
16209
  type: "boolean",
16174
16210
  description: "When true and artifact_type is 'orchestrator-state', require all phases to be complete."
16211
+ },
16212
+ require_model_routing: {
16213
+ type: "boolean",
16214
+ description: "When true and artifact_type is 'orchestrator-state', require a model_routing_receipts entry per delegated agent once a delegation is recorded. The TypeScript side performs the existence check only; the Python validator is authoritative for full per-receipt correctness."
16175
16215
  }
16176
16216
  },
16177
16217
  required: ["artifact_type", "artifact_path"],
@@ -16205,7 +16245,7 @@ var REPO_AUTOMATION_TOOLS = [
16205
16245
  ];
16206
16246
 
16207
16247
  // ../../extensions/drm-copilot/src/mcp-tool-inputs-push-down.ts
16208
- function resolveClaudePacksField(rawValue) {
16248
+ function resolvePacksField(rawValue) {
16209
16249
  if (rawValue === void 0) {
16210
16250
  return void 0;
16211
16251
  }
@@ -16240,7 +16280,22 @@ function resolveMemoryModeField(rawValue) {
16240
16280
  }
16241
16281
  function resolvePushDownClaudeCustomizationsToolInput(rawInput, fallbackWorkspaceRoot) {
16242
16282
  const args = asToolArgumentObject(rawInput);
16243
- const packs = resolveClaudePacksField(args["packs"]);
16283
+ const packs = resolvePacksField(args["packs"]);
16284
+ const csharpVariant = resolveCsharpVariantField(args["csharp_variant"]);
16285
+ const memoryMode = resolveMemoryModeField(args["memory_mode"]);
16286
+ return {
16287
+ workspaceRoot: normalizeWorkspaceRoot(
16288
+ args["workspace_root"],
16289
+ fallbackWorkspaceRoot
16290
+ ),
16291
+ ...packs === void 0 ? {} : { packs },
16292
+ ...csharpVariant === void 0 ? {} : { csharpVariant },
16293
+ ...memoryMode === void 0 ? {} : { memoryMode }
16294
+ };
16295
+ }
16296
+ function resolvePushDownCodexAndAgentsCustomizationsToolInput(rawInput, fallbackWorkspaceRoot) {
16297
+ const args = asToolArgumentObject(rawInput);
16298
+ const packs = resolvePacksField(args["packs"]);
16244
16299
  const csharpVariant = resolveCsharpVariantField(args["csharp_variant"]);
16245
16300
  const memoryMode = resolveMemoryModeField(args["memory_mode"]);
16246
16301
  return {
@@ -16381,15 +16436,6 @@ function resolvePushDownCopilotCustomizationsToolInput(rawInput, fallbackWorkspa
16381
16436
  )
16382
16437
  };
16383
16438
  }
16384
- function resolvePushDownCodexAndAgentsCustomizationsToolInput(rawInput, fallbackWorkspaceRoot) {
16385
- const args = asToolArgumentObject(rawInput);
16386
- return {
16387
- workspaceRoot: normalizeWorkspaceRoot(
16388
- args["workspace_root"],
16389
- fallbackWorkspaceRoot
16390
- )
16391
- };
16392
- }
16393
16439
  function resolveNewPotentialBugEntryToolInput(rawInput, fallbackWorkspaceRoot) {
16394
16440
  const args = asToolArgumentObject(rawInput);
16395
16441
  return {
@@ -16555,6 +16601,7 @@ function resolveValidateOrchestrationArtifactsToolInput(rawInput, fallbackWorksp
16555
16601
  );
16556
16602
  }
16557
16603
  const requireComplete = args["require_complete"];
16604
+ const requireModelRouting = args["require_model_routing"];
16558
16605
  return {
16559
16606
  workspaceRoot: normalizeWorkspaceRoot(
16560
16607
  args["workspace_root"],
@@ -16562,7 +16609,8 @@ function resolveValidateOrchestrationArtifactsToolInput(rawInput, fallbackWorksp
16562
16609
  ),
16563
16610
  artifactType,
16564
16611
  artifactPath: normalizeRequiredText(args["artifact_path"], "artifact_path"),
16565
- ...requireComplete === true ? { requireComplete: true } : {}
16612
+ ...requireComplete === true ? { requireComplete: true } : {},
16613
+ ...requireModelRouting === true ? { requireModelRouting: true } : {}
16566
16614
  };
16567
16615
  }
16568
16616
 
@@ -17458,18 +17506,304 @@ function pushDownCustomizations2(options) {
17458
17506
  });
17459
17507
  }
17460
17508
 
17509
+ // ../../extensions/drm-copilot/src/lib/push-down/codex-pack-selection.ts
17510
+ var CORE_PACK_NAME = "core";
17511
+ var PUBLIC_CSHARP_PACK_NAME = "csharp";
17512
+ var SUPPORTED_PACK_NAMES = /* @__PURE__ */ new Set([
17513
+ "core",
17514
+ "python",
17515
+ "powershell",
17516
+ "typescript",
17517
+ PUBLIC_CSHARP_PACK_NAME
17518
+ ]);
17519
+ var MANIFEST_PACK_NAMES = /* @__PURE__ */ new Set([
17520
+ "core",
17521
+ "python",
17522
+ "powershell",
17523
+ "typescript",
17524
+ "csharp-modern",
17525
+ "csharp-legacy"
17526
+ ]);
17527
+ var CSHARP_CANONICAL_PATHS = [
17528
+ ".agents/skills/csharp/SKILL.md",
17529
+ ".agents/skills/csharp-qa-gate/SKILL.md",
17530
+ ".agents/skills/invoke-csharp-engineer/SKILL.md",
17531
+ ".codex/agents/csharp-typed-engineer.toml"
17532
+ ];
17533
+ var CSHARP_PACK_NAMES = /* @__PURE__ */ new Set([
17534
+ "csharp-modern",
17535
+ "csharp-legacy"
17536
+ ]);
17537
+ var AGENTS_LEGACY_VARIANT_SOURCE_PREFIX = ".agents-variants/csharp-legacy";
17538
+ var CODEX_LEGACY_VARIANT_SOURCE_PREFIX = ".codex-variants/csharp-legacy";
17539
+ var ManifestError = class extends Error {
17540
+ constructor(message) {
17541
+ super(message);
17542
+ this.name = "ManifestError";
17543
+ }
17544
+ };
17545
+ function joinPosix3(dir, name) {
17546
+ const normalizedDir = dir.replace(/\\/g, "/").replace(/\/+$/, "");
17547
+ return normalizedDir === "" ? name : `${normalizedDir}/${name}`;
17548
+ }
17549
+ function loadPackManifests(manifestDir, selectedPackNames, fs9) {
17550
+ const unknown2 = [...selectedPackNames].filter(
17551
+ (name) => !MANIFEST_PACK_NAMES.has(name)
17552
+ );
17553
+ if (unknown2.length > 0) {
17554
+ throw new ManifestError(`Unknown Codex pack name(s): ${unknown2.sort()}`);
17555
+ }
17556
+ const namesToLoad = new Set(selectedPackNames);
17557
+ namesToLoad.add(CORE_PACK_NAME);
17558
+ const manifests = /* @__PURE__ */ new Map();
17559
+ for (const name of [...namesToLoad].sort()) {
17560
+ const manifestPath = joinPosix3(manifestDir, `${name}.json`);
17561
+ if (!fs9.isFile(manifestPath)) {
17562
+ throw new ManifestError(
17563
+ `Codex pack manifest is missing for pack '${name}': ${manifestPath}`
17564
+ );
17565
+ }
17566
+ manifests.set(
17567
+ name,
17568
+ parseManifest(name, manifestPath, fs9.readTextFile(manifestPath))
17569
+ );
17570
+ }
17571
+ return manifests;
17572
+ }
17573
+ function resolveManifestPackNames(selectedPackNames, csharpVariant) {
17574
+ if (selectedPackNames === null || selectedPackNames.size === 0) {
17575
+ return null;
17576
+ }
17577
+ const variantSpecific = [...selectedPackNames].filter(
17578
+ (name) => CSHARP_PACK_NAMES.has(name)
17579
+ );
17580
+ if (variantSpecific.length > 0) {
17581
+ throw new ManifestError(
17582
+ `Use public Codex pack 'csharp' with csharpVariant instead of variant-specific pack name(s): ${variantSpecific.sort().join(", ")}.`
17583
+ );
17584
+ }
17585
+ const unknown2 = [...selectedPackNames].filter(
17586
+ (name) => !SUPPORTED_PACK_NAMES.has(name)
17587
+ );
17588
+ if (unknown2.length > 0) {
17589
+ throw new ManifestError(`Unknown Codex pack name(s): ${unknown2.sort()}`);
17590
+ }
17591
+ const manifestNames = new Set(selectedPackNames);
17592
+ if (manifestNames.has(PUBLIC_CSHARP_PACK_NAME)) {
17593
+ manifestNames.delete(PUBLIC_CSHARP_PACK_NAME);
17594
+ manifestNames.add(`csharp-${csharpVariant}`);
17595
+ }
17596
+ return manifestNames;
17597
+ }
17598
+ function parseManifest(name, manifestPath, rawText) {
17599
+ let loaded;
17600
+ try {
17601
+ loaded = JSON.parse(rawText);
17602
+ } catch {
17603
+ throw new ManifestError(
17604
+ `Codex pack manifest is not valid JSON for pack '${name}': ${manifestPath}`
17605
+ );
17606
+ }
17607
+ if (loaded === null || typeof loaded !== "object" || Array.isArray(loaded)) {
17608
+ throw new ManifestError(
17609
+ `Codex pack manifest must be a JSON object for pack '${name}': ${manifestPath}`
17610
+ );
17611
+ }
17612
+ const parsed = loaded;
17613
+ const manifestName = parsed["name"];
17614
+ const manifestLabel = parsed["label"] ?? manifestName;
17615
+ const manifestPaths = parsed["paths"];
17616
+ const sourcePrefix = parsed["source_prefix"];
17617
+ if (typeof manifestName !== "string" || manifestName === "") {
17618
+ throw new ManifestError(
17619
+ `Codex pack manifest 'name' must be a non-empty string: ${manifestPath}`
17620
+ );
17621
+ }
17622
+ if (typeof manifestLabel !== "string" || manifestLabel === "") {
17623
+ throw new ManifestError(
17624
+ `Codex pack manifest 'label' must be a non-empty string: ${manifestPath}`
17625
+ );
17626
+ }
17627
+ if (!Array.isArray(manifestPaths) || manifestPaths.length === 0) {
17628
+ throw new ManifestError(
17629
+ `Codex pack manifest 'paths' must be a non-empty list of strings: ${manifestPath}`
17630
+ );
17631
+ }
17632
+ const paths = [];
17633
+ for (const entry of manifestPaths) {
17634
+ if (typeof entry !== "string" || entry === "") {
17635
+ throw new ManifestError(
17636
+ `Codex pack manifest 'paths' must be a non-empty list of strings: ${manifestPath}`
17637
+ );
17638
+ }
17639
+ paths.push(entry);
17640
+ }
17641
+ if (sourcePrefix !== void 0 && sourcePrefix !== null && typeof sourcePrefix !== "string") {
17642
+ throw new ManifestError(
17643
+ `Codex pack manifest 'source_prefix' must be a string when present: ${manifestPath}`
17644
+ );
17645
+ }
17646
+ return {
17647
+ name: manifestName,
17648
+ label: manifestLabel,
17649
+ paths,
17650
+ sourcePrefix: sourcePrefix === void 0 || sourcePrefix === null ? null : sourcePrefix
17651
+ };
17652
+ }
17653
+ function computePublishedPaths(selectedPackNames, manifests) {
17654
+ if (selectedPackNames === null || selectedPackNames.size === 0) {
17655
+ return null;
17656
+ }
17657
+ const effectiveNames = new Set(selectedPackNames);
17658
+ effectiveNames.add(CORE_PACK_NAME);
17659
+ const published = /* @__PURE__ */ new Set();
17660
+ for (const name of effectiveNames) {
17661
+ const manifest = manifests.get(name);
17662
+ if (manifest === void 0) {
17663
+ throw new ManifestError(
17664
+ `No loaded Codex manifest for selected pack '${name}'.`
17665
+ );
17666
+ }
17667
+ for (const path10 of manifest.paths) {
17668
+ published.add(path10);
17669
+ }
17670
+ }
17671
+ return published;
17672
+ }
17673
+ function resolveVariantSourcePath(destinationRelativePath, csharpVariant) {
17674
+ if (csharpVariant === "legacy" && CSHARP_CANONICAL_PATHS.includes(destinationRelativePath)) {
17675
+ if (destinationRelativePath.startsWith(".agents/")) {
17676
+ return `${AGENTS_LEGACY_VARIANT_SOURCE_PREFIX}/${destinationRelativePath.slice(".agents/".length)}`;
17677
+ }
17678
+ if (destinationRelativePath.startsWith(".codex/")) {
17679
+ return `${CODEX_LEGACY_VARIANT_SOURCE_PREFIX}/${destinationRelativePath.slice(".codex/".length)}`;
17680
+ }
17681
+ }
17682
+ return destinationRelativePath;
17683
+ }
17684
+ function assertSingleCsharpToolchain(publishedPaths, selectedPackNames) {
17685
+ const selectedCsharp = [...selectedPackNames].filter((name) => CSHARP_PACK_NAMES.has(name)).sort();
17686
+ if (selectedCsharp.length > 1) {
17687
+ throw new ManifestError(
17688
+ `C# mutual exclusion violated: both modern and legacy Codex C# packs were selected (${selectedCsharp.join(", ")}); select exactly one C# variant.`
17689
+ );
17690
+ }
17691
+ void publishedPaths;
17692
+ }
17693
+
17461
17694
  // ../../extensions/drm-copilot/src/lib/push-down/codex-agents-customizations.ts
17462
17695
  var ARTIFACT_DIRECTORY3 = "artifacts/codex-and-agents-customizations";
17463
17696
  var ROOT_FOLDERS = [".codex", ".agents"];
17697
+ var PACK_MANIFEST_SUBDIR = "pack-manifests";
17464
17698
  function passthroughRewrite(text) {
17465
17699
  return [text, 0, 0, []];
17466
17700
  }
17701
+ function normalizePosix(value) {
17702
+ return value.replace(/\\/g, "/").replace(/\/+$/, "");
17703
+ }
17704
+ function joinPosix4(root, relative2) {
17705
+ const normalizedRoot = normalizePosix(root);
17706
+ const normalizedRelative = relative2.replace(/\\/g, "/").replace(/^\/+/, "");
17707
+ return normalizedRoot === "" ? normalizedRelative : `${normalizedRoot}/${normalizedRelative}`;
17708
+ }
17709
+ function relativeToPosix2(path10, root) {
17710
+ const normalizedPath = normalizePosix(path10);
17711
+ const normalizedRoot = normalizePosix(root);
17712
+ if (normalizedPath === normalizedRoot) {
17713
+ return "";
17714
+ }
17715
+ const prefix = `${normalizedRoot}/`;
17716
+ return normalizedPath.startsWith(prefix) ? normalizedPath.slice(prefix.length) : null;
17717
+ }
17718
+ var CodexFilteringFileSystem = class {
17719
+ constructor(inner, options) {
17720
+ this.inner = inner;
17721
+ this.sourceRoot = normalizePosix(options.sourceRoot);
17722
+ this.bundleRoot = normalizePosix(options.bundleRoot);
17723
+ this.publishedPaths = options.publishedPaths;
17724
+ this.csharpVariant = options.csharpVariant;
17725
+ }
17726
+ inner;
17727
+ sourceRoot;
17728
+ bundleRoot;
17729
+ publishedPaths;
17730
+ csharpVariant;
17731
+ sourceRelative(path10) {
17732
+ return relativeToPosix2(path10, this.sourceRoot);
17733
+ }
17734
+ isPackIncluded(path10) {
17735
+ if (this.publishedPaths === null) {
17736
+ return true;
17737
+ }
17738
+ const relative2 = this.sourceRelative(path10);
17739
+ return relative2 === null || this.publishedPaths.has(relative2);
17740
+ }
17741
+ resolveReadSource(path10) {
17742
+ if (this.csharpVariant !== "legacy") {
17743
+ return path10;
17744
+ }
17745
+ const relative2 = this.sourceRelative(path10);
17746
+ if (relative2 === null) {
17747
+ return path10;
17748
+ }
17749
+ const routed = resolveVariantSourcePath(relative2, "legacy");
17750
+ return routed === relative2 ? path10 : joinPosix4(this.bundleRoot, routed);
17751
+ }
17752
+ listFiles(root) {
17753
+ return this.inner.listFiles(root).filter((path10) => this.isPackIncluded(path10));
17754
+ }
17755
+ isDir(path10) {
17756
+ return this.inner.isDir(path10);
17757
+ }
17758
+ isFile(path10) {
17759
+ return this.inner.isFile(path10);
17760
+ }
17761
+ readTextFile(path10) {
17762
+ return this.inner.readTextFile(this.resolveReadSource(path10));
17763
+ }
17764
+ writeTextFile(path10, content) {
17765
+ this.inner.writeTextFile(path10, content);
17766
+ }
17767
+ ensureDir(path10) {
17768
+ this.inner.ensureDir(path10);
17769
+ }
17770
+ };
17771
+ function resolvePublishedPaths(packs, csharpVariant, bundleRoot, fs9) {
17772
+ const manifestPacks = resolveManifestPackNames(packs ?? null, csharpVariant);
17773
+ if (manifestPacks === null || manifestPacks.size === 0) {
17774
+ return null;
17775
+ }
17776
+ const manifests = loadPackManifests(
17777
+ joinPosix4(bundleRoot, PACK_MANIFEST_SUBDIR),
17778
+ manifestPacks,
17779
+ fs9
17780
+ );
17781
+ const published = computePublishedPaths(manifestPacks, manifests) ?? /* @__PURE__ */ new Set();
17782
+ assertSingleCsharpToolchain(published, manifestPacks);
17783
+ return published;
17784
+ }
17467
17785
  function pushDownCustomizations3(options) {
17786
+ const sourceRoot = options.sourceRoot ?? options.repoRoot;
17787
+ const bundleRoot = options.bundleRoot ?? sourceRoot;
17788
+ const csharpVariant = options.csharpVariant ?? "modern";
17789
+ const publishedPaths = resolvePublishedPaths(
17790
+ options.packs,
17791
+ csharpVariant,
17792
+ bundleRoot,
17793
+ options.fs
17794
+ );
17795
+ const filteringFs = new CodexFilteringFileSystem(options.fs, {
17796
+ sourceRoot,
17797
+ bundleRoot,
17798
+ publishedPaths,
17799
+ csharpVariant
17800
+ });
17801
+ void options.memoryMode;
17468
17802
  return pushDownCustomizations({
17469
17803
  repoRoot: options.repoRoot,
17470
17804
  destinationRoot: options.destinationRoot,
17471
- fs: options.fs,
17472
- ...options.sourceRoot === void 0 ? {} : { sourceRoot: options.sourceRoot },
17805
+ fs: filteringFs,
17806
+ sourceRoot,
17473
17807
  ...options.artifactRoot === void 0 ? {} : { artifactRoot: options.artifactRoot },
17474
17808
  rootFolders: ROOT_FOLDERS,
17475
17809
  artifactDirectory: ARTIFACT_DIRECTORY3,
@@ -17506,11 +17840,11 @@ function readMemoryScope(content) {
17506
17840
  }
17507
17841
  return scopeValue === GENERAL_MEMORY_SCOPE ? GENERAL_MEMORY_SCOPE : REPO_MEMORY_SCOPE;
17508
17842
  }
17509
- function normalizePosix(value) {
17843
+ function normalizePosix2(value) {
17510
17844
  return value.replace(/\\/g, "/").replace(/\/+$/, "");
17511
17845
  }
17512
17846
  function isUnderAgentMemory(relativePosixPath) {
17513
- const normalized = normalizePosix(relativePosixPath);
17847
+ const normalized = normalizePosix2(relativePosixPath);
17514
17848
  return normalized === AGENT_MEMORY_RELATIVE_ROOT || normalized.startsWith(`${AGENT_MEMORY_RELATIVE_ROOT}/`);
17515
17849
  }
17516
17850
  function isGeneralMemoryFile(relativePosixPath, content) {
@@ -17521,55 +17855,55 @@ function isGeneralMemoryFile(relativePosixPath, content) {
17521
17855
  }
17522
17856
 
17523
17857
  // ../../extensions/drm-copilot/src/lib/push-down/claude-pack-selection.ts
17524
- var CORE_PACK_NAME = "core";
17525
- var CSHARP_CANONICAL_PATHS = [
17858
+ var CORE_PACK_NAME2 = "core";
17859
+ var CSHARP_CANONICAL_PATHS2 = [
17526
17860
  ".claude/rules/csharp.md",
17527
17861
  ".claude/agents/csharp-typed-engineer.md",
17528
17862
  ".claude/skills/csharp-qa-gate/SKILL.md",
17529
17863
  ".claude/skills/invoke-csharp-engineer/SKILL.md"
17530
17864
  ];
17531
- var CSHARP_PACK_NAMES = /* @__PURE__ */ new Set([
17865
+ var CSHARP_PACK_NAMES2 = /* @__PURE__ */ new Set([
17532
17866
  "csharp-modern",
17533
17867
  "csharp-legacy"
17534
17868
  ]);
17535
17869
  var LEGACY_VARIANT_SOURCE_PREFIX = ".claude-variants/csharp-legacy";
17536
- var ManifestError = class extends Error {
17870
+ var ManifestError2 = class extends Error {
17537
17871
  constructor(message) {
17538
17872
  super(message);
17539
17873
  this.name = "ManifestError";
17540
17874
  }
17541
17875
  };
17542
- function joinPosix3(dir, name) {
17876
+ function joinPosix5(dir, name) {
17543
17877
  const normalizedDir = dir.replace(/\\/g, "/").replace(/\/+$/, "");
17544
17878
  return normalizedDir === "" ? name : `${normalizedDir}/${name}`;
17545
17879
  }
17546
- function loadPackManifests(manifestDir, selectedPackNames, fs9) {
17880
+ function loadPackManifests2(manifestDir, selectedPackNames, fs9) {
17547
17881
  const namesToLoad = new Set(selectedPackNames);
17548
- namesToLoad.add(CORE_PACK_NAME);
17882
+ namesToLoad.add(CORE_PACK_NAME2);
17549
17883
  const manifests = /* @__PURE__ */ new Map();
17550
17884
  for (const name of [...namesToLoad].sort()) {
17551
- const manifestPath = joinPosix3(manifestDir, `${name}.json`);
17885
+ const manifestPath = joinPosix5(manifestDir, `${name}.json`);
17552
17886
  if (!fs9.isFile(manifestPath)) {
17553
- throw new ManifestError(
17887
+ throw new ManifestError2(
17554
17888
  `Pack manifest is missing for pack '${name}': ${manifestPath}`
17555
17889
  );
17556
17890
  }
17557
17891
  const rawText = fs9.readTextFile(manifestPath);
17558
- manifests.set(name, parseManifest(name, manifestPath, rawText));
17892
+ manifests.set(name, parseManifest2(name, manifestPath, rawText));
17559
17893
  }
17560
17894
  return manifests;
17561
17895
  }
17562
- function parseManifest(name, manifestPath, rawText) {
17896
+ function parseManifest2(name, manifestPath, rawText) {
17563
17897
  let loaded;
17564
17898
  try {
17565
17899
  loaded = JSON.parse(rawText);
17566
17900
  } catch {
17567
- throw new ManifestError(
17901
+ throw new ManifestError2(
17568
17902
  `Pack manifest is not valid JSON for pack '${name}': ${manifestPath}`
17569
17903
  );
17570
17904
  }
17571
17905
  if (loaded === null || typeof loaded !== "object" || Array.isArray(loaded)) {
17572
- throw new ManifestError(
17906
+ throw new ManifestError2(
17573
17907
  `Pack manifest must be a JSON object for pack '${name}': ${manifestPath}`
17574
17908
  );
17575
17909
  }
@@ -17579,31 +17913,31 @@ function parseManifest(name, manifestPath, rawText) {
17579
17913
  const manifestPaths = parsed["paths"];
17580
17914
  const sourcePrefix = parsed["source_prefix"];
17581
17915
  if (typeof manifestName !== "string" || manifestName === "") {
17582
- throw new ManifestError(
17916
+ throw new ManifestError2(
17583
17917
  `Pack manifest 'name' must be a non-empty string: ${manifestPath}`
17584
17918
  );
17585
17919
  }
17586
17920
  if (typeof manifestLabel !== "string" || manifestLabel === "") {
17587
- throw new ManifestError(
17921
+ throw new ManifestError2(
17588
17922
  `Pack manifest 'label' must be a non-empty string: ${manifestPath}`
17589
17923
  );
17590
17924
  }
17591
17925
  if (!Array.isArray(manifestPaths)) {
17592
- throw new ManifestError(
17926
+ throw new ManifestError2(
17593
17927
  `Pack manifest 'paths' must be a list of strings: ${manifestPath}`
17594
17928
  );
17595
17929
  }
17596
17930
  const typedPaths = [];
17597
17931
  for (const entry of manifestPaths) {
17598
17932
  if (typeof entry !== "string") {
17599
- throw new ManifestError(
17933
+ throw new ManifestError2(
17600
17934
  `Pack manifest 'paths' must be a list of strings: ${manifestPath}`
17601
17935
  );
17602
17936
  }
17603
17937
  typedPaths.push(entry);
17604
17938
  }
17605
17939
  if (sourcePrefix !== void 0 && sourcePrefix !== null && typeof sourcePrefix !== "string") {
17606
- throw new ManifestError(
17940
+ throw new ManifestError2(
17607
17941
  `Pack manifest 'source_prefix' must be a string when present: ${manifestPath}`
17608
17942
  );
17609
17943
  }
@@ -17614,17 +17948,17 @@ function parseManifest(name, manifestPath, rawText) {
17614
17948
  sourcePrefix: sourcePrefix === void 0 || sourcePrefix === null ? null : sourcePrefix
17615
17949
  };
17616
17950
  }
17617
- function computePublishedPaths(selectedPackNames, manifests) {
17951
+ function computePublishedPaths2(selectedPackNames, manifests) {
17618
17952
  if (selectedPackNames === null || selectedPackNames.size === 0) {
17619
17953
  return null;
17620
17954
  }
17621
17955
  const effectiveNames = new Set(selectedPackNames);
17622
- effectiveNames.add(CORE_PACK_NAME);
17956
+ effectiveNames.add(CORE_PACK_NAME2);
17623
17957
  const published = /* @__PURE__ */ new Set();
17624
17958
  for (const name of effectiveNames) {
17625
17959
  const manifest = manifests.get(name);
17626
17960
  if (manifest === void 0) {
17627
- throw new ManifestError(
17961
+ throw new ManifestError2(
17628
17962
  `No loaded manifest for selected pack '${name}'.`
17629
17963
  );
17630
17964
  }
@@ -17634,17 +17968,17 @@ function computePublishedPaths(selectedPackNames, manifests) {
17634
17968
  }
17635
17969
  return published;
17636
17970
  }
17637
- function resolveVariantSourcePath(destinationRelativePath, csharpVariant) {
17638
- if (csharpVariant === "legacy" && CSHARP_CANONICAL_PATHS.includes(destinationRelativePath)) {
17971
+ function resolveVariantSourcePath2(destinationRelativePath, csharpVariant) {
17972
+ if (csharpVariant === "legacy" && CSHARP_CANONICAL_PATHS2.includes(destinationRelativePath)) {
17639
17973
  const tail = destinationRelativePath.slice(".claude/".length);
17640
17974
  return `${LEGACY_VARIANT_SOURCE_PREFIX}/${tail}`;
17641
17975
  }
17642
17976
  return destinationRelativePath;
17643
17977
  }
17644
- function assertSingleCsharpToolchain(publishedPaths, selectedPackNames) {
17645
- const selectedCsharp = [...selectedPackNames].filter((name) => CSHARP_PACK_NAMES.has(name)).sort();
17978
+ function assertSingleCsharpToolchain2(publishedPaths, selectedPackNames) {
17979
+ const selectedCsharp = [...selectedPackNames].filter((name) => CSHARP_PACK_NAMES2.has(name)).sort();
17646
17980
  if (selectedCsharp.length > 1) {
17647
- throw new ManifestError(
17981
+ throw new ManifestError2(
17648
17982
  `C# mutual exclusion violated: both modern and legacy C# packs were selected ([${selectedCsharp.map((n) => `'${n}'`).join(", ")}]); select exactly one C# variant.`
17649
17983
  );
17650
17984
  }
@@ -17652,11 +17986,11 @@ function assertSingleCsharpToolchain(publishedPaths, selectedPackNames) {
17652
17986
  }
17653
17987
 
17654
17988
  // ../../extensions/drm-copilot/src/lib/push-down/claude-filesystem-adapter.ts
17655
- function normalizePosix2(value) {
17989
+ function normalizePosix3(value) {
17656
17990
  return value.replace(/\\/g, "/").replace(/\/+$/, "");
17657
17991
  }
17658
- function joinPosix4(root, relative2) {
17659
- const normalizedRoot = normalizePosix2(root);
17992
+ function joinPosix6(root, relative2) {
17993
+ const normalizedRoot = normalizePosix3(root);
17660
17994
  const normalizedRelative = relative2.replace(/\\/g, "/").replace(/^\/+/, "");
17661
17995
  if (normalizedRoot === "") {
17662
17996
  return normalizedRelative;
@@ -17666,9 +18000,9 @@ function joinPosix4(root, relative2) {
17666
18000
  }
17667
18001
  return `${normalizedRoot}/${normalizedRelative}`;
17668
18002
  }
17669
- function relativeToPosix2(path10, root) {
17670
- const normalizedPath = normalizePosix2(path10);
17671
- const normalizedRoot = normalizePosix2(root);
18003
+ function relativeToPosix3(path10, root) {
18004
+ const normalizedPath = normalizePosix3(path10);
18005
+ const normalizedRoot = normalizePosix3(root);
17672
18006
  if (normalizedPath === normalizedRoot) {
17673
18007
  return "";
17674
18008
  }
@@ -17697,16 +18031,16 @@ var ExcludingFileSystem = class {
17697
18031
  */
17698
18032
  constructor(inner, repoRoot, excluded, options = {}) {
17699
18033
  this.inner = inner;
17700
- this.repoRoot = normalizePosix2(repoRoot);
17701
- this.sourceRoot = normalizePosix2(options.sourceRoot ?? repoRoot);
17702
- this.variantRoot = normalizePosix2(
18034
+ this.repoRoot = normalizePosix3(repoRoot);
18035
+ this.sourceRoot = normalizePosix3(options.sourceRoot ?? repoRoot);
18036
+ this.variantRoot = normalizePosix3(
17703
18037
  options.variantRoot ?? options.sourceRoot ?? repoRoot
17704
18038
  );
17705
- this.destinationRoot = options.destinationRoot === void 0 ? void 0 : normalizePosix2(options.destinationRoot);
18039
+ this.destinationRoot = options.destinationRoot === void 0 ? void 0 : normalizePosix3(options.destinationRoot);
17706
18040
  this.publishedPaths = options.publishedPaths ?? null;
17707
18041
  this.csharpVariant = options.csharpVariant ?? "modern";
17708
18042
  this.memoryMode = options.memoryMode ?? "overwrite";
17709
- this.excluded = new Set(excluded.map((p) => joinPosix4(this.repoRoot, p)));
18043
+ this.excluded = new Set(excluded.map((p) => joinPosix6(this.repoRoot, p)));
17710
18044
  }
17711
18045
  /**
17712
18046
  * Return the source-relative POSIX path, or null when outside the root.
@@ -17715,7 +18049,7 @@ var ExcludingFileSystem = class {
17715
18049
  * @returns The source-relative POSIX path, or `null`.
17716
18050
  */
17717
18051
  sourceRelativePosix(path10) {
17718
- return relativeToPosix2(path10, this.sourceRoot);
18052
+ return relativeToPosix3(path10, this.sourceRoot);
17719
18053
  }
17720
18054
  /**
17721
18055
  * Return whether a candidate path is in the active published set.
@@ -17742,7 +18076,7 @@ var ExcludingFileSystem = class {
17742
18076
  * @returns True when the file is outside the memory subtree or general-scoped.
17743
18077
  */
17744
18078
  isScopeIncluded(path10) {
17745
- const relativePath = relativeToPosix2(path10, this.repoRoot);
18079
+ const relativePath = relativeToPosix3(path10, this.repoRoot);
17746
18080
  if (relativePath === null) {
17747
18081
  return true;
17748
18082
  }
@@ -17773,7 +18107,7 @@ var ExcludingFileSystem = class {
17773
18107
  if (this.destinationRoot === void 0) {
17774
18108
  return true;
17775
18109
  }
17776
- const destinationPath = joinPosix4(this.destinationRoot, relative2);
18110
+ const destinationPath = joinPosix6(this.destinationRoot, relative2);
17777
18111
  return !this.inner.isFile(destinationPath);
17778
18112
  }
17779
18113
  return true;
@@ -17792,15 +18126,15 @@ var ExcludingFileSystem = class {
17792
18126
  return path10;
17793
18127
  }
17794
18128
  const relative2 = this.sourceRelativePosix(path10);
17795
- if (relative2 === null || !CSHARP_CANONICAL_PATHS.includes(relative2)) {
18129
+ if (relative2 === null || !CSHARP_CANONICAL_PATHS2.includes(relative2)) {
17796
18130
  return path10;
17797
18131
  }
17798
- const redirectedRelative = resolveVariantSourcePath(relative2, "legacy");
17799
- return joinPosix4(this.variantRoot, redirectedRelative);
18132
+ const redirectedRelative = resolveVariantSourcePath2(relative2, "legacy");
18133
+ return joinPosix6(this.variantRoot, redirectedRelative);
17800
18134
  }
17801
18135
  listFiles(root) {
17802
18136
  return this.inner.listFiles(root).filter(
17803
- (p) => !this.excluded.has(normalizePosix2(p)) && this.isPackIncluded(p) && this.isScopeIncluded(p) && this.isMemoryModeIncluded(p)
18137
+ (p) => !this.excluded.has(normalizePosix3(p)) && this.isPackIncluded(p) && this.isScopeIncluded(p) && this.isMemoryModeIncluded(p)
17804
18138
  );
17805
18139
  }
17806
18140
  isDir(path10) {
@@ -17830,28 +18164,28 @@ var EXCLUDED_RELATIVE_PATHS = [
17830
18164
  ".claude/settings.local.json"
17831
18165
  ];
17832
18166
  var BUNDLE_ROOT_RELATIVE_DIR = "extensions/drm-copilot/resources/claude-customizations";
17833
- var PACK_MANIFEST_SUBDIR = "pack-manifests";
18167
+ var PACK_MANIFEST_SUBDIR2 = "pack-manifests";
17834
18168
  function passthroughRewrite2(text) {
17835
18169
  return [text, 0, 0, []];
17836
18170
  }
17837
- function joinPosix5(root, relative2) {
18171
+ function joinPosix7(root, relative2) {
17838
18172
  const normalizedRoot = root.replace(/\\/g, "/").replace(/\/+$/, "");
17839
18173
  const normalizedRelative = relative2.replace(/\\/g, "/").replace(/^\/+/, "");
17840
18174
  return normalizedRoot === "" ? normalizedRelative : `${normalizedRoot}/${normalizedRelative}`;
17841
18175
  }
17842
- function resolvePublishedPaths(packs, bundleRoot, fs9) {
18176
+ function resolvePublishedPaths2(packs, bundleRoot, fs9) {
17843
18177
  if (packs === null || packs.size === 0) {
17844
18178
  return null;
17845
18179
  }
17846
- const manifestDir = joinPosix5(bundleRoot, PACK_MANIFEST_SUBDIR);
17847
- const manifests = loadPackManifests(
18180
+ const manifestDir = joinPosix7(bundleRoot, PACK_MANIFEST_SUBDIR2);
18181
+ const manifests = loadPackManifests2(
17848
18182
  manifestDir,
17849
18183
  packs,
17850
18184
  fs9
17851
18185
  );
17852
- const published = computePublishedPaths(packs, manifests);
18186
+ const published = computePublishedPaths2(packs, manifests);
17853
18187
  const effectivePublished = published ?? /* @__PURE__ */ new Set();
17854
- assertSingleCsharpToolchain(effectivePublished, packs);
18188
+ assertSingleCsharpToolchain2(effectivePublished, packs);
17855
18189
  return effectivePublished;
17856
18190
  }
17857
18191
  function pushDownCustomizations4(options) {
@@ -17868,8 +18202,8 @@ function pushDownCustomizations4(options) {
17868
18202
  clock
17869
18203
  } = options;
17870
18204
  const effectiveSource = sourceRoot ?? repoRoot;
17871
- const effectiveBundle = bundleRoot ?? joinPosix5(effectiveSource, BUNDLE_ROOT_RELATIVE_DIR);
17872
- const publishedPaths = resolvePublishedPaths(
18205
+ const effectiveBundle = bundleRoot ?? joinPosix7(effectiveSource, BUNDLE_ROOT_RELATIVE_DIR);
18206
+ const publishedPaths = resolvePublishedPaths2(
17873
18207
  packs ?? null,
17874
18208
  effectiveBundle,
17875
18209
  fs9
@@ -17932,12 +18266,17 @@ function pushDownCodexAndAgentsCustomizationsServiceCall(input) {
17932
18266
  "resources/codex-and-agents-customizations"
17933
18267
  );
17934
18268
  const destinationRoot = toPosixPath(input.workspaceRoot);
18269
+ const packs = input.packs === void 0 || input.packs.length === 0 ? null : new Set(input.packs);
17935
18270
  const summary = pushDownCustomizations3({
17936
18271
  repoRoot: sourceRoot,
17937
18272
  destinationRoot,
17938
18273
  fs: input.fs,
17939
18274
  sourceRoot,
17940
18275
  artifactRoot: destinationRoot,
18276
+ bundleRoot: sourceRoot,
18277
+ packs,
18278
+ ...input.csharpVariant === void 0 ? {} : { csharpVariant: input.csharpVariant },
18279
+ ...input.memoryMode === void 0 ? {} : { memoryMode: input.memoryMode },
17941
18280
  ...input.clock === void 0 ? {} : { clock: input.clock }
17942
18281
  });
17943
18282
  return {
@@ -17983,6 +18322,14 @@ function buildPushDownClaudeCustomizationsOptions(input) {
17983
18322
  ...input.memoryMode === void 0 ? {} : { memoryMode: input.memoryMode }
17984
18323
  };
17985
18324
  }
18325
+ function buildPushDownCodexAndAgentsCustomizationsOptions(input) {
18326
+ return {
18327
+ workspaceRoot: input.workspaceRoot,
18328
+ ...input.packs === void 0 ? {} : { packs: input.packs },
18329
+ ...input.csharpVariant === void 0 ? {} : { csharpVariant: input.csharpVariant },
18330
+ ...input.memoryMode === void 0 ? {} : { memoryMode: input.memoryMode }
18331
+ };
18332
+ }
17986
18333
  function runPushDownCopilotCustomizations(workspaceRoot, deps) {
17987
18334
  return pushDownCopilotCustomizationsServiceCall({
17988
18335
  fs: deps.fs,
@@ -17991,12 +18338,16 @@ function runPushDownCopilotCustomizations(workspaceRoot, deps) {
17991
18338
  log: deps.log
17992
18339
  });
17993
18340
  }
17994
- function runPushDownCodexAndAgentsCustomizations(workspaceRoot, deps) {
18341
+ function runPushDownCodexAndAgentsCustomizations(input, deps) {
18342
+ const forwarded = buildPushDownCodexAndAgentsCustomizationsOptions(input);
17995
18343
  return pushDownCodexAndAgentsCustomizationsServiceCall({
17996
18344
  fs: deps.fs,
17997
18345
  extensionRoot: deps.extensionRoot,
17998
- workspaceRoot,
17999
- log: deps.log
18346
+ workspaceRoot: forwarded.workspaceRoot,
18347
+ log: deps.log,
18348
+ ...forwarded.packs === void 0 ? {} : { packs: forwarded.packs },
18349
+ ...forwarded.csharpVariant === void 0 ? {} : { csharpVariant: forwarded.csharpVariant },
18350
+ ...forwarded.memoryMode === void 0 ? {} : { memoryMode: forwarded.memoryMode }
18000
18351
  });
18001
18352
  }
18002
18353
  function runPushDownClaudeCustomizations(input, deps) {
@@ -18074,7 +18425,7 @@ var nodePath3 = __toESM(require("node:path"));
18074
18425
  function toPosixPath2(value) {
18075
18426
  return value.replace(/\\/g, "/");
18076
18427
  }
18077
- function joinPosix6(root, relative2) {
18428
+ function joinPosix8(root, relative2) {
18078
18429
  const normalizedRoot = toPosixPath2(root).replace(/\/+$/, "");
18079
18430
  const normalizedRelative = toPosixPath2(relative2).replace(/^\/+/, "");
18080
18431
  if (normalizedRoot === "") {
@@ -18147,7 +18498,7 @@ var RealFileSystem = class {
18147
18498
  for (const entry of entries) {
18148
18499
  const relativePath = relativePrefix === "" ? entry.name : `${relativePrefix}/${entry.name}`;
18149
18500
  if (matcher.test(relativePath)) {
18150
- matches.push(joinPosix6(normalizedRoot, relativePath));
18501
+ matches.push(joinPosix8(normalizedRoot, relativePath));
18151
18502
  }
18152
18503
  if (entry.isDirectory()) {
18153
18504
  walk(nodePath3.join(currentDir, entry.name), relativePath);
@@ -18305,11 +18656,11 @@ function resolveTemplateName(templateKind) {
18305
18656
  function resolveTemplatePath(templateName, workspaceRoot, templateRoot, fs9) {
18306
18657
  const candidates = [];
18307
18658
  if (templateRoot !== null) {
18308
- candidates.push(joinPosix7(templateRoot, templateName));
18659
+ candidates.push(joinPosix9(templateRoot, templateName));
18309
18660
  }
18310
18661
  candidates.push(
18311
- joinPosix7(
18312
- joinPosix7(toPosixPath2(workspaceRoot), ".github/codex"),
18662
+ joinPosix9(
18663
+ joinPosix9(toPosixPath2(workspaceRoot), ".github/codex"),
18313
18664
  templateName
18314
18665
  )
18315
18666
  );
@@ -18324,15 +18675,15 @@ function resolveIssueFileForTarget(targetPath, workspaceRoot, fs9) {
18324
18675
  const normalizedRoot = toPosixPath2(workspaceRoot).replace(/\/+$/, "");
18325
18676
  const relativeTarget = tryRelativeToWorkspace(targetPath, workspaceRoot);
18326
18677
  const planDir = parentOf(relativeTarget);
18327
- const directIssue = joinPosix7(joinPosix7(normalizedRoot, planDir), "issue.md");
18678
+ const directIssue = joinPosix9(joinPosix9(normalizedRoot, planDir), "issue.md");
18328
18679
  if (fs9.isFile(directIssue)) {
18329
18680
  return directIssue;
18330
18681
  }
18331
18682
  const planDirParts = splitParts(planDir);
18332
18683
  const planDirName = planDirParts[planDirParts.length - 1] ?? "";
18333
18684
  if (planDirName.startsWith("v") && planDirParts.length >= 2) {
18334
- const parentIssue = joinPosix7(
18335
- joinPosix7(normalizedRoot, parentOf(planDir)),
18685
+ const parentIssue = joinPosix9(
18686
+ joinPosix9(normalizedRoot, parentOf(planDir)),
18336
18687
  "issue.md"
18337
18688
  );
18338
18689
  if (fs9.isFile(parentIssue)) {
@@ -18453,7 +18804,7 @@ function resolveOutputPath(output, workspaceRoot) {
18453
18804
  if (isAbsolute(output)) {
18454
18805
  return toPosixPath2(output);
18455
18806
  }
18456
- return joinPosix7(toPosixPath2(workspaceRoot), output);
18807
+ return joinPosix9(toPosixPath2(workspaceRoot), output);
18457
18808
  }
18458
18809
  function tryRelativeToWorkspace(path10, workspaceRoot) {
18459
18810
  const normalizedPath = toPosixPath2(path10).replace(/\/+$/, "");
@@ -18481,7 +18832,7 @@ function parentOf(pathValue) {
18481
18832
  function splitParts(pathValue) {
18482
18833
  return toPosixPath2(pathValue).split("/").filter((part) => part.length > 0 && part !== ".");
18483
18834
  }
18484
- function joinPosix7(root, relative2) {
18835
+ function joinPosix9(root, relative2) {
18485
18836
  const normalizedRoot = toPosixPath2(root).replace(/\/+$/, "");
18486
18837
  const normalizedRelative = toPosixPath2(relative2).replace(/^\/+/, "");
18487
18838
  if (normalizedRelative === "" || normalizedRelative === ".") {
@@ -19443,7 +19794,7 @@ var SUPPORTED_ROOTS = {
19443
19794
  ".claude/rules"
19444
19795
  ]
19445
19796
  };
19446
- function joinPosix8(root, relative2) {
19797
+ function joinPosix10(root, relative2) {
19447
19798
  const normalizedRoot = root.replace(/\/+$/, "");
19448
19799
  const normalizedRelative = relative2.replace(/^\/+/, "");
19449
19800
  if (normalizedRoot === "") {
@@ -19485,7 +19836,7 @@ function isAbsolutePath(value) {
19485
19836
  function normalizeRelativePath(sourceRoot, candidatePath) {
19486
19837
  const resolvedRoot = collapseSegments(toPosixPath2(sourceRoot));
19487
19838
  const candidate = toPosixPath2(candidatePath);
19488
- const resolvedCandidate = isAbsolutePath(candidate) ? collapseSegments(candidate) : collapseSegments(joinPosix8(resolvedRoot, candidate));
19839
+ const resolvedCandidate = isAbsolutePath(candidate) ? collapseSegments(candidate) : collapseSegments(joinPosix10(resolvedRoot, candidate));
19489
19840
  const rootPrefix = `${resolvedRoot.replace(/\/+$/, "")}/`;
19490
19841
  if (resolvedCandidate === resolvedRoot) {
19491
19842
  return "";
@@ -19508,7 +19859,7 @@ function normalizeSelectedPaths(sourceRoot, selectedPaths) {
19508
19859
  }
19509
19860
  function collectFilesRecursive(fileSystem, absoluteDir, out) {
19510
19861
  for (const childName of fileSystem.listDirectory(absoluteDir)) {
19511
- const childPath = joinPosix8(absoluteDir, childName);
19862
+ const childPath = joinPosix10(absoluteDir, childName);
19512
19863
  if (fileSystem.isDirectory(childPath)) {
19513
19864
  collectFilesRecursive(fileSystem, childPath, out);
19514
19865
  } else if (fileSystem.isFile(childPath)) {
@@ -19522,7 +19873,7 @@ function iterSupportedArtifacts(fileSystem, sourceRoot, sourceEcosystem) {
19522
19873
  const discovered = /* @__PURE__ */ new Set();
19523
19874
  for (const supportedRoot of SUPPORTED_ROOTS[sourceEcosystem]) {
19524
19875
  const absoluteSupportedRoot = collapseSegments(
19525
- joinPosix8(resolvedRoot, supportedRoot)
19876
+ joinPosix10(resolvedRoot, supportedRoot)
19526
19877
  );
19527
19878
  if (!fileSystem.exists(absoluteSupportedRoot)) {
19528
19879
  continue;
@@ -20589,14 +20940,14 @@ function sortKeysDeep(value) {
20589
20940
  function dumpsSorted(payload) {
20590
20941
  return JSON.stringify(sortKeysDeep(payload), null, 2);
20591
20942
  }
20592
- function joinPosix9(root, child) {
20943
+ function joinPosix11(root, child) {
20593
20944
  const normalizedRoot = root.replace(/\/+$/, "");
20594
20945
  return normalizedRoot === "" ? child : `${normalizedRoot}/${child}`;
20595
20946
  }
20596
20947
  function writeIntermediateStateArtifacts(fileSystem, state, artifactRoot) {
20597
- const intermediateDir = joinPosix9(artifactRoot, "intermediate");
20948
+ const intermediateDir = joinPosix11(artifactRoot, "intermediate");
20598
20949
  fileSystem.ensureDir(intermediateDir);
20599
- const sourceArtifactsPath = joinPosix9(
20950
+ const sourceArtifactsPath = joinPosix11(
20600
20951
  intermediateDir,
20601
20952
  "source-artifacts.json"
20602
20953
  );
@@ -20606,14 +20957,14 @@ function writeIntermediateStateArtifacts(fileSystem, state, artifactRoot) {
20606
20957
  state.sourceArtifacts.map((artifact) => sourceArtifactToJson(artifact))
20607
20958
  )
20608
20959
  );
20609
- const sectionIntentsPath = joinPosix9(intermediateDir, "section-intents.json");
20960
+ const sectionIntentsPath = joinPosix11(intermediateDir, "section-intents.json");
20610
20961
  fileSystem.writeTextFile(
20611
20962
  sectionIntentsPath,
20612
20963
  dumpsSorted(
20613
20964
  state.sectionIntents.map((intent) => sectionIntentToJson(intent))
20614
20965
  )
20615
20966
  );
20616
- const plannedEmissionsPath = joinPosix9(
20967
+ const plannedEmissionsPath = joinPosix11(
20617
20968
  intermediateDir,
20618
20969
  "planned-emissions.json"
20619
20970
  );
@@ -20623,7 +20974,7 @@ function writeIntermediateStateArtifacts(fileSystem, state, artifactRoot) {
20623
20974
  state.plannedEmissions.map((emission) => plannedEmissionToJson(emission))
20624
20975
  )
20625
20976
  );
20626
- const translationTracesPath = joinPosix9(
20977
+ const translationTracesPath = joinPosix11(
20627
20978
  intermediateDir,
20628
20979
  "translation-traces.json"
20629
20980
  );
@@ -20955,7 +21306,7 @@ function collapseSegments2(value) {
20955
21306
  }
20956
21307
  return isAbsolute2 ? `/${joined}` : joined;
20957
21308
  }
20958
- function joinPosix10(root, child) {
21309
+ function joinPosix12(root, child) {
20959
21310
  const normalizedRoot = root.replace(/\/+$/, "");
20960
21311
  const normalizedChild = child.replace(/^\/+/, "");
20961
21312
  return normalizedRoot === "" ? normalizedChild : `${normalizedRoot}/${normalizedChild}`;
@@ -20981,11 +21332,11 @@ function sortFindings(validationFindings) {
20981
21332
  }
20982
21333
  function writeConversionReportSet(fileSystem, runOptions, mappingRecords, topologyEdges, translationTraces, validationFindings, generatedOutput) {
20983
21334
  const artifactRoot = collapseSegments2(runOptions.artifactRoot);
20984
- const proposedTreeRoot = joinPosix10(artifactRoot, "proposed-tree");
21335
+ const proposedTreeRoot = joinPosix12(artifactRoot, "proposed-tree");
20985
21336
  const reportPaths = {
20986
- conversionReport: joinPosix10(artifactRoot, "conversion-report.md"),
20987
- mappingCatalog: joinPosix10(artifactRoot, "mapping-catalog.json"),
20988
- validationResults: joinPosix10(artifactRoot, "validation-results.json"),
21337
+ conversionReport: joinPosix12(artifactRoot, "conversion-report.md"),
21338
+ mappingCatalog: joinPosix12(artifactRoot, "mapping-catalog.json"),
21339
+ validationResults: joinPosix12(artifactRoot, "validation-results.json"),
20989
21340
  proposedTreeRoot
20990
21341
  };
20991
21342
  fileSystem.ensureDir(artifactRoot);
@@ -21018,7 +21369,7 @@ function writeConversionReportSet(fileSystem, runOptions, mappingRecords, topolo
21018
21369
  (left, right) => left < right ? -1 : left > right ? 1 : 0
21019
21370
  )) {
21020
21371
  fileSystem.writeTextFile(
21021
- joinPosix10(proposedTreeRoot, targetPath),
21372
+ joinPosix12(proposedTreeRoot, targetPath),
21022
21373
  generatedOutput[targetPath] ?? ""
21023
21374
  );
21024
21375
  }
@@ -21435,6 +21786,278 @@ var SubprocessRunner = class {
21435
21786
  // ../../extensions/drm-copilot/src/lib/validate/validate-orchestration-service-call.ts
21436
21787
  var path8 = __toESM(require("node:path"));
21437
21788
 
21789
+ // ../../extensions/drm-copilot/src/lib/validate/epic-orchestrator-state-core.ts
21790
+ var REQUIRED_BASELINE_KEYS = [
21791
+ "objective",
21792
+ "completed_steps",
21793
+ "next_step",
21794
+ "last_updated"
21795
+ ];
21796
+ var REQUIRED_EPIC_KEYS = [
21797
+ "route_id",
21798
+ "epic_feature_folder",
21799
+ "integration_branch",
21800
+ "waves",
21801
+ "features"
21802
+ ];
21803
+ var EXPECTED_ROUTE_ID = "epic";
21804
+ var VALID_MERGE_STATUS = /* @__PURE__ */ new Set([
21805
+ "not_started",
21806
+ "worktree_created",
21807
+ "pr_open",
21808
+ "ci_green",
21809
+ "merge_conflict",
21810
+ "blocked_conflict_loop_limit",
21811
+ "merged",
21812
+ "worktree_removed"
21813
+ ]);
21814
+ var MERGED_STATUSES = /* @__PURE__ */ new Set([
21815
+ "merged",
21816
+ "worktree_removed"
21817
+ ]);
21818
+ function isObject2(value) {
21819
+ return typeof value === "object" && value !== null && !Array.isArray(value);
21820
+ }
21821
+ function extractFeatures(state) {
21822
+ const features = state["features"];
21823
+ if (!Array.isArray(features)) {
21824
+ return [];
21825
+ }
21826
+ return features.filter(isObject2);
21827
+ }
21828
+ function missingBaselineAndEpicKeys(state) {
21829
+ const errors = [];
21830
+ for (const key of [...REQUIRED_BASELINE_KEYS, ...REQUIRED_EPIC_KEYS]) {
21831
+ if (!(key in state)) {
21832
+ errors.push(`Epic checkpoint missing required key: ${key}`);
21833
+ }
21834
+ }
21835
+ return errors;
21836
+ }
21837
+ function validateRouteId(state) {
21838
+ if ("route_id" in state && state["route_id"] !== EXPECTED_ROUTE_ID) {
21839
+ return [
21840
+ `Epic checkpoint route_id must be 'epic', found: ${JSON.stringify(state["route_id"])}`
21841
+ ];
21842
+ }
21843
+ return [];
21844
+ }
21845
+ function validateFeatureFolderUniquenessAndDependencies(features) {
21846
+ const errors = [];
21847
+ const seen = /* @__PURE__ */ new Set();
21848
+ const duplicates = /* @__PURE__ */ new Set();
21849
+ const allFolders = /* @__PURE__ */ new Set();
21850
+ for (const feature of features) {
21851
+ const folder = feature["feature_folder"];
21852
+ if (typeof folder === "string" && folder) {
21853
+ allFolders.add(folder);
21854
+ }
21855
+ }
21856
+ for (const feature of features) {
21857
+ const folder = feature["feature_folder"];
21858
+ if (typeof folder !== "string" || !folder) {
21859
+ continue;
21860
+ }
21861
+ if (seen.has(folder)) {
21862
+ duplicates.add(folder);
21863
+ }
21864
+ seen.add(folder);
21865
+ const dependsOn = feature["depends_on"];
21866
+ if (!Array.isArray(dependsOn)) {
21867
+ continue;
21868
+ }
21869
+ for (const dependency of dependsOn) {
21870
+ if (!allFolders.has(dependency)) {
21871
+ errors.push(
21872
+ `Epic checkpoint feature '${folder}' depends_on unresolved feature_folder: ${JSON.stringify(dependency)}`
21873
+ );
21874
+ }
21875
+ }
21876
+ }
21877
+ for (const folder of [...duplicates].sort()) {
21878
+ errors.push(
21879
+ `Epic checkpoint has duplicate features[].feature_folder: ${folder}`
21880
+ );
21881
+ }
21882
+ return errors;
21883
+ }
21884
+ function detectDependencyCycle(features) {
21885
+ const graph = /* @__PURE__ */ new Map();
21886
+ for (const feature of features) {
21887
+ const folder = feature["feature_folder"];
21888
+ if (typeof folder !== "string" || !folder) {
21889
+ continue;
21890
+ }
21891
+ const dependsOn = feature["depends_on"];
21892
+ graph.set(
21893
+ folder,
21894
+ Array.isArray(dependsOn) ? dependsOn.filter(
21895
+ (d) => typeof d === "string"
21896
+ ) : []
21897
+ );
21898
+ }
21899
+ const visiting = /* @__PURE__ */ new Set();
21900
+ const visited = /* @__PURE__ */ new Set();
21901
+ function visit(node) {
21902
+ if (visiting.has(node)) {
21903
+ return node;
21904
+ }
21905
+ if (visited.has(node) || !graph.has(node)) {
21906
+ return null;
21907
+ }
21908
+ visiting.add(node);
21909
+ for (const dependency of graph.get(node) ?? []) {
21910
+ const cycleNode = visit(dependency);
21911
+ if (cycleNode !== null) {
21912
+ return cycleNode;
21913
+ }
21914
+ }
21915
+ visiting.delete(node);
21916
+ visited.add(node);
21917
+ return null;
21918
+ }
21919
+ for (const start of graph.keys()) {
21920
+ const cycleNode = visit(start);
21921
+ if (cycleNode !== null) {
21922
+ return `Epic checkpoint depends_on graph contains a cycle involving feature_folder: ${cycleNode}`;
21923
+ }
21924
+ }
21925
+ return null;
21926
+ }
21927
+ function validateMergeStatusEnum(features) {
21928
+ const errors = [];
21929
+ for (const feature of features) {
21930
+ const folder = feature["feature_folder"] ?? "<unknown>";
21931
+ const mergeStatus = feature["merge_status"];
21932
+ if (mergeStatus !== void 0 && mergeStatus !== null && !(typeof mergeStatus === "string" && VALID_MERGE_STATUS.has(mergeStatus))) {
21933
+ errors.push(
21934
+ `Epic checkpoint feature '${String(folder)}' has invalid merge_status: ${JSON.stringify(mergeStatus)}`
21935
+ );
21936
+ }
21937
+ }
21938
+ return errors;
21939
+ }
21940
+ function validateWaveBarrierOrdering(features) {
21941
+ const errors = [];
21942
+ const byFolder = /* @__PURE__ */ new Map();
21943
+ for (const feature of features) {
21944
+ const folder = feature["feature_folder"];
21945
+ if (typeof folder === "string") {
21946
+ byFolder.set(folder, feature);
21947
+ }
21948
+ }
21949
+ for (const feature of features) {
21950
+ const folder = feature["feature_folder"];
21951
+ const dependsOn = feature["depends_on"];
21952
+ if (typeof folder !== "string" || !Array.isArray(dependsOn)) {
21953
+ continue;
21954
+ }
21955
+ const worktreeCreatedAt = feature["worktree_created_at"];
21956
+ for (const dependency of dependsOn) {
21957
+ const dependencyFeature = byFolder.get(dependency);
21958
+ if (dependencyFeature === void 0) {
21959
+ continue;
21960
+ }
21961
+ const depMergeStatus = dependencyFeature["merge_status"];
21962
+ const depConfirmedAt = dependencyFeature["merge_confirmed_at"];
21963
+ const statusViolation = typeof depMergeStatus !== "string" || !MERGED_STATUSES.has(depMergeStatus);
21964
+ const timingViolation = typeof depConfirmedAt === "string" && typeof worktreeCreatedAt === "string" && depConfirmedAt > worktreeCreatedAt;
21965
+ if (statusViolation || timingViolation) {
21966
+ errors.push(
21967
+ `EPIC_WAVE_BARRIER_VIOLATION: ${folder} started before dependency ${String(dependency)} merged`
21968
+ );
21969
+ }
21970
+ }
21971
+ }
21972
+ return errors;
21973
+ }
21974
+ function validateWavesConsistency(state) {
21975
+ const errors = [];
21976
+ const waves = state["waves"];
21977
+ if (!Array.isArray(waves)) {
21978
+ return errors;
21979
+ }
21980
+ const featuresByFolder = /* @__PURE__ */ new Map();
21981
+ for (const feature of extractFeatures(state)) {
21982
+ const folder = feature["feature_folder"];
21983
+ if (typeof folder === "string") {
21984
+ featuresByFolder.set(folder, feature);
21985
+ }
21986
+ }
21987
+ for (const waveItem of waves) {
21988
+ if (!isObject2(waveItem)) {
21989
+ continue;
21990
+ }
21991
+ const waveNumber = waveItem["wave_number"];
21992
+ const folders = waveItem["feature_folders"];
21993
+ if (!Array.isArray(folders)) {
21994
+ continue;
21995
+ }
21996
+ for (const folder of folders) {
21997
+ const feature = featuresByFolder.get(folder);
21998
+ if (feature === void 0) {
21999
+ continue;
22000
+ }
22001
+ if (feature["wave_number"] !== waveNumber) {
22002
+ errors.push(
22003
+ `Epic checkpoint waves[] lists '${String(folder)}' under wave ${String(waveNumber)} but its own wave_number is ${JSON.stringify(feature["wave_number"])}`
22004
+ );
22005
+ }
22006
+ }
22007
+ }
22008
+ return errors;
22009
+ }
22010
+ function validateCompletion(features, state) {
22011
+ const errors = [];
22012
+ for (const feature of features) {
22013
+ const folder = feature["feature_folder"] ?? "<unknown>";
22014
+ const mergeStatus = feature["merge_status"];
22015
+ if (typeof mergeStatus !== "string" || !MERGED_STATUSES.has(mergeStatus)) {
22016
+ errors.push(
22017
+ `Epic checkpoint completion validation failed: feature '${String(folder)}' merge_status is not merged/worktree_removed.`
22018
+ );
22019
+ }
22020
+ }
22021
+ const epicMergePr = state["epic_merge_pr"];
22022
+ const mergeCommitSha = isObject2(epicMergePr) ? epicMergePr["merge_commit_sha"] : void 0;
22023
+ if (typeof mergeCommitSha !== "string" || !mergeCommitSha.trim()) {
22024
+ errors.push(
22025
+ "Epic checkpoint completion validation failed: epic_merge_pr.merge_commit_sha is missing or empty."
22026
+ );
22027
+ }
22028
+ return errors;
22029
+ }
22030
+ function validateEpicOrchestratorStateText(text, options = {}) {
22031
+ let state;
22032
+ try {
22033
+ state = JSON.parse(text);
22034
+ } catch (exc) {
22035
+ return [
22036
+ `Epic checkpoint is not valid JSON: ${exc instanceof Error ? exc.message : String(exc)}`
22037
+ ];
22038
+ }
22039
+ if (!isObject2(state)) {
22040
+ return ["Epic checkpoint root must be a JSON object."];
22041
+ }
22042
+ const stateMap = state;
22043
+ const errors = [];
22044
+ errors.push(...missingBaselineAndEpicKeys(stateMap));
22045
+ errors.push(...validateRouteId(stateMap));
22046
+ const features = extractFeatures(stateMap);
22047
+ errors.push(...validateFeatureFolderUniquenessAndDependencies(features));
22048
+ const cycleError = detectDependencyCycle(features);
22049
+ if (cycleError !== null) {
22050
+ errors.push(cycleError);
22051
+ }
22052
+ errors.push(...validateMergeStatusEnum(features));
22053
+ errors.push(...validateWaveBarrierOrdering(features));
22054
+ errors.push(...validateWavesConsistency(stateMap));
22055
+ if (options.requireComplete === true) {
22056
+ errors.push(...validateCompletion(features, stateMap));
22057
+ }
22058
+ return errors;
22059
+ }
22060
+
21438
22061
  // ../../extensions/drm-copilot/src/lib/validate/orchestrator-state-completion.ts
21439
22062
  var ISSUE_232 = "232";
21440
22063
  var ISSUE_232_BRANCH = "feature/harden-orchestrate-skill-232";
@@ -21451,11 +22074,11 @@ var PROMOTION_RECEIPT_KEYS = [
21451
22074
  "issue",
21452
22075
  "feature_folder"
21453
22076
  ];
21454
- function isObject2(value) {
22077
+ function isObject3(value) {
21455
22078
  return typeof value === "object" && value !== null && !Array.isArray(value);
21456
22079
  }
21457
22080
  function missingObjectKeys(value, keys) {
21458
- if (!isObject2(value)) {
22081
+ if (!isObject3(value)) {
21459
22082
  return [...keys];
21460
22083
  }
21461
22084
  const missing = [];
@@ -21470,7 +22093,7 @@ function missingObjectKeys(value, keys) {
21470
22093
  function validateCompletionPrGate(state) {
21471
22094
  const prGate = state["pr_gate"];
21472
22095
  const missing = missingObjectKeys(prGate, PR_GATE_KEYS);
21473
- if (!isObject2(prGate)) {
22096
+ if (!isObject3(prGate)) {
21474
22097
  return [
21475
22098
  `Checkpoint completion validation failed: pr_gate must be an object with keys: ${PR_GATE_KEYS.join(", ")}.`
21476
22099
  ];
@@ -21493,7 +22116,7 @@ function validateCompletionPrGate(state) {
21493
22116
  function validateCompletionCiGate(state) {
21494
22117
  const ciGate = state["ci_gate"];
21495
22118
  const missing = missingObjectKeys(ciGate, CI_GATE_KEYS);
21496
- if (!isObject2(ciGate)) {
22119
+ if (!isObject3(ciGate)) {
21497
22120
  return [
21498
22121
  `Checkpoint completion validation failed: ci_gate must be an object with keys: ${CI_GATE_KEYS.join(", ")}.`
21499
22122
  ];
@@ -21510,7 +22133,7 @@ function validateCompletionCiGate(state) {
21510
22133
  );
21511
22134
  }
21512
22135
  const prGate = state["pr_gate"];
21513
- const prHeadSha = isObject2(prGate) ? prGate["head_sha"] : null;
22136
+ const prHeadSha = isObject3(prGate) ? prGate["head_sha"] : null;
21514
22137
  if (prHeadSha !== null && prHeadSha !== void 0 && ciGate["head_sha"] !== prHeadSha) {
21515
22138
  errors.push(
21516
22139
  "Checkpoint completion validation failed: ci_gate.head_sha must match pr_gate.head_sha."
@@ -21525,7 +22148,7 @@ function validateIssue232PromotionReceipts(state) {
21525
22148
  const receipts = state["delegation_receipts"];
21526
22149
  let promotionSource = "promotion_receipts";
21527
22150
  let promotion = state["promotion_receipts"];
21528
- if (isObject2(receipts)) {
22151
+ if (isObject3(receipts)) {
21529
22152
  const namespacedPromotion = receipts[PROMOTION_RECEIPT_NAMESPACE_KEY];
21530
22153
  if (namespacedPromotion !== void 0 && namespacedPromotion !== null) {
21531
22154
  promotionSource = "delegation_receipts.promotion";
@@ -21550,7 +22173,7 @@ var HUMAN_INTERACTION_RESPONSE_ENUM = /* @__PURE__ */ new Set([
21550
22173
  "halt"
21551
22174
  ]);
21552
22175
  var HUMAN_INTERACTION_EXCEPTION_RESPONSE = "exception";
21553
- function isObject3(value) {
22176
+ function isObject4(value) {
21554
22177
  return typeof value === "object" && value !== null && !Array.isArray(value);
21555
22178
  }
21556
22179
  function pythonRepr(value) {
@@ -21567,7 +22190,7 @@ function pythonRepr(value) {
21567
22190
  }
21568
22191
  function validateHumanInteraction(humanInteraction) {
21569
22192
  const errors = [];
21570
- if (!isObject3(humanInteraction)) {
22193
+ if (!isObject4(humanInteraction)) {
21571
22194
  errors.push("Checkpoint human_interaction must be an object when present.");
21572
22195
  return errors;
21573
22196
  }
@@ -21577,7 +22200,7 @@ function validateHumanInteraction(humanInteraction) {
21577
22200
  return errors;
21578
22201
  }
21579
22202
  requirements.forEach((requirement, index) => {
21580
- if (!isObject3(requirement)) {
22203
+ if (!isObject4(requirement)) {
21581
22204
  errors.push(
21582
22205
  `Checkpoint human_interaction.requirements #${index} must be an object.`
21583
22206
  );
@@ -21607,7 +22230,7 @@ var REMEDIATION_LOOP_KEY = "remediation_loop";
21607
22230
  var REMEDIATION_CYCLES_KEY = "cycles";
21608
22231
  var EXECUTION_STATUSES_REQUIRING_CLEAR_PREFLIGHT = /* @__PURE__ */ new Set(["in_progress", "complete", "failed"]);
21609
22232
  var PREFLIGHT_CLEARED_STATUS = "clear";
21610
- function isObject4(value) {
22233
+ function isObject5(value) {
21611
22234
  return typeof value === "object" && value !== null && !Array.isArray(value);
21612
22235
  }
21613
22236
  function validateRemediationCycle(index, cycle) {
@@ -21621,7 +22244,7 @@ function validateRemediationCycle(index, cycle) {
21621
22244
  const executionStatus = cycle["execution_status"];
21622
22245
  if (typeof executionStatus === "string" && EXECUTION_STATUSES_REQUIRING_CLEAR_PREFLIGHT.has(executionStatus)) {
21623
22246
  const preflight = cycle["preflight"];
21624
- const preflightStatus = isObject4(preflight) ? preflight["final_status"] : void 0;
22247
+ const preflightStatus = isObject5(preflight) ? preflight["final_status"] : void 0;
21625
22248
  if (preflightStatus !== PREFLIGHT_CLEARED_STATUS) {
21626
22249
  errors.push(
21627
22250
  `Checkpoint remediation cycle #${index} execution_status is ${executionStatus} but preflight.final_status is not 'clear'.`
@@ -21637,7 +22260,7 @@ function validateRemediationCycle(index, cycle) {
21637
22260
  }
21638
22261
  function validateRemediationLoop(remediationLoop) {
21639
22262
  const errors = [];
21640
- if (!isObject4(remediationLoop)) {
22263
+ if (!isObject5(remediationLoop)) {
21641
22264
  return errors;
21642
22265
  }
21643
22266
  const cycles = remediationLoop[REMEDIATION_CYCLES_KEY];
@@ -21645,7 +22268,7 @@ function validateRemediationLoop(remediationLoop) {
21645
22268
  return errors;
21646
22269
  }
21647
22270
  cycles.forEach((cycle, index) => {
21648
- if (!isObject4(cycle)) {
22271
+ if (!isObject5(cycle)) {
21649
22272
  errors.push(`Checkpoint remediation cycle #${index} must be an object.`);
21650
22273
  return;
21651
22274
  }
@@ -21656,7 +22279,7 @@ function validateRemediationLoop(remediationLoop) {
21656
22279
 
21657
22280
  // ../../extensions/drm-copilot/src/lib/validate/orchestrator-state-routing.ts
21658
22281
  var ROUTING_MATRIX_RELATIVE_PATH = "config/orchestration-routing.json";
21659
- function isObject5(value) {
22282
+ function isObject6(value) {
21660
22283
  return typeof value === "object" && value !== null && !Array.isArray(value);
21661
22284
  }
21662
22285
  function loadRoutingMatrix(fs9, root) {
@@ -21693,7 +22316,7 @@ function listReceipts(receipts) {
21693
22316
  if (!Array.isArray(receipts)) {
21694
22317
  return [];
21695
22318
  }
21696
- return receipts.filter(isObject5);
22319
+ return receipts.filter(isObject6);
21697
22320
  }
21698
22321
  function receiptAgents(state) {
21699
22322
  const agents = /* @__PURE__ */ new Set();
@@ -21712,7 +22335,7 @@ function receiptSkills(state) {
21712
22335
  return skills;
21713
22336
  }
21714
22337
  for (const receipt of receipts) {
21715
- if (!isObject5(receipt)) {
22338
+ if (!isObject6(receipt)) {
21716
22339
  continue;
21717
22340
  }
21718
22341
  const skill = receipt["skill"];
@@ -21731,7 +22354,7 @@ function mcpTools(state) {
21731
22354
  return tools;
21732
22355
  }
21733
22356
  for (const receipt of receipts) {
21734
- if (!isObject5(receipt)) {
22357
+ if (!isObject6(receipt)) {
21735
22358
  continue;
21736
22359
  }
21737
22360
  const tool = receipt["tool"];
@@ -21763,7 +22386,7 @@ function validateLifecycleOperations(state) {
21763
22386
  }
21764
22387
  const errors = [];
21765
22388
  operations.forEach((operation, index) => {
21766
- if (!isObject5(operation)) {
22389
+ if (!isObject6(operation)) {
21767
22390
  errors.push(
21768
22391
  `Checkpoint lifecycle_operations #${index} must be an object.`
21769
22392
  );
@@ -21779,11 +22402,11 @@ function validateLifecycleOperations(state) {
21779
22402
  }
21780
22403
  function validateRoutingContract(state, options = {}) {
21781
22404
  const matrix = options.routingMatrix;
21782
- if (!isObject5(matrix)) {
22405
+ if (!isObject6(matrix)) {
21783
22406
  return ["Routing matrix missing routes object."];
21784
22407
  }
21785
22408
  const rawRoutes = matrix["routes"];
21786
- if (!isObject5(rawRoutes)) {
22409
+ if (!isObject6(rawRoutes)) {
21787
22410
  return ["Routing matrix missing routes object."];
21788
22411
  }
21789
22412
  const routeIdValue = state["route_id"] !== void 0 ? state["route_id"] : state["path_selected"];
@@ -21792,7 +22415,7 @@ function validateRoutingContract(state, options = {}) {
21792
22415
  }
21793
22416
  const routeId = routeIdValue;
21794
22417
  const rawRoute = rawRoutes[routeId];
21795
- if (!isObject5(rawRoute)) {
22418
+ if (!isObject6(rawRoute)) {
21796
22419
  return [
21797
22420
  `Checkpoint selected route has no routing-matrix entry: ${routeId}.`
21798
22421
  ];
@@ -21902,13 +22525,21 @@ var STEP_STATUS_KEYS = [
21902
22525
  "step9_status",
21903
22526
  "step10_status"
21904
22527
  ];
21905
- function isObject6(value) {
22528
+ var DELEGATING_AGENTS = /* @__PURE__ */ new Set([
22529
+ "atomic-planner",
22530
+ "atomic-executor",
22531
+ "feature-review",
22532
+ "task-researcher",
22533
+ "prd-feature",
22534
+ "pr-author"
22535
+ ]);
22536
+ function isObject7(value) {
21906
22537
  return typeof value === "object" && value !== null && !Array.isArray(value);
21907
22538
  }
21908
22539
  function validateListDelegationReceipts(receipts) {
21909
22540
  const errors = [];
21910
22541
  receipts.forEach((receipt, index) => {
21911
- if (!isObject6(receipt)) {
22542
+ if (!isObject7(receipt)) {
21912
22543
  errors.push(`Checkpoint delegation receipt #${index} must be an object.`);
21913
22544
  return;
21914
22545
  }
@@ -21940,7 +22571,7 @@ function validateNamespacedDelegationReceipts(receipts) {
21940
22571
  if (promotionReceipts === void 0 || promotionReceipts === null) {
21941
22572
  return errors;
21942
22573
  }
21943
- if (!isObject6(promotionReceipts)) {
22574
+ if (!isObject7(promotionReceipts)) {
21944
22575
  errors.push(
21945
22576
  "Checkpoint delegation_receipts.promotion must be an object namespace."
21946
22577
  );
@@ -21965,6 +22596,53 @@ function resolveRoutingMatrix(options) {
21965
22596
  }
21966
22597
  return void 0;
21967
22598
  }
22599
+ function delegatedAgents(stateMap) {
22600
+ const agents = /* @__PURE__ */ new Set();
22601
+ const receipts = stateMap["delegation_receipts"];
22602
+ if (Array.isArray(receipts)) {
22603
+ receipts.forEach((receipt) => {
22604
+ if (!isObject7(receipt)) {
22605
+ return;
22606
+ }
22607
+ const agentName = receipt["agent_name"];
22608
+ if (typeof agentName === "string" && agentName.trim() !== "") {
22609
+ agents.add(agentName);
22610
+ }
22611
+ });
22612
+ }
22613
+ const nextStep = stateMap["next_step"];
22614
+ if (typeof nextStep === "string" && DELEGATING_AGENTS.has(nextStep)) {
22615
+ agents.add(nextStep);
22616
+ }
22617
+ return agents;
22618
+ }
22619
+ function validateModelRoutingExistence(stateMap) {
22620
+ const errors = [];
22621
+ const delegated = delegatedAgents(stateMap);
22622
+ if (delegated.size === 0) {
22623
+ return errors;
22624
+ }
22625
+ const receiptAgents2 = /* @__PURE__ */ new Set();
22626
+ const receipts = stateMap["model_routing_receipts"];
22627
+ if (Array.isArray(receipts)) {
22628
+ receipts.forEach((receipt) => {
22629
+ if (!isObject7(receipt)) {
22630
+ return;
22631
+ }
22632
+ const agent = receipt["agent"];
22633
+ if (typeof agent === "string" && agent.trim() !== "") {
22634
+ receiptAgents2.add(agent);
22635
+ }
22636
+ });
22637
+ }
22638
+ const missing = [...delegated].filter((a) => !receiptAgents2.has(a)).sort();
22639
+ for (const agent of missing) {
22640
+ errors.push(
22641
+ `Checkpoint model_routing_receipts is missing a receipt for delegated agent: ${agent}.`
22642
+ );
22643
+ }
22644
+ return errors;
22645
+ }
21968
22646
  function validateOrchestratorStateText(text, options = {}) {
21969
22647
  const errors = [];
21970
22648
  let state;
@@ -21975,7 +22653,7 @@ function validateOrchestratorStateText(text, options = {}) {
21975
22653
  `Checkpoint is not valid JSON: ${exc instanceof Error ? exc.message : String(exc)}`
21976
22654
  ];
21977
22655
  }
21978
- if (!isObject6(state)) {
22656
+ if (!isObject7(state)) {
21979
22657
  return ["Checkpoint root must be a JSON object."];
21980
22658
  }
21981
22659
  const stateMap = state;
@@ -22000,7 +22678,7 @@ function validateOrchestratorStateText(text, options = {}) {
22000
22678
  if (receipts !== void 0 && receipts !== null) {
22001
22679
  if (Array.isArray(receipts)) {
22002
22680
  errors.push(...validateListDelegationReceipts(receipts));
22003
- } else if (isObject6(receipts)) {
22681
+ } else if (isObject7(receipts)) {
22004
22682
  errors.push(...validateNamespacedDelegationReceipts(receipts));
22005
22683
  } else {
22006
22684
  errors.push(
@@ -22038,6 +22716,9 @@ function validateOrchestratorStateText(text, options = {}) {
22038
22716
  })
22039
22717
  );
22040
22718
  }
22719
+ if (options.requireModelRouting === true) {
22720
+ errors.push(...validateModelRoutingExistence(stateMap));
22721
+ }
22041
22722
  return errors;
22042
22723
  }
22043
22724
 
@@ -22412,12 +23093,19 @@ function validateArtifact(input) {
22412
23093
  case "orchestrator-state": {
22413
23094
  const options = {
22414
23095
  ...input.requireComplete === void 0 ? {} : { requireComplete: input.requireComplete },
23096
+ ...input.requireModelRouting === void 0 ? {} : { requireModelRouting: input.requireModelRouting },
22415
23097
  ...input.fs === void 0 ? {} : { fs: input.fs },
22416
23098
  ...input.root === void 0 ? {} : { root: input.root },
22417
23099
  ...input.routingMatrix === void 0 ? {} : { routingMatrix: input.routingMatrix }
22418
23100
  };
22419
23101
  return validateOrchestratorStateText(input.text, options);
22420
23102
  }
23103
+ case "epic-orchestrator-state": {
23104
+ const options = {
23105
+ ...input.requireComplete === void 0 ? {} : { requireComplete: input.requireComplete }
23106
+ };
23107
+ return validateEpicOrchestratorStateText(input.text, options);
23108
+ }
22421
23109
  default:
22422
23110
  return [`Unsupported artifact type: ${input.artifactType}`];
22423
23111
  }
@@ -22433,6 +23121,7 @@ function validateOrchestrationServiceCall(input) {
22433
23121
  artifactType: input.artifactType,
22434
23122
  text,
22435
23123
  ...input.requireComplete === void 0 ? {} : { requireComplete: input.requireComplete },
23124
+ ...input.requireModelRouting === void 0 ? {} : { requireModelRouting: input.requireModelRouting },
22436
23125
  fs: input.fileSystem,
22437
23126
  root: input.workspaceRoot
22438
23127
  });
@@ -22449,6 +23138,18 @@ ${errors.join("\n")}`
22449
23138
  };
22450
23139
  }
22451
23140
 
23141
+ // ../../extensions/drm-copilot/src/lib/validate/build-validate-orchestration-service-call-input.ts
23142
+ function buildValidateOrchestrationServiceCallInput(fileSystem, input) {
23143
+ return {
23144
+ fileSystem,
23145
+ workspaceRoot: input.workspaceRoot,
23146
+ artifactType: input.artifactType,
23147
+ artifactPath: input.artifactPath,
23148
+ ...input.requireComplete === void 0 ? {} : { requireComplete: input.requireComplete },
23149
+ ...input.requireModelRouting === void 0 ? {} : { requireModelRouting: input.requireModelRouting }
23150
+ };
23151
+ }
23152
+
22452
23153
  // ../../extensions/drm-copilot/src/lib/new-potential-bug-entry.ts
22453
23154
  var fs5 = __toESM(require("node:fs"));
22454
23155
  var nodePath4 = __toESM(require("node:path"));
@@ -23969,7 +24670,7 @@ function resolveReadinessSignal(fs9, featureDir) {
23969
24670
  }
23970
24671
  return [null, null];
23971
24672
  }
23972
- function relativeToPosix3(root, path10) {
24673
+ function relativeToPosix4(root, path10) {
23973
24674
  const normalizedRoot = toPosixPath2(root).replace(/\/+$/u, "");
23974
24675
  const normalized = toPosixPath2(path10);
23975
24676
  if (normalized.startsWith(`${normalizedRoot}/`)) {
@@ -24007,7 +24708,7 @@ function discoverCanonicalEvidenceFiles(fs9, root, feature) {
24007
24708
  for (const pattern of CANONICAL_GLOBS) {
24008
24709
  for (const candidate of fs9.glob(featureRoot, pattern)) {
24009
24710
  if (fs9.isFile(candidate)) {
24010
- discovered.add(relativeToPosix4(normalizedRoot, candidate));
24711
+ discovered.add(relativeToPosix5(normalizedRoot, candidate));
24011
24712
  }
24012
24713
  }
24013
24714
  }
@@ -24078,7 +24779,7 @@ function parseIntegerStrict(value) {
24078
24779
  }
24079
24780
  return Number.parseInt(value, 10);
24080
24781
  }
24081
- function relativeToPosix4(root, absolute) {
24782
+ function relativeToPosix5(root, absolute) {
24082
24783
  const normalized = toPosixPath2(absolute);
24083
24784
  if (normalized.startsWith(`${root}/`)) {
24084
24785
  return normalized.slice(root.length + 1);
@@ -24117,7 +24818,7 @@ var SPEC_HEADINGS = [
24117
24818
  "Behavior",
24118
24819
  "Overview"
24119
24820
  ];
24120
- function extractFeatures(changedFiles) {
24821
+ function extractFeatures2(changedFiles) {
24121
24822
  const features = /* @__PURE__ */ new Set();
24122
24823
  for (const raw of changedFiles) {
24123
24824
  const parts = toPosixPath2(raw).split("/");
@@ -24129,7 +24830,7 @@ function extractFeatures(changedFiles) {
24129
24830
  }
24130
24831
  function gatherFeatureExcerpts2(fs9, root, changedFiles) {
24131
24832
  const normalizedRoot = toPosixPath2(root).replace(/\/+$/u, "");
24132
- const features = extractFeatures(changedFiles);
24833
+ const features = extractFeatures2(changedFiles);
24133
24834
  const excerpts = [];
24134
24835
  const baseDir = `${normalizedRoot}/docs/features/active`;
24135
24836
  const promotedDir = `${normalizedRoot}/docs/features/potential/promoted`;
@@ -24275,11 +24976,11 @@ function buildContextFiles(params) {
24275
24976
  const contextFiles = [];
24276
24977
  for (const path10 of candidatePaths) {
24277
24978
  if (fs9.exists(path10)) {
24278
- contextFiles.push(relativeToPosix3(root, path10));
24979
+ contextFiles.push(relativeToPosix4(root, path10));
24279
24980
  }
24280
24981
  }
24281
24982
  if (readinessSource !== null) {
24282
- contextFiles.push(relativeToPosix3(root, readinessSource));
24983
+ contextFiles.push(relativeToPosix4(root, readinessSource));
24283
24984
  }
24284
24985
  const evidenceContextFiles = discoverCanonicalEvidenceFiles(
24285
24986
  fs9,
@@ -25816,7 +26517,7 @@ var PLACEHOLDERS = [
25816
26517
  "<bug-name>"
25817
26518
  ];
25818
26519
  var PLAN_TIMESTAMP_TEMPLATE_NAME = "plan.yyyy-MM-ddTHH-mm.md";
25819
- function joinPosix11(root, relative2) {
26520
+ function joinPosix13(root, relative2) {
25820
26521
  const normalizedRoot = toPosixPath2(root).replace(/\/+$/, "");
25821
26522
  const normalizedRelative = toPosixPath2(relative2).replace(/^\/+/, "");
25822
26523
  if (normalizedRoot === "") {
@@ -25876,14 +26577,14 @@ var RealFolderFileSystem = class {
25876
26577
  return;
25877
26578
  }
25878
26579
  for (const entry of entries) {
25879
- const childAbs = joinPosix11(toPosixPath2(currentDir), entry.name);
26580
+ const childAbs = joinPosix13(toPosixPath2(currentDir), entry.name);
25880
26581
  if (entry.isDirectory()) {
25881
26582
  walk(childAbs);
25882
26583
  continue;
25883
26584
  }
25884
26585
  if (entry.isFile()) {
25885
26586
  const relative2 = childAbs.slice(normalizedSrc.length + 1);
25886
- this.copyFile(childAbs, joinPosix11(toPosixPath2(dest), relative2));
26587
+ this.copyFile(childAbs, joinPosix13(toPosixPath2(dest), relative2));
25887
26588
  }
25888
26589
  }
25889
26590
  };
@@ -25904,7 +26605,7 @@ var RealFolderFileSystem = class {
25904
26605
  const files = [];
25905
26606
  for (const entry of entries) {
25906
26607
  if (entry.isFile()) {
25907
- files.push(joinPosix11(toPosixPath2(path10), entry.name));
26608
+ files.push(joinPosix13(toPosixPath2(path10), entry.name));
25908
26609
  }
25909
26610
  }
25910
26611
  return files;
@@ -26289,8 +26990,8 @@ function stem(path10) {
26289
26990
  function findPotentialFile(featureName, workspace2, fs9) {
26290
26991
  const normalized = featureName.replace(/_/g, "-");
26291
26992
  const potentialDirs = [
26292
- joinPosix11(workspace2, "docs/features/potential"),
26293
- joinPosix11(workspace2, "docs/features/potential/promoted")
26993
+ joinPosix13(workspace2, "docs/features/potential"),
26994
+ joinPosix13(workspace2, "docs/features/potential/promoted")
26294
26995
  ];
26295
26996
  for (const directory of potentialDirs) {
26296
26997
  const candidates = fs9.listFiles(directory).filter(
@@ -26327,9 +27028,9 @@ function buildFolderSlug(featureName, potentialFile, issueNumber) {
26327
27028
  function copyTemplate(featureType, templateDir, targetDir, fs9) {
26328
27029
  if (featureType === "bug") {
26329
27030
  for (const name of ["spec.md", PLAN_TIMESTAMP_TEMPLATE_NAME, "plan.md"]) {
26330
- const src = joinPosix11(templateDir, name);
27031
+ const src = joinPosix13(templateDir, name);
26331
27032
  if (fs9.exists(src)) {
26332
- fs9.copyFile(src, joinPosix11(targetDir, name));
27033
+ fs9.copyFile(src, joinPosix13(targetDir, name));
26333
27034
  if (name === PLAN_TIMESTAMP_TEMPLATE_NAME) {
26334
27035
  break;
26335
27036
  }
@@ -26340,24 +27041,24 @@ function copyTemplate(featureType, templateDir, targetDir, fs9) {
26340
27041
  }
26341
27042
  }
26342
27043
  function copyFeatureTemplateForMinorAudit(templateDir, targetDir, fs9) {
26343
- const timestampedPlan = joinPosix11(templateDir, PLAN_TIMESTAMP_TEMPLATE_NAME);
27044
+ const timestampedPlan = joinPosix13(templateDir, PLAN_TIMESTAMP_TEMPLATE_NAME);
26344
27045
  if (fs9.exists(timestampedPlan)) {
26345
27046
  fs9.copyFile(
26346
27047
  timestampedPlan,
26347
- joinPosix11(targetDir, PLAN_TIMESTAMP_TEMPLATE_NAME)
27048
+ joinPosix13(targetDir, PLAN_TIMESTAMP_TEMPLATE_NAME)
26348
27049
  );
26349
27050
  return;
26350
27051
  }
26351
- const legacyPlan = joinPosix11(templateDir, "plan.md");
27052
+ const legacyPlan = joinPosix13(templateDir, "plan.md");
26352
27053
  if (fs9.exists(legacyPlan)) {
26353
- fs9.copyFile(legacyPlan, joinPosix11(targetDir, "plan.md"));
27054
+ fs9.copyFile(legacyPlan, joinPosix13(targetDir, "plan.md"));
26354
27055
  }
26355
27056
  }
26356
27057
  function materializePlanFile(featureType, targetDir, featureName, issueField, ownerField, parentField, statusField, versionField, planTimestamp, fs9) {
26357
27058
  void featureType;
26358
- const templatePlan = joinPosix11(targetDir, PLAN_TIMESTAMP_TEMPLATE_NAME);
27059
+ const templatePlan = joinPosix13(targetDir, PLAN_TIMESTAMP_TEMPLATE_NAME);
26359
27060
  if (fs9.exists(templatePlan)) {
26360
- const targetPlan = joinPosix11(targetDir, `plan.${planTimestamp}.md`);
27061
+ const targetPlan = joinPosix13(targetDir, `plan.${planTimestamp}.md`);
26361
27062
  fs9.move(templatePlan, targetPlan);
26362
27063
  let content = fs9.readText(targetPlan);
26363
27064
  const updatedField = planTimestamp;
@@ -26374,7 +27075,7 @@ function materializePlanFile(featureType, targetDir, featureName, issueField, ow
26374
27075
  fs9.writeText(targetPlan, content);
26375
27076
  return targetPlan;
26376
27077
  }
26377
- const legacy = joinPosix11(targetDir, "plan.md");
27078
+ const legacy = joinPosix13(targetDir, "plan.md");
26378
27079
  if (fs9.exists(legacy)) {
26379
27080
  return legacy;
26380
27081
  }
@@ -26444,9 +27145,9 @@ function updateFeatureDocs(featureType, featureName, targetDir, issueField, owne
26444
27145
  const filesToOpen = [];
26445
27146
  const get = (key) => sections[key] ?? "";
26446
27147
  if (featureType === "feature") {
26447
- const userStory = joinPosix11(targetDir, "user-story.md");
26448
- const spec = joinPosix11(targetDir, "spec.md");
26449
- const plan = planPath ?? joinPosix11(targetDir, "plan.md");
27148
+ const userStory = joinPosix13(targetDir, "user-story.md");
27149
+ const spec = joinPosix13(targetDir, "spec.md");
27150
+ const plan = planPath ?? joinPosix13(targetDir, "plan.md");
26450
27151
  applyHeaderAndSections(
26451
27152
  userStory,
26452
27153
  featureName,
@@ -26496,8 +27197,8 @@ function updateFeatureDocs(featureType, featureName, targetDir, issueField, owne
26496
27197
  );
26497
27198
  filesToOpen.push(userStory, spec, plan);
26498
27199
  } else if (featureType === "refactor") {
26499
- const spec = joinPosix11(targetDir, "spec.md");
26500
- const plan = planPath ?? joinPosix11(targetDir, "plan.md");
27200
+ const spec = joinPosix13(targetDir, "spec.md");
27201
+ const plan = planPath ?? joinPosix13(targetDir, "plan.md");
26501
27202
  applyHeaderAndSections(
26502
27203
  spec,
26503
27204
  featureName,
@@ -26532,7 +27233,7 @@ function updateFeatureDocs(featureType, featureName, targetDir, issueField, owne
26532
27233
  );
26533
27234
  filesToOpen.push(spec, plan);
26534
27235
  } else if (featureType === "epic") {
26535
- const initiative = joinPosix11(targetDir, "initiative.md");
27236
+ const initiative = joinPosix13(targetDir, "initiative.md");
26536
27237
  applyHeaderAndSections(
26537
27238
  initiative,
26538
27239
  featureName,
@@ -26547,8 +27248,8 @@ function updateFeatureDocs(featureType, featureName, targetDir, issueField, owne
26547
27248
  );
26548
27249
  filesToOpen.push(initiative);
26549
27250
  } else if (featureType === "bug") {
26550
- const spec = joinPosix11(targetDir, "spec.md");
26551
- const plan = planPath ?? joinPosix11(targetDir, "plan.md");
27251
+ const spec = joinPosix13(targetDir, "spec.md");
27252
+ const plan = planPath ?? joinPosix13(targetDir, "plan.md");
26552
27253
  const contextParts = [];
26553
27254
  if (get("bug_summary")) {
26554
27255
  contextParts.push(get("bug_summary"));
@@ -26669,9 +27370,9 @@ function createActiveFolder(options) {
26669
27370
  const autoResolveError = "Select a promoted issue markdown file under docs/features/potential/promoted or supply --feature-name directly.";
26670
27371
  let activeFilePath = toPosixPath2(options.activeFileForFeatureName);
26671
27372
  if (!isAbsolutePosix(activeFilePath)) {
26672
- activeFilePath = joinPosix11(workspacePath, activeFilePath);
27373
+ activeFilePath = joinPosix13(workspacePath, activeFilePath);
26673
27374
  }
26674
- const promotedRoot = joinPosix11(
27375
+ const promotedRoot = joinPosix13(
26675
27376
  workspacePath,
26676
27377
  "docs/features/potential/promoted"
26677
27378
  );
@@ -26689,7 +27390,7 @@ function createActiveFolder(options) {
26689
27390
  }
26690
27391
  validateFeatureName2(resolvedFeatureName);
26691
27392
  emit(`Feature name source: ${featureNameSource}`);
26692
- const templateDir = options.templateRoot !== void 0 && options.templateRoot !== null ? joinPosix11(options.templateRoot, featureType) : joinPosix11(workspacePath, `docs/features/templates/${featureType}`);
27393
+ const templateDir = options.templateRoot !== void 0 && options.templateRoot !== null ? joinPosix13(options.templateRoot, featureType) : joinPosix13(workspacePath, `docs/features/templates/${featureType}`);
26693
27394
  if (!filesystem.exists(templateDir)) {
26694
27395
  throw new Error(`Template folder not found: ${templateDir}`);
26695
27396
  }
@@ -26717,7 +27418,7 @@ function createActiveFolder(options) {
26717
27418
  potentialFile,
26718
27419
  normalizedIssueNumber
26719
27420
  );
26720
- const targetDir = joinPosix11(
27421
+ const targetDir = joinPosix13(
26721
27422
  workspacePath,
26722
27423
  `docs/features/active/${folderSlug}`
26723
27424
  );
@@ -26782,7 +27483,7 @@ function createActiveFolder(options) {
26782
27483
  let potentialIssuePath = null;
26783
27484
  if (useMinorAudit) {
26784
27485
  if (potentialFile) {
26785
- potentialIssuePath = joinPosix11(targetDir, "issue.md");
27486
+ potentialIssuePath = joinPosix13(targetDir, "issue.md");
26786
27487
  filesystem.move(potentialFile, potentialIssuePath);
26787
27488
  const movedContent = filesystem.readText(potentialIssuePath);
26788
27489
  filesystem.writeText(
@@ -26791,7 +27492,7 @@ function createActiveFolder(options) {
26791
27492
  );
26792
27493
  filesToOpen = [potentialIssuePath];
26793
27494
  } else {
26794
- const issueDoc = joinPosix11(targetDir, "issue.md");
27495
+ const issueDoc = joinPosix13(targetDir, "issue.md");
26795
27496
  const issueBody = [
26796
27497
  `# ${resolvedFeatureName}`,
26797
27498
  "",
@@ -26842,7 +27543,7 @@ function createActiveFolder(options) {
26842
27543
  emit(`Moved potential file to ${potentialIssuePath}`);
26843
27544
  }
26844
27545
  } else {
26845
- potentialIssuePath = joinPosix11(targetDir, "issue.md");
27546
+ potentialIssuePath = joinPosix13(targetDir, "issue.md");
26846
27547
  filesystem.move(potentialFile, potentialIssuePath);
26847
27548
  const movedContent = filesystem.readText(potentialIssuePath);
26848
27549
  filesystem.writeText(
@@ -26989,10 +27690,7 @@ var DefaultRepoAutomationService = class {
26989
27690
  );
26990
27691
  }
26991
27692
  async pushDownCodexAndAgentsCustomizations(input) {
26992
- return runPushDownCodexAndAgentsCustomizations(
26993
- input.workspaceRoot,
26994
- this.pushDownDeps
26995
- );
27693
+ return runPushDownCodexAndAgentsCustomizations(input, this.pushDownDeps);
26996
27694
  }
26997
27695
  async pushDownClaudeCustomizations(input) {
26998
27696
  return runPushDownClaudeCustomizations(input, this.pushDownDeps);
@@ -27093,13 +27791,9 @@ var DefaultRepoAutomationService = class {
27093
27791
  });
27094
27792
  }
27095
27793
  async validateOrchestrationArtifacts(input) {
27096
- return validateOrchestrationServiceCall({
27097
- fileSystem: this.fileSystem,
27098
- workspaceRoot: input.workspaceRoot,
27099
- artifactType: input.artifactType,
27100
- artifactPath: input.artifactPath,
27101
- ...input.requireComplete === void 0 ? {} : { requireComplete: input.requireComplete }
27102
- });
27794
+ return validateOrchestrationServiceCall(
27795
+ buildValidateOrchestrationServiceCallInput(this.fileSystem, input)
27796
+ );
27103
27797
  }
27104
27798
  async executeScript(options) {
27105
27799
  const execution = await executeBundledScriptFromExtensionRoot(this.output, {