@danmoisan/drm-copilot-mcp 1.0.10 → 1.0.13

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.
package/out/mcp-server.js CHANGED
@@ -3231,8 +3231,8 @@ var require_utils = __commonJS({
3231
3231
  }
3232
3232
  return ind;
3233
3233
  }
3234
- function removeDotSegments(path10) {
3235
- let input = path10;
3234
+ function removeDotSegments(path11) {
3235
+ let input = path11;
3236
3236
  const output = [];
3237
3237
  let nextSlash = -1;
3238
3238
  let len = 0;
@@ -3484,8 +3484,8 @@ var require_schemes = __commonJS({
3484
3484
  wsComponent.secure = void 0;
3485
3485
  }
3486
3486
  if (wsComponent.resourceName) {
3487
- const [path10, query] = wsComponent.resourceName.split("?");
3488
- wsComponent.path = path10 && path10 !== "/" ? path10 : void 0;
3487
+ const [path11, query] = wsComponent.resourceName.split("?");
3488
+ wsComponent.path = path11 && path11 !== "/" ? path11 : void 0;
3489
3489
  wsComponent.query = query;
3490
3490
  wsComponent.resourceName = void 0;
3491
3491
  }
@@ -6907,7 +6907,7 @@ __export(mcp_server_exports, {
6907
6907
  });
6908
6908
  module.exports = __toCommonJS(mcp_server_exports);
6909
6909
  var fs8 = __toESM(require("node:fs"));
6910
- var path9 = __toESM(require("node:path"));
6910
+ var path10 = __toESM(require("node:path"));
6911
6911
 
6912
6912
  // node_modules/zod/v4/core/core.js
6913
6913
  var _a;
@@ -7149,10 +7149,10 @@ function mergeDefs(...defs) {
7149
7149
  function cloneDef(schema) {
7150
7150
  return mergeDefs(schema._zod.def);
7151
7151
  }
7152
- function getElementAtPath(obj, path10) {
7153
- if (!path10)
7152
+ function getElementAtPath(obj, path11) {
7153
+ if (!path11)
7154
7154
  return obj;
7155
- return path10.reduce((acc, key) => acc?.[key], obj);
7155
+ return path11.reduce((acc, key) => acc?.[key], obj);
7156
7156
  }
7157
7157
  function promiseAllObject(promisesObj) {
7158
7158
  const keys = Object.keys(promisesObj);
@@ -7561,11 +7561,11 @@ function explicitlyAborted(x, startIndex = 0) {
7561
7561
  }
7562
7562
  return false;
7563
7563
  }
7564
- function prefixIssues(path10, issues) {
7564
+ function prefixIssues(path11, issues) {
7565
7565
  return issues.map((iss) => {
7566
7566
  var _a3;
7567
7567
  (_a3 = iss).path ?? (_a3.path = []);
7568
- iss.path.unshift(path10);
7568
+ iss.path.unshift(path11);
7569
7569
  return iss;
7570
7570
  });
7571
7571
  }
@@ -7712,16 +7712,16 @@ function flattenError(error2, mapper = (issue2) => issue2.message) {
7712
7712
  }
7713
7713
  function formatError(error2, mapper = (issue2) => issue2.message) {
7714
7714
  const fieldErrors = { _errors: [] };
7715
- const processError = (error3, path10 = []) => {
7715
+ const processError = (error3, path11 = []) => {
7716
7716
  for (const issue2 of error3.issues) {
7717
7717
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7718
- issue2.errors.map((issues) => processError({ issues }, [...path10, ...issue2.path]));
7718
+ issue2.errors.map((issues) => processError({ issues }, [...path11, ...issue2.path]));
7719
7719
  } else if (issue2.code === "invalid_key") {
7720
- processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
7720
+ processError({ issues: issue2.issues }, [...path11, ...issue2.path]);
7721
7721
  } else if (issue2.code === "invalid_element") {
7722
- processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
7722
+ processError({ issues: issue2.issues }, [...path11, ...issue2.path]);
7723
7723
  } else {
7724
- const fullpath = [...path10, ...issue2.path];
7724
+ const fullpath = [...path11, ...issue2.path];
7725
7725
  if (fullpath.length === 0) {
7726
7726
  fieldErrors._errors.push(mapper(issue2));
7727
7727
  } else {
@@ -8964,13 +8964,13 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
8964
8964
  }
8965
8965
  return propValues;
8966
8966
  });
8967
- const isObject8 = isObject;
8967
+ const isObject9 = 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 (!isObject8(input)) {
8973
+ if (!isObject9(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 isObject8 = isObject;
9100
+ const isObject9 = 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 (!isObject8(input)) {
9109
+ if (!isObject9(input)) {
9110
9110
  payload.issues.push({
9111
9111
  expected: "object",
9112
9112
  code: "invalid_type",
@@ -15471,38 +15471,12 @@ var StdioServerTransport = class {
15471
15471
 
15472
15472
  // ../../extensions/drm-copilot/src/command-runtime.ts
15473
15473
  var cp = __toESM(require("node:child_process"));
15474
+ var path2 = __toESM(require("node:path"));
15475
+ var vscode = __toESM(require_vscode());
15476
+
15477
+ // ../../extensions/drm-copilot/src/runtime-detection.ts
15474
15478
  var fs = __toESM(require("node:fs"));
15475
15479
  var path = __toESM(require("node:path"));
15476
- var vscode = __toESM(require_vscode());
15477
- var CommandExecutionError = class extends Error {
15478
- executable;
15479
- args;
15480
- cwd;
15481
- exitCode;
15482
- stdout;
15483
- stderr;
15484
- constructor(input) {
15485
- super(`Command exited with code ${input.exitCode ?? "unknown"}.`);
15486
- this.name = "CommandExecutionError";
15487
- this.executable = input.executable;
15488
- this.args = input.args;
15489
- this.cwd = input.cwd;
15490
- this.exitCode = input.exitCode;
15491
- this.stdout = input.stdout;
15492
- this.stderr = input.stderr;
15493
- }
15494
- };
15495
- function createBufferedOutput() {
15496
- const lines = [];
15497
- return {
15498
- output: {
15499
- appendLine(line) {
15500
- lines.push(line);
15501
- }
15502
- },
15503
- lines
15504
- };
15505
- }
15506
15480
  function executableExists(executable) {
15507
15481
  return findExecutableOnPath(executable) !== void 0;
15508
15482
  }
@@ -15556,13 +15530,57 @@ function detectRuntime(runtimeKind) {
15556
15530
  "PowerShell runtime not found. Expected 'pwsh' or 'powershell' on PATH."
15557
15531
  );
15558
15532
  }
15533
+
15534
+ // ../../extensions/drm-copilot/src/command-runtime.ts
15535
+ var CommandExecutionError = class extends Error {
15536
+ executable;
15537
+ args;
15538
+ cwd;
15539
+ exitCode;
15540
+ stdout;
15541
+ stderr;
15542
+ constructor(input) {
15543
+ super(`Command exited with code ${input.exitCode ?? "unknown"}.`);
15544
+ this.name = "CommandExecutionError";
15545
+ this.executable = input.executable;
15546
+ this.args = input.args;
15547
+ this.cwd = input.cwd;
15548
+ this.exitCode = input.exitCode;
15549
+ this.stdout = input.stdout;
15550
+ this.stderr = input.stderr;
15551
+ }
15552
+ };
15553
+ function createBufferedOutput() {
15554
+ const lines = [];
15555
+ return {
15556
+ output: {
15557
+ appendLine(line) {
15558
+ lines.push(line);
15559
+ }
15560
+ },
15561
+ lines
15562
+ };
15563
+ }
15564
+ function getClaudeProjectsRoot(env = process.env) {
15565
+ const configDirOverride = env["CLAUDE_CONFIG_DIR"]?.trim();
15566
+ if (configDirOverride !== void 0 && configDirOverride.length > 0) {
15567
+ return path2.join(configDirOverride, "projects").replace(/\\/g, "/");
15568
+ }
15569
+ const home = env["HOME"]?.trim() || env["USERPROFILE"]?.trim();
15570
+ if (home === void 0 || home.length === 0) {
15571
+ throw new Error(
15572
+ "Cannot resolve the user-global Claude projects directory: none of CLAUDE_CONFIG_DIR, HOME, or USERPROFILE is set."
15573
+ );
15574
+ }
15575
+ return path2.join(home, ".claude", "projects").replace(/\\/g, "/");
15576
+ }
15559
15577
  function resolveBundledScriptPath(extensionRoot, bundledRelativePath) {
15560
15578
  const normalizedExtensionRoot = extensionRoot.replace(/\\/g, "/");
15561
15579
  const normalizedBundledRelativePath = bundledRelativePath.replace(/\\/g, "/").replace(/^\/+/, "");
15562
15580
  if (/^[A-Za-z]:\//.test(normalizedExtensionRoot)) {
15563
15581
  return `${normalizedExtensionRoot.replace(/\/+$/, "")}/${normalizedBundledRelativePath}`;
15564
15582
  }
15565
- return path.resolve(extensionRoot, bundledRelativePath).replace(/\\/g, "/");
15583
+ return path2.resolve(extensionRoot, bundledRelativePath).replace(/\\/g, "/");
15566
15584
  }
15567
15585
  function runCommandWithOutput(output, executable, args, cwd) {
15568
15586
  return new Promise((resolve4, reject) => {
@@ -15715,7 +15733,7 @@ var claudePushDownSelectionProperties = {
15715
15733
  };
15716
15734
 
15717
15735
  // ../../extensions/drm-copilot/src/workflow-command-arguments.ts
15718
- var path2 = __toESM(require("node:path"));
15736
+ var path3 = __toESM(require("node:path"));
15719
15737
  var SHORT_NAME_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;
15720
15738
  var FEATURE_NAME_PATTERN = /^[a-z0-9]+(?:[-_][a-z0-9]+)*$/;
15721
15739
  var POTENTIAL_PROMOTION_TYPES = [
@@ -15820,7 +15838,7 @@ function isAbsolutePathLike(filePath) {
15820
15838
  }
15821
15839
  function normalizeWorkspaceDestinationPath(value, workspaceRoot, fieldName) {
15822
15840
  const targetPath = normalizeRequiredText(value, fieldName);
15823
- const resolvedPath = isAbsolutePathLike(targetPath) ? targetPath : path2.join(workspaceRoot, targetPath);
15841
+ const resolvedPath = isAbsolutePathLike(targetPath) ? targetPath : path3.join(workspaceRoot, targetPath);
15824
15842
  return resolvedPath.replace(/\\/g, "/");
15825
15843
  }
15826
15844
 
@@ -16217,6 +16235,22 @@ var REPO_AUTOMATION_TOOL_DEFINITIONS = [
16217
16235
  required: ["artifact_type", "artifact_path"],
16218
16236
  additionalProperties: false
16219
16237
  }
16238
+ },
16239
+ {
16240
+ name: "render_subagent_tree",
16241
+ description: "Render the subagent call tree for a root session id. The session id is a transcript filename stem; the transcript is resolved under the user-global Claude projects directory, searching the encoded workspace directory plus its '-wt-' worktree siblings (case-insensitive) and returning the first match deterministically.",
16242
+ inputSchema: {
16243
+ type: "object",
16244
+ properties: {
16245
+ workspace_root: workspaceRootProperty,
16246
+ session_id: {
16247
+ type: "string",
16248
+ description: "Root session identifier (transcript filename stem under ~/.claude/projects/<encoded-workspace>/, e.g. a UUIDv4)."
16249
+ }
16250
+ },
16251
+ required: ["session_id"],
16252
+ additionalProperties: false
16253
+ }
16220
16254
  }
16221
16255
  ];
16222
16256
 
@@ -16241,7 +16275,8 @@ var REPO_AUTOMATION_TOOLS = [
16241
16275
  "resolve_policy_audit_template_asset",
16242
16276
  "resolve_execute_hard_lock_prompt",
16243
16277
  "resolve_atomic_plan_prompt",
16244
- "validate_orchestration_artifacts"
16278
+ "validate_orchestration_artifacts",
16279
+ "render_subagent_tree"
16245
16280
  ];
16246
16281
 
16247
16282
  // ../../extensions/drm-copilot/src/mcp-tool-inputs-push-down.ts
@@ -16695,6 +16730,24 @@ async function handleResolveExecuteHardLockPrompt(rawInput, service) {
16695
16730
  });
16696
16731
  }
16697
16732
 
16733
+ // ../../extensions/drm-copilot/src/mcp-tool-inputs-subagent-tree.ts
16734
+ function resolveRenderSubagentTreeToolInput(rawInput, fallbackWorkspaceRoot) {
16735
+ const args = asToolArgumentObject(rawInput);
16736
+ return {
16737
+ workspaceRoot: normalizeWorkspaceRoot(
16738
+ args["workspace_root"],
16739
+ fallbackWorkspaceRoot
16740
+ ),
16741
+ sessionId: normalizeRequiredText(args["session_id"], "session_id")
16742
+ };
16743
+ }
16744
+
16745
+ // ../../extensions/drm-copilot/src/mcp-handlers/render-subagent-tree-handler.ts
16746
+ async function handleRenderSubagentTree(rawInput, service) {
16747
+ const input = resolveRenderSubagentTreeToolInput(rawInput);
16748
+ return service.renderSubagentTree(input);
16749
+ }
16750
+
16698
16751
  // ../../extensions/drm-copilot/src/mcp-handlers/template-validation-handlers.ts
16699
16752
  async function handleResolvePolicyAuditTemplateAsset(rawInput, service) {
16700
16753
  const input = resolvePolicyAuditTemplateAssetToolInput(rawInput);
@@ -16722,7 +16775,8 @@ function toMcpToolResult(result) {
16722
16775
  ...result.artifacts === void 0 ? {} : { artifacts: result.artifacts },
16723
16776
  ...result.assetId === void 0 ? {} : { asset_id: result.assetId },
16724
16777
  ...result.bundledSourcePath === void 0 ? {} : { bundled_source_path: result.bundledSourcePath },
16725
- ...result.destinationPath === void 0 ? {} : { destination_path: result.destinationPath }
16778
+ ...result.destinationPath === void 0 ? {} : { destination_path: result.destinationPath },
16779
+ ...result.renderedTree === void 0 ? {} : { rendered_tree: result.renderedTree }
16726
16780
  };
16727
16781
  }
16728
16782
  function toFailureToolResult(tool, workspaceRoot, error2) {
@@ -16828,6 +16882,11 @@ async function dispatchRepoAutomationTool(toolName, rawInput, service) {
16828
16882
  await handleValidateOrchestrationArtifacts(rawInput, service)
16829
16883
  );
16830
16884
  }
16885
+ case "render_subagent_tree": {
16886
+ return toMcpToolResult(
16887
+ await handleRenderSubagentTree(rawInput, service)
16888
+ );
16889
+ }
16831
16890
  }
16832
16891
  } catch (error2) {
16833
16892
  return toFailureToolResult(toolName, workspaceRoot, error2);
@@ -16838,7 +16897,7 @@ function isRepoAutomationToolName(name) {
16838
16897
  }
16839
16898
 
16840
16899
  // ../../extensions/drm-copilot/src/repo-automation-service-support.ts
16841
- var path3 = __toESM(require("node:path"));
16900
+ var path4 = __toESM(require("node:path"));
16842
16901
 
16843
16902
  // ../../extensions/drm-copilot/src/lib/collect-commit-context.ts
16844
16903
  var nodePath = __toESM(require("node:path"));
@@ -17010,7 +17069,7 @@ function normalizeGeneratedPath(filePath) {
17010
17069
  return filePath.replace(/\\/g, "/");
17011
17070
  }
17012
17071
  function runCollectCommitContext(input) {
17013
- const outputPath = path3.join(
17072
+ const outputPath = path4.join(
17014
17073
  input.workspaceRoot,
17015
17074
  "artifacts/commit_context.txt"
17016
17075
  );
@@ -17034,6 +17093,26 @@ function parseFirstArtifactPath(execution, pattern) {
17034
17093
  return capturedPath && capturedPath.length > 0 ? normalizeGeneratedPath(capturedPath) : void 0;
17035
17094
  }
17036
17095
 
17096
+ // ../../extensions/drm-copilot/src/repo-automation-execute-script.ts
17097
+ async function executeScriptServiceCall(output, extensionRoot, options) {
17098
+ const execution = await executeBundledScriptFromExtensionRoot(output, {
17099
+ runtimeKind: options.runtimeKind,
17100
+ bundledRelativePath: options.bundledRelativePath,
17101
+ commandId: options.invocationId,
17102
+ args: options.args,
17103
+ extensionRoot,
17104
+ workspaceRoot: options.workspaceRoot
17105
+ });
17106
+ const parsedArtifactPath = options.stdoutArtifactPattern === void 0 ? void 0 : parseFirstArtifactPath(execution, options.stdoutArtifactPattern);
17107
+ const artifacts = options.artifactPaths ?? (parsedArtifactPath === void 0 ? void 0 : [parsedArtifactPath]);
17108
+ return {
17109
+ tool: options.tool,
17110
+ workspaceRoot: options.workspaceRoot,
17111
+ summary: options.summary,
17112
+ ...artifacts === void 0 ? {} : { artifacts }
17113
+ };
17114
+ }
17115
+
17037
17116
  // ../../extensions/drm-copilot/src/repo-automation-args.ts
17038
17117
  function buildPoshQcWorkflowArguments(tool, input) {
17039
17118
  const toolConfig = POSH_QC_TOOL_CONFIG[tool];
@@ -17115,9 +17194,9 @@ var RealPushDownFileSystem = class {
17115
17194
  * @param path Path to inspect.
17116
17195
  * @returns True when `path` exists and is a directory.
17117
17196
  */
17118
- isDir(path10) {
17197
+ isDir(path11) {
17119
17198
  try {
17120
- return fs2.statSync(path10).isDirectory();
17199
+ return fs2.statSync(path11).isDirectory();
17121
17200
  } catch {
17122
17201
  return false;
17123
17202
  }
@@ -17126,9 +17205,9 @@ var RealPushDownFileSystem = class {
17126
17205
  * @param path Path to inspect.
17127
17206
  * @returns True when `path` exists and is a regular file.
17128
17207
  */
17129
- isFile(path10) {
17208
+ isFile(path11) {
17130
17209
  try {
17131
- return fs2.statSync(path10).isFile();
17210
+ return fs2.statSync(path11).isFile();
17132
17211
  } catch {
17133
17212
  return false;
17134
17213
  }
@@ -17137,8 +17216,8 @@ var RealPushDownFileSystem = class {
17137
17216
  * @param path File to read.
17138
17217
  * @returns The file content decoded as UTF-8.
17139
17218
  */
17140
- readTextFile(path10) {
17141
- return fs2.readFileSync(path10, "utf8");
17219
+ readTextFile(path11) {
17220
+ return fs2.readFileSync(path11, "utf8");
17142
17221
  }
17143
17222
  /**
17144
17223
  * Write UTF-8 text to a file path, creating parent directories first.
@@ -17150,19 +17229,19 @@ var RealPushDownFileSystem = class {
17150
17229
  * @param path Destination file path.
17151
17230
  * @param content UTF-8 text to write.
17152
17231
  */
17153
- writeTextFile(path10, content) {
17154
- const parent = nodePath2.dirname(path10);
17232
+ writeTextFile(path11, content) {
17233
+ const parent = nodePath2.dirname(path11);
17155
17234
  fs2.mkdirSync(parent, { recursive: true });
17156
17235
  const lfNormalized = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
17157
- fs2.writeFileSync(path10, lfNormalized, "utf8");
17236
+ fs2.writeFileSync(path11, lfNormalized, "utf8");
17158
17237
  }
17159
17238
  /**
17160
17239
  * Ensure a directory exists, creating any missing parents.
17161
17240
  *
17162
17241
  * @param path Directory path to create.
17163
17242
  */
17164
- ensureDir(path10) {
17165
- fs2.mkdirSync(path10, { recursive: true });
17243
+ ensureDir(path11) {
17244
+ fs2.mkdirSync(path11, { recursive: true });
17166
17245
  }
17167
17246
  };
17168
17247
 
@@ -17299,8 +17378,8 @@ function joinPosix2(root, relative2) {
17299
17378
  }
17300
17379
  return `${normalizedRoot}/${normalizedRelative}`;
17301
17380
  }
17302
- function relativeToPosix(path10, root) {
17303
- const normalizedPath = toPosixPath(path10).replace(/\/+$/, "");
17381
+ function relativeToPosix(path11, root) {
17382
+ const normalizedPath = toPosixPath(path11).replace(/\/+$/, "");
17304
17383
  const normalizedRoot = toPosixPath(root).replace(/\/+$/, "");
17305
17384
  if (normalizedPath === normalizedRoot) {
17306
17385
  return "";
@@ -17664,8 +17743,8 @@ function computePublishedPaths(selectedPackNames, manifests) {
17664
17743
  `No loaded Codex manifest for selected pack '${name}'.`
17665
17744
  );
17666
17745
  }
17667
- for (const path10 of manifest.paths) {
17668
- published.add(path10);
17746
+ for (const path11 of manifest.paths) {
17747
+ published.add(path11);
17669
17748
  }
17670
17749
  }
17671
17750
  return published;
@@ -17706,8 +17785,8 @@ function joinPosix4(root, relative2) {
17706
17785
  const normalizedRelative = relative2.replace(/\\/g, "/").replace(/^\/+/, "");
17707
17786
  return normalizedRoot === "" ? normalizedRelative : `${normalizedRoot}/${normalizedRelative}`;
17708
17787
  }
17709
- function relativeToPosix2(path10, root) {
17710
- const normalizedPath = normalizePosix(path10);
17788
+ function relativeToPosix2(path11, root) {
17789
+ const normalizedPath = normalizePosix(path11);
17711
17790
  const normalizedRoot = normalizePosix(root);
17712
17791
  if (normalizedPath === normalizedRoot) {
17713
17792
  return "";
@@ -17728,44 +17807,44 @@ var CodexFilteringFileSystem = class {
17728
17807
  bundleRoot;
17729
17808
  publishedPaths;
17730
17809
  csharpVariant;
17731
- sourceRelative(path10) {
17732
- return relativeToPosix2(path10, this.sourceRoot);
17810
+ sourceRelative(path11) {
17811
+ return relativeToPosix2(path11, this.sourceRoot);
17733
17812
  }
17734
- isPackIncluded(path10) {
17813
+ isPackIncluded(path11) {
17735
17814
  if (this.publishedPaths === null) {
17736
17815
  return true;
17737
17816
  }
17738
- const relative2 = this.sourceRelative(path10);
17817
+ const relative2 = this.sourceRelative(path11);
17739
17818
  return relative2 === null || this.publishedPaths.has(relative2);
17740
17819
  }
17741
- resolveReadSource(path10) {
17820
+ resolveReadSource(path11) {
17742
17821
  if (this.csharpVariant !== "legacy") {
17743
- return path10;
17822
+ return path11;
17744
17823
  }
17745
- const relative2 = this.sourceRelative(path10);
17824
+ const relative2 = this.sourceRelative(path11);
17746
17825
  if (relative2 === null) {
17747
- return path10;
17826
+ return path11;
17748
17827
  }
17749
17828
  const routed = resolveVariantSourcePath(relative2, "legacy");
17750
- return routed === relative2 ? path10 : joinPosix4(this.bundleRoot, routed);
17829
+ return routed === relative2 ? path11 : joinPosix4(this.bundleRoot, routed);
17751
17830
  }
17752
17831
  listFiles(root) {
17753
- return this.inner.listFiles(root).filter((path10) => this.isPackIncluded(path10));
17832
+ return this.inner.listFiles(root).filter((path11) => this.isPackIncluded(path11));
17754
17833
  }
17755
- isDir(path10) {
17756
- return this.inner.isDir(path10);
17834
+ isDir(path11) {
17835
+ return this.inner.isDir(path11);
17757
17836
  }
17758
- isFile(path10) {
17759
- return this.inner.isFile(path10);
17837
+ isFile(path11) {
17838
+ return this.inner.isFile(path11);
17760
17839
  }
17761
- readTextFile(path10) {
17762
- return this.inner.readTextFile(this.resolveReadSource(path10));
17840
+ readTextFile(path11) {
17841
+ return this.inner.readTextFile(this.resolveReadSource(path11));
17763
17842
  }
17764
- writeTextFile(path10, content) {
17765
- this.inner.writeTextFile(path10, content);
17843
+ writeTextFile(path11, content) {
17844
+ this.inner.writeTextFile(path11, content);
17766
17845
  }
17767
- ensureDir(path10) {
17768
- this.inner.ensureDir(path10);
17846
+ ensureDir(path11) {
17847
+ this.inner.ensureDir(path11);
17769
17848
  }
17770
17849
  };
17771
17850
  function resolvePublishedPaths(packs, csharpVariant, bundleRoot, fs9) {
@@ -18000,8 +18079,8 @@ function joinPosix6(root, relative2) {
18000
18079
  }
18001
18080
  return `${normalizedRoot}/${normalizedRelative}`;
18002
18081
  }
18003
- function relativeToPosix3(path10, root) {
18004
- const normalizedPath = normalizePosix3(path10);
18082
+ function relativeToPosix3(path11, root) {
18083
+ const normalizedPath = normalizePosix3(path11);
18005
18084
  const normalizedRoot = normalizePosix3(root);
18006
18085
  if (normalizedPath === normalizedRoot) {
18007
18086
  return "";
@@ -18048,8 +18127,8 @@ var ExcludingFileSystem = class {
18048
18127
  * @param path An absolute candidate POSIX path from the inner adapter.
18049
18128
  * @returns The source-relative POSIX path, or `null`.
18050
18129
  */
18051
- sourceRelativePosix(path10) {
18052
- return relativeToPosix3(path10, this.sourceRoot);
18130
+ sourceRelativePosix(path11) {
18131
+ return relativeToPosix3(path11, this.sourceRoot);
18053
18132
  }
18054
18133
  /**
18055
18134
  * Return whether a candidate path is in the active published set.
@@ -18057,11 +18136,11 @@ var ExcludingFileSystem = class {
18057
18136
  * @param path An absolute candidate POSIX path.
18058
18137
  * @returns True when no pack filter is active or the path is published.
18059
18138
  */
18060
- isPackIncluded(path10) {
18139
+ isPackIncluded(path11) {
18061
18140
  if (this.publishedPaths === null) {
18062
18141
  return true;
18063
18142
  }
18064
- const relative2 = this.sourceRelativePosix(path10);
18143
+ const relative2 = this.sourceRelativePosix(path11);
18065
18144
  if (relative2 === null) {
18066
18145
  return true;
18067
18146
  }
@@ -18075,15 +18154,15 @@ var ExcludingFileSystem = class {
18075
18154
  * @param path An absolute candidate POSIX path.
18076
18155
  * @returns True when the file is outside the memory subtree or general-scoped.
18077
18156
  */
18078
- isScopeIncluded(path10) {
18079
- const relativePath = relativeToPosix3(path10, this.repoRoot);
18157
+ isScopeIncluded(path11) {
18158
+ const relativePath = relativeToPosix3(path11, this.repoRoot);
18080
18159
  if (relativePath === null) {
18081
18160
  return true;
18082
18161
  }
18083
18162
  if (!isUnderAgentMemory(relativePath)) {
18084
18163
  return true;
18085
18164
  }
18086
- const content = this.readText(path10);
18165
+ const content = this.readText(path11);
18087
18166
  return isGeneralMemoryFile(relativePath, content);
18088
18167
  }
18089
18168
  /**
@@ -18092,8 +18171,8 @@ var ExcludingFileSystem = class {
18092
18171
  * @param path An absolute candidate POSIX path.
18093
18172
  * @returns True when the file should be published under the active mode.
18094
18173
  */
18095
- isMemoryModeIncluded(path10) {
18096
- const relative2 = this.sourceRelativePosix(path10);
18174
+ isMemoryModeIncluded(path11) {
18175
+ const relative2 = this.sourceRelativePosix(path11);
18097
18176
  if (relative2 === null) {
18098
18177
  return true;
18099
18178
  }
@@ -18121,13 +18200,13 @@ var ExcludingFileSystem = class {
18121
18200
  * @param path The absolute POSIX path the engine asked to read.
18122
18201
  * @returns The redirected legacy source path, or the original path.
18123
18202
  */
18124
- resolveReadSource(path10) {
18203
+ resolveReadSource(path11) {
18125
18204
  if (this.csharpVariant !== "legacy") {
18126
- return path10;
18205
+ return path11;
18127
18206
  }
18128
- const relative2 = this.sourceRelativePosix(path10);
18207
+ const relative2 = this.sourceRelativePosix(path11);
18129
18208
  if (relative2 === null || !CSHARP_CANONICAL_PATHS2.includes(relative2)) {
18130
- return path10;
18209
+ return path11;
18131
18210
  }
18132
18211
  const redirectedRelative = resolveVariantSourcePath2(relative2, "legacy");
18133
18212
  return joinPosix6(this.variantRoot, redirectedRelative);
@@ -18137,23 +18216,23 @@ var ExcludingFileSystem = class {
18137
18216
  (p) => !this.excluded.has(normalizePosix3(p)) && this.isPackIncluded(p) && this.isScopeIncluded(p) && this.isMemoryModeIncluded(p)
18138
18217
  );
18139
18218
  }
18140
- isDir(path10) {
18141
- return this.inner.isDir(path10);
18219
+ isDir(path11) {
18220
+ return this.inner.isDir(path11);
18142
18221
  }
18143
- isFile(path10) {
18144
- return this.inner.isFile(path10);
18222
+ isFile(path11) {
18223
+ return this.inner.isFile(path11);
18145
18224
  }
18146
- readText(path10) {
18147
- return this.inner.readTextFile(this.resolveReadSource(path10));
18225
+ readText(path11) {
18226
+ return this.inner.readTextFile(this.resolveReadSource(path11));
18148
18227
  }
18149
- readTextFile(path10) {
18150
- return this.readText(path10);
18228
+ readTextFile(path11) {
18229
+ return this.readText(path11);
18151
18230
  }
18152
- writeTextFile(path10, content) {
18153
- this.inner.writeTextFile(path10, content);
18231
+ writeTextFile(path11, content) {
18232
+ this.inner.writeTextFile(path11, content);
18154
18233
  }
18155
- ensureDir(path10) {
18156
- this.inner.ensureDir(path10);
18234
+ ensureDir(path11) {
18235
+ this.inner.ensureDir(path11);
18157
18236
  }
18158
18237
  };
18159
18238
 
@@ -18364,11 +18443,11 @@ function runPushDownClaudeCustomizations(input, deps) {
18364
18443
  }
18365
18444
 
18366
18445
  // ../../extensions/drm-copilot/src/repo-automation-service-workflows.ts
18367
- var path6 = __toESM(require("node:path"));
18446
+ var path7 = __toESM(require("node:path"));
18368
18447
 
18369
18448
  // ../../extensions/drm-copilot/src/policy-audit-template-assets.ts
18370
18449
  var fs3 = __toESM(require("node:fs"));
18371
- var path4 = __toESM(require("node:path"));
18450
+ var path5 = __toESM(require("node:path"));
18372
18451
  var POLICY_AUDIT_TEMPLATE_ASSET_METADATA = {
18373
18452
  template: {
18374
18453
  assetId: "policy_audit.template",
@@ -18393,7 +18472,7 @@ function normalizeRepoPath(filePath) {
18393
18472
  function resolveBundledPolicyAuditTemplateAsset(extensionRoot, asset) {
18394
18473
  const assetMetadata = POLICY_AUDIT_TEMPLATE_ASSET_METADATA[asset];
18395
18474
  const bundledSourcePath = normalizeRepoPath(
18396
- path4.join(
18475
+ path5.join(
18397
18476
  extensionRoot,
18398
18477
  "resources",
18399
18478
  "templates",
@@ -18411,13 +18490,13 @@ function copyBundledPolicyAuditTemplateAsset(bundledSourcePath, targetPath) {
18411
18490
  if (normalizedTargetPath === bundledSourcePath) {
18412
18491
  return normalizedTargetPath;
18413
18492
  }
18414
- fs3.mkdirSync(path4.dirname(normalizedTargetPath), { recursive: true });
18493
+ fs3.mkdirSync(path5.dirname(normalizedTargetPath), { recursive: true });
18415
18494
  fs3.copyFileSync(bundledSourcePath, normalizedTargetPath);
18416
18495
  return normalizedTargetPath;
18417
18496
  }
18418
18497
 
18419
18498
  // ../../extensions/drm-copilot/src/lib/resolve/resolve-prompts-service-call.ts
18420
- var path5 = __toESM(require("node:path"));
18499
+ var path6 = __toESM(require("node:path"));
18421
18500
 
18422
18501
  // ../../extensions/drm-copilot/src/lib/file-system.ts
18423
18502
  var fs4 = __toESM(require("node:fs"));
@@ -18512,9 +18591,9 @@ var RealFileSystem = class {
18512
18591
  * @param path Path to test.
18513
18592
  * @returns True when `path` exists and is a regular file.
18514
18593
  */
18515
- isFile(path10) {
18594
+ isFile(path11) {
18516
18595
  try {
18517
- return fs4.statSync(path10).isFile();
18596
+ return fs4.statSync(path11).isFile();
18518
18597
  } catch {
18519
18598
  return false;
18520
18599
  }
@@ -18523,16 +18602,16 @@ var RealFileSystem = class {
18523
18602
  * @param path Path to test.
18524
18603
  * @returns True when `path` exists; false on any access error.
18525
18604
  */
18526
- exists(path10) {
18527
- return fs4.existsSync(path10);
18605
+ exists(path11) {
18606
+ return fs4.existsSync(path11);
18528
18607
  }
18529
18608
  /**
18530
18609
  * @param path Path to test.
18531
18610
  * @returns True when `path` exists and is a directory; false otherwise.
18532
18611
  */
18533
- isDirectory(path10) {
18612
+ isDirectory(path11) {
18534
18613
  try {
18535
- return fs4.statSync(path10).isDirectory();
18614
+ return fs4.statSync(path11).isDirectory();
18536
18615
  } catch {
18537
18616
  return false;
18538
18617
  }
@@ -18542,9 +18621,9 @@ var RealFileSystem = class {
18542
18621
  * @returns Sorted child names; an empty array when `path` is not a readable
18543
18622
  * directory.
18544
18623
  */
18545
- listDirectory(path10) {
18624
+ listDirectory(path11) {
18546
18625
  try {
18547
- return fs4.readdirSync(path10).sort((left, right) => left.localeCompare(right));
18626
+ return fs4.readdirSync(path11).sort((left, right) => left.localeCompare(right));
18548
18627
  } catch {
18549
18628
  return [];
18550
18629
  }
@@ -18553,15 +18632,15 @@ var RealFileSystem = class {
18553
18632
  * @param path File to read.
18554
18633
  * @returns The file content decoded as UTF-8.
18555
18634
  */
18556
- readTextFile(path10) {
18557
- return fs4.readFileSync(path10, "utf8");
18635
+ readTextFile(path11) {
18636
+ return fs4.readFileSync(path11, "utf8");
18558
18637
  }
18559
18638
  /**
18560
18639
  * @param path File to write.
18561
18640
  * @param content Text content to write as UTF-8.
18562
18641
  */
18563
- writeTextFile(path10, content) {
18564
- fs4.writeFileSync(path10, content, "utf8");
18642
+ writeTextFile(path11, content) {
18643
+ fs4.writeFileSync(path11, content, "utf8");
18565
18644
  }
18566
18645
  /**
18567
18646
  * Create the directory at `path`, including any missing parents.
@@ -18572,8 +18651,8 @@ var RealFileSystem = class {
18572
18651
  *
18573
18652
  * @param path Directory path to create.
18574
18653
  */
18575
- ensureDir(path10) {
18576
- fs4.mkdirSync(path10, { recursive: true });
18654
+ ensureDir(path11) {
18655
+ fs4.mkdirSync(path11, { recursive: true });
18577
18656
  }
18578
18657
  };
18579
18658
 
@@ -18806,8 +18885,8 @@ function resolveOutputPath(output, workspaceRoot) {
18806
18885
  }
18807
18886
  return joinPosix9(toPosixPath2(workspaceRoot), output);
18808
18887
  }
18809
- function tryRelativeToWorkspace(path10, workspaceRoot) {
18810
- const normalizedPath = toPosixPath2(path10).replace(/\/+$/, "");
18888
+ function tryRelativeToWorkspace(path11, workspaceRoot) {
18889
+ const normalizedPath = toPosixPath2(path11).replace(/\/+$/, "");
18811
18890
  const normalizedRoot = toPosixPath2(workspaceRoot).replace(/\/+$/, "");
18812
18891
  if (normalizedPath === normalizedRoot) {
18813
18892
  return "";
@@ -18931,8 +19010,8 @@ function stripFrontMatter(content) {
18931
19010
  function splitPathPlatformAgnostic(pathStr) {
18932
19011
  return pathStr.split(/[\\/]+/).filter((part) => part.length > 0);
18933
19012
  }
18934
- function tryRelativeToWorkspace2(path10, workspaceRoot) {
18935
- const normalizedPath = toPosixPath2(path10).replace(/\/+$/, "");
19013
+ function tryRelativeToWorkspace2(path11, workspaceRoot) {
19014
+ const normalizedPath = toPosixPath2(path11).replace(/\/+$/, "");
18936
19015
  const normalizedRoot = toPosixPath2(workspaceRoot).replace(/\/+$/, "");
18937
19016
  if (normalizedPath === normalizedRoot) {
18938
19017
  return "";
@@ -19114,7 +19193,7 @@ function resolveExecuteHardLockPromptServiceCall(input) {
19114
19193
  );
19115
19194
  }
19116
19195
  const templateRoot = toPosixPath2(
19117
- path5.join(
19196
+ path6.join(
19118
19197
  input.extensionRoot,
19119
19198
  "resources",
19120
19199
  "customizations",
@@ -19146,7 +19225,7 @@ ${emittedLines.join("\n")}`
19146
19225
  }
19147
19226
  const artifacts = input.output === void 0 ? void 0 : [
19148
19227
  normalizeGeneratedPath(
19149
- isAbsolutePathLike(input.output) ? input.output : path5.join(input.workspaceRoot, input.output)
19228
+ isAbsolutePathLike(input.output) ? input.output : path6.join(input.workspaceRoot, input.output)
19150
19229
  )
19151
19230
  ];
19152
19231
  return {
@@ -19158,7 +19237,7 @@ ${emittedLines.join("\n")}`
19158
19237
  }
19159
19238
  function resolveAtomicPlanPromptServiceCall(input) {
19160
19239
  const templatePath = toPosixPath2(
19161
- path5.join(
19240
+ path6.join(
19162
19241
  input.extensionRoot,
19163
19242
  "resources",
19164
19243
  "customizations",
@@ -19167,7 +19246,7 @@ function resolveAtomicPlanPromptServiceCall(input) {
19167
19246
  "generate-atomic-plan.prompt.md"
19168
19247
  )
19169
19248
  );
19170
- const targetPath = isAbsolutePathLike(input.target) ? toPosixPath2(input.target) : toPosixPath2(path5.join(input.workspaceRoot, input.target));
19249
+ const targetPath = isAbsolutePathLike(input.target) ? toPosixPath2(input.target) : toPosixPath2(path6.join(input.workspaceRoot, input.target));
19171
19250
  const emittedLines = [];
19172
19251
  const log = (message) => {
19173
19252
  emittedLines.push(message);
@@ -19216,7 +19295,7 @@ function resolvePolicyAuditTemplateAssetResult(extensionRoot, input) {
19216
19295
  }
19217
19296
  function buildTemplateRoot(extensionRoot) {
19218
19297
  return normalizeGeneratedPath(
19219
- path6.join(extensionRoot, "resources", "feature-templates")
19298
+ path7.join(extensionRoot, "resources", "feature-templates")
19220
19299
  );
19221
19300
  }
19222
19301
  function runResolveExecuteHardLockPrompt(deps, input) {
@@ -19241,7 +19320,7 @@ function runResolveAtomicPlanPrompt(deps, input) {
19241
19320
  }
19242
19321
 
19243
19322
  // ../../extensions/drm-copilot/src/lib/codex-native-converter/codex-native-converter-service-call.ts
19244
- var path7 = __toESM(require("node:path"));
19323
+ var path8 = __toESM(require("node:path"));
19245
19324
 
19246
19325
  // ../../extensions/drm-copilot/src/lib/codex-native-converter/models-intermediate.ts
19247
19326
  var TargetRole = {
@@ -21697,7 +21776,7 @@ function resolveAgainstWorkspace(workspaceRoot, value) {
21697
21776
  return normalizedValue.replace(/\/+$/, "");
21698
21777
  }
21699
21778
  return toPosixPath2(
21700
- path7.posix.join(toPosixPath2(workspaceRoot), normalizedValue)
21779
+ path8.posix.join(toPosixPath2(workspaceRoot), normalizedValue)
21701
21780
  ).replace(/\/+$/, "");
21702
21781
  }
21703
21782
  function reportParent(conversionReportPath) {
@@ -21784,7 +21863,144 @@ var SubprocessRunner = class {
21784
21863
  };
21785
21864
 
21786
21865
  // ../../extensions/drm-copilot/src/lib/validate/validate-orchestration-service-call.ts
21787
- var path8 = __toESM(require("node:path"));
21866
+ var path9 = __toESM(require("node:path"));
21867
+
21868
+ // ../../extensions/drm-copilot/src/lib/validate/epic-orchestrator-state-resolution.ts
21869
+ var LIFECYCLE_PREFIXES = [
21870
+ "docs/features/active/",
21871
+ "docs/features/completed/",
21872
+ "active/",
21873
+ "completed/"
21874
+ ];
21875
+ var VALID_EPIC_TYPES = /* @__PURE__ */ new Set(["business", "enabler"]);
21876
+ function isObject2(value) {
21877
+ return typeof value === "object" && value !== null && !Array.isArray(value);
21878
+ }
21879
+ function pythonRepr(value) {
21880
+ if (value === null || value === void 0) {
21881
+ return "None";
21882
+ }
21883
+ if (typeof value === "boolean") {
21884
+ return value ? "True" : "False";
21885
+ }
21886
+ if (typeof value === "string") {
21887
+ return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
21888
+ }
21889
+ return String(value);
21890
+ }
21891
+ function normalizeFolderHint(value) {
21892
+ for (const prefix of LIFECYCLE_PREFIXES) {
21893
+ if (value.startsWith(prefix)) {
21894
+ return value.slice(prefix.length);
21895
+ }
21896
+ }
21897
+ return value;
21898
+ }
21899
+ function buildFeatureReferenceIndex(features) {
21900
+ const byFolderHint = /* @__PURE__ */ new Map();
21901
+ const byIssueNum = /* @__PURE__ */ new Map();
21902
+ for (const feature of features) {
21903
+ const folder = feature["feature_folder"];
21904
+ if (typeof folder === "string" && folder) {
21905
+ byFolderHint.set(normalizeFolderHint(folder), folder);
21906
+ const issueNum = feature["issue_num"];
21907
+ if (issueNum !== void 0 && issueNum !== null) {
21908
+ byIssueNum.set(issueNum, folder);
21909
+ }
21910
+ }
21911
+ }
21912
+ return { byFolderHint, byIssueNum };
21913
+ }
21914
+ function resolveFeatureReference(dependency, index) {
21915
+ if (typeof dependency !== "string") {
21916
+ return index.byIssueNum.get(dependency) ?? null;
21917
+ }
21918
+ return index.byFolderHint.get(normalizeFolderHint(dependency)) ?? null;
21919
+ }
21920
+ function detectDependencyCycle(features) {
21921
+ const index = buildFeatureReferenceIndex(features);
21922
+ const graph = /* @__PURE__ */ new Map();
21923
+ for (const feature of features) {
21924
+ const folder = feature["feature_folder"];
21925
+ if (typeof folder !== "string" || !folder) {
21926
+ continue;
21927
+ }
21928
+ const dependsOn = feature["depends_on"];
21929
+ if (!Array.isArray(dependsOn)) {
21930
+ graph.set(folder, []);
21931
+ continue;
21932
+ }
21933
+ const resolvedEdges = [];
21934
+ for (const dependency of dependsOn) {
21935
+ const resolved = resolveFeatureReference(dependency, index);
21936
+ if (resolved !== null) {
21937
+ resolvedEdges.push(resolved);
21938
+ }
21939
+ }
21940
+ graph.set(folder, resolvedEdges);
21941
+ }
21942
+ const visiting = /* @__PURE__ */ new Set();
21943
+ const visited = /* @__PURE__ */ new Set();
21944
+ function visit(node) {
21945
+ if (visiting.has(node)) {
21946
+ return node;
21947
+ }
21948
+ if (visited.has(node) || !graph.has(node)) {
21949
+ return null;
21950
+ }
21951
+ visiting.add(node);
21952
+ for (const dependency of graph.get(node) ?? []) {
21953
+ const cycleNode = visit(dependency);
21954
+ if (cycleNode !== null) {
21955
+ return cycleNode;
21956
+ }
21957
+ }
21958
+ visiting.delete(node);
21959
+ visited.add(node);
21960
+ return null;
21961
+ }
21962
+ for (const start of graph.keys()) {
21963
+ const cycleNode = visit(start);
21964
+ if (cycleNode !== null) {
21965
+ return `Epic checkpoint depends_on graph contains a cycle involving feature_folder: ${cycleNode}`;
21966
+ }
21967
+ }
21968
+ return null;
21969
+ }
21970
+ function validateIntentBlock(state) {
21971
+ if (!("intent" in state)) {
21972
+ return [];
21973
+ }
21974
+ const intent = state["intent"];
21975
+ if (!isObject2(intent)) {
21976
+ return ["Epic checkpoint intent must be an object."];
21977
+ }
21978
+ const errors = [];
21979
+ const epicType = intent["epic_type"];
21980
+ if (typeof epicType !== "string" || !VALID_EPIC_TYPES.has(epicType)) {
21981
+ errors.push(
21982
+ `Epic checkpoint intent.epic_type must be 'business' or 'enabler', found: ${pythonRepr(epicType)}`
21983
+ );
21984
+ }
21985
+ const hypothesis = intent["business_outcome_hypothesis"];
21986
+ if (typeof hypothesis !== "string" || !hypothesis.trim()) {
21987
+ errors.push(
21988
+ "Epic checkpoint intent.business_outcome_hypothesis must be a non-empty string."
21989
+ );
21990
+ }
21991
+ for (const fieldName of ["leading_indicators", "nfrs"]) {
21992
+ if (!(fieldName in intent)) {
21993
+ continue;
21994
+ }
21995
+ const value = intent[fieldName];
21996
+ if (!Array.isArray(value) || !value.every((item) => typeof item === "string")) {
21997
+ errors.push(
21998
+ `Epic checkpoint intent.${fieldName} must be a list of strings.`
21999
+ );
22000
+ }
22001
+ }
22002
+ return errors;
22003
+ }
21788
22004
 
21789
22005
  // ../../extensions/drm-copilot/src/lib/validate/epic-orchestrator-state-core.ts
21790
22006
  var REQUIRED_BASELINE_KEYS = [
@@ -21815,7 +22031,7 @@ var MERGED_STATUSES = /* @__PURE__ */ new Set([
21815
22031
  "merged",
21816
22032
  "worktree_removed"
21817
22033
  ]);
21818
- function isObject2(value) {
22034
+ function isObject3(value) {
21819
22035
  return typeof value === "object" && value !== null && !Array.isArray(value);
21820
22036
  }
21821
22037
  function extractFeatures(state) {
@@ -21823,7 +22039,7 @@ function extractFeatures(state) {
21823
22039
  if (!Array.isArray(features)) {
21824
22040
  return [];
21825
22041
  }
21826
- return features.filter(isObject2);
22042
+ return features.filter(isObject3);
21827
22043
  }
21828
22044
  function missingBaselineAndEpicKeys(state) {
21829
22045
  const errors = [];
@@ -21846,13 +22062,7 @@ function validateFeatureFolderUniquenessAndDependencies(features) {
21846
22062
  const errors = [];
21847
22063
  const seen = /* @__PURE__ */ new Set();
21848
22064
  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
- }
22065
+ const index = buildFeatureReferenceIndex(features);
21856
22066
  for (const feature of features) {
21857
22067
  const folder = feature["feature_folder"];
21858
22068
  if (typeof folder !== "string" || !folder) {
@@ -21867,7 +22077,7 @@ function validateFeatureFolderUniquenessAndDependencies(features) {
21867
22077
  continue;
21868
22078
  }
21869
22079
  for (const dependency of dependsOn) {
21870
- if (!allFolders.has(dependency)) {
22080
+ if (resolveFeatureReference(dependency, index) === null) {
21871
22081
  errors.push(
21872
22082
  `Epic checkpoint feature '${folder}' depends_on unresolved feature_folder: ${JSON.stringify(dependency)}`
21873
22083
  );
@@ -21881,49 +22091,6 @@ function validateFeatureFolderUniquenessAndDependencies(features) {
21881
22091
  }
21882
22092
  return errors;
21883
22093
  }
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
22094
  function validateMergeStatusEnum(features) {
21928
22095
  const errors = [];
21929
22096
  for (const feature of features) {
@@ -21946,6 +22113,7 @@ function validateWaveBarrierOrdering(features) {
21946
22113
  byFolder.set(folder, feature);
21947
22114
  }
21948
22115
  }
22116
+ const index = buildFeatureReferenceIndex(features);
21949
22117
  for (const feature of features) {
21950
22118
  const folder = feature["feature_folder"];
21951
22119
  const dependsOn = feature["depends_on"];
@@ -21954,7 +22122,8 @@ function validateWaveBarrierOrdering(features) {
21954
22122
  }
21955
22123
  const worktreeCreatedAt = feature["worktree_created_at"];
21956
22124
  for (const dependency of dependsOn) {
21957
- const dependencyFeature = byFolder.get(dependency);
22125
+ const resolved = resolveFeatureReference(dependency, index);
22126
+ const dependencyFeature = resolved !== null ? byFolder.get(resolved) : void 0;
21958
22127
  if (dependencyFeature === void 0) {
21959
22128
  continue;
21960
22129
  }
@@ -21977,15 +22146,17 @@ function validateWavesConsistency(state) {
21977
22146
  if (!Array.isArray(waves)) {
21978
22147
  return errors;
21979
22148
  }
22149
+ const features = extractFeatures(state);
21980
22150
  const featuresByFolder = /* @__PURE__ */ new Map();
21981
- for (const feature of extractFeatures(state)) {
22151
+ for (const feature of features) {
21982
22152
  const folder = feature["feature_folder"];
21983
22153
  if (typeof folder === "string") {
21984
22154
  featuresByFolder.set(folder, feature);
21985
22155
  }
21986
22156
  }
22157
+ const index = buildFeatureReferenceIndex(features);
21987
22158
  for (const waveItem of waves) {
21988
- if (!isObject2(waveItem)) {
22159
+ if (!isObject3(waveItem)) {
21989
22160
  continue;
21990
22161
  }
21991
22162
  const waveNumber = waveItem["wave_number"];
@@ -21994,7 +22165,8 @@ function validateWavesConsistency(state) {
21994
22165
  continue;
21995
22166
  }
21996
22167
  for (const folder of folders) {
21997
- const feature = featuresByFolder.get(folder);
22168
+ const resolved = resolveFeatureReference(folder, index);
22169
+ const feature = resolved !== null ? featuresByFolder.get(resolved) : void 0;
21998
22170
  if (feature === void 0) {
21999
22171
  continue;
22000
22172
  }
@@ -22019,7 +22191,7 @@ function validateCompletion(features, state) {
22019
22191
  }
22020
22192
  }
22021
22193
  const epicMergePr = state["epic_merge_pr"];
22022
- const mergeCommitSha = isObject2(epicMergePr) ? epicMergePr["merge_commit_sha"] : void 0;
22194
+ const mergeCommitSha = isObject3(epicMergePr) ? epicMergePr["merge_commit_sha"] : void 0;
22023
22195
  if (typeof mergeCommitSha !== "string" || !mergeCommitSha.trim()) {
22024
22196
  errors.push(
22025
22197
  "Epic checkpoint completion validation failed: epic_merge_pr.merge_commit_sha is missing or empty."
@@ -22036,7 +22208,7 @@ function validateEpicOrchestratorStateText(text, options = {}) {
22036
22208
  `Epic checkpoint is not valid JSON: ${exc instanceof Error ? exc.message : String(exc)}`
22037
22209
  ];
22038
22210
  }
22039
- if (!isObject2(state)) {
22211
+ if (!isObject3(state)) {
22040
22212
  return ["Epic checkpoint root must be a JSON object."];
22041
22213
  }
22042
22214
  const stateMap = state;
@@ -22052,6 +22224,7 @@ function validateEpicOrchestratorStateText(text, options = {}) {
22052
22224
  errors.push(...validateMergeStatusEnum(features));
22053
22225
  errors.push(...validateWaveBarrierOrdering(features));
22054
22226
  errors.push(...validateWavesConsistency(stateMap));
22227
+ errors.push(...validateIntentBlock(stateMap));
22055
22228
  if (options.requireComplete === true) {
22056
22229
  errors.push(...validateCompletion(features, stateMap));
22057
22230
  }
@@ -22074,11 +22247,11 @@ var PROMOTION_RECEIPT_KEYS = [
22074
22247
  "issue",
22075
22248
  "feature_folder"
22076
22249
  ];
22077
- function isObject3(value) {
22250
+ function isObject4(value) {
22078
22251
  return typeof value === "object" && value !== null && !Array.isArray(value);
22079
22252
  }
22080
22253
  function missingObjectKeys(value, keys) {
22081
- if (!isObject3(value)) {
22254
+ if (!isObject4(value)) {
22082
22255
  return [...keys];
22083
22256
  }
22084
22257
  const missing = [];
@@ -22093,7 +22266,7 @@ function missingObjectKeys(value, keys) {
22093
22266
  function validateCompletionPrGate(state) {
22094
22267
  const prGate = state["pr_gate"];
22095
22268
  const missing = missingObjectKeys(prGate, PR_GATE_KEYS);
22096
- if (!isObject3(prGate)) {
22269
+ if (!isObject4(prGate)) {
22097
22270
  return [
22098
22271
  `Checkpoint completion validation failed: pr_gate must be an object with keys: ${PR_GATE_KEYS.join(", ")}.`
22099
22272
  ];
@@ -22116,7 +22289,7 @@ function validateCompletionPrGate(state) {
22116
22289
  function validateCompletionCiGate(state) {
22117
22290
  const ciGate = state["ci_gate"];
22118
22291
  const missing = missingObjectKeys(ciGate, CI_GATE_KEYS);
22119
- if (!isObject3(ciGate)) {
22292
+ if (!isObject4(ciGate)) {
22120
22293
  return [
22121
22294
  `Checkpoint completion validation failed: ci_gate must be an object with keys: ${CI_GATE_KEYS.join(", ")}.`
22122
22295
  ];
@@ -22133,7 +22306,7 @@ function validateCompletionCiGate(state) {
22133
22306
  );
22134
22307
  }
22135
22308
  const prGate = state["pr_gate"];
22136
- const prHeadSha = isObject3(prGate) ? prGate["head_sha"] : null;
22309
+ const prHeadSha = isObject4(prGate) ? prGate["head_sha"] : null;
22137
22310
  if (prHeadSha !== null && prHeadSha !== void 0 && ciGate["head_sha"] !== prHeadSha) {
22138
22311
  errors.push(
22139
22312
  "Checkpoint completion validation failed: ci_gate.head_sha must match pr_gate.head_sha."
@@ -22148,7 +22321,7 @@ function validateIssue232PromotionReceipts(state) {
22148
22321
  const receipts = state["delegation_receipts"];
22149
22322
  let promotionSource = "promotion_receipts";
22150
22323
  let promotion = state["promotion_receipts"];
22151
- if (isObject3(receipts)) {
22324
+ if (isObject4(receipts)) {
22152
22325
  const namespacedPromotion = receipts[PROMOTION_RECEIPT_NAMESPACE_KEY];
22153
22326
  if (namespacedPromotion !== void 0 && namespacedPromotion !== null) {
22154
22327
  promotionSource = "delegation_receipts.promotion";
@@ -22173,10 +22346,10 @@ var HUMAN_INTERACTION_RESPONSE_ENUM = /* @__PURE__ */ new Set([
22173
22346
  "halt"
22174
22347
  ]);
22175
22348
  var HUMAN_INTERACTION_EXCEPTION_RESPONSE = "exception";
22176
- function isObject4(value) {
22349
+ function isObject5(value) {
22177
22350
  return typeof value === "object" && value !== null && !Array.isArray(value);
22178
22351
  }
22179
- function pythonRepr(value) {
22352
+ function pythonRepr2(value) {
22180
22353
  if (value === null || value === void 0) {
22181
22354
  return "None";
22182
22355
  }
@@ -22190,7 +22363,7 @@ function pythonRepr(value) {
22190
22363
  }
22191
22364
  function validateHumanInteraction(humanInteraction) {
22192
22365
  const errors = [];
22193
- if (!isObject4(humanInteraction)) {
22366
+ if (!isObject5(humanInteraction)) {
22194
22367
  errors.push("Checkpoint human_interaction must be an object when present.");
22195
22368
  return errors;
22196
22369
  }
@@ -22200,7 +22373,7 @@ function validateHumanInteraction(humanInteraction) {
22200
22373
  return errors;
22201
22374
  }
22202
22375
  requirements.forEach((requirement, index) => {
22203
- if (!isObject4(requirement)) {
22376
+ if (!isObject5(requirement)) {
22204
22377
  errors.push(
22205
22378
  `Checkpoint human_interaction.requirements #${index} must be an object.`
22206
22379
  );
@@ -22209,7 +22382,7 @@ function validateHumanInteraction(humanInteraction) {
22209
22382
  const response = requirement["response"];
22210
22383
  if (typeof response !== "string" || !HUMAN_INTERACTION_RESPONSE_ENUM.has(response)) {
22211
22384
  errors.push(
22212
- `Checkpoint human_interaction.requirements #${index} response must be one of scope_change, exception, halt; got: ` + pythonRepr(response)
22385
+ `Checkpoint human_interaction.requirements #${index} response must be one of scope_change, exception, halt; got: ` + pythonRepr2(response)
22213
22386
  );
22214
22387
  return;
22215
22388
  }
@@ -22230,7 +22403,7 @@ var REMEDIATION_LOOP_KEY = "remediation_loop";
22230
22403
  var REMEDIATION_CYCLES_KEY = "cycles";
22231
22404
  var EXECUTION_STATUSES_REQUIRING_CLEAR_PREFLIGHT = /* @__PURE__ */ new Set(["in_progress", "complete", "failed"]);
22232
22405
  var PREFLIGHT_CLEARED_STATUS = "clear";
22233
- function isObject5(value) {
22406
+ function isObject6(value) {
22234
22407
  return typeof value === "object" && value !== null && !Array.isArray(value);
22235
22408
  }
22236
22409
  function validateRemediationCycle(index, cycle) {
@@ -22244,7 +22417,7 @@ function validateRemediationCycle(index, cycle) {
22244
22417
  const executionStatus = cycle["execution_status"];
22245
22418
  if (typeof executionStatus === "string" && EXECUTION_STATUSES_REQUIRING_CLEAR_PREFLIGHT.has(executionStatus)) {
22246
22419
  const preflight = cycle["preflight"];
22247
- const preflightStatus = isObject5(preflight) ? preflight["final_status"] : void 0;
22420
+ const preflightStatus = isObject6(preflight) ? preflight["final_status"] : void 0;
22248
22421
  if (preflightStatus !== PREFLIGHT_CLEARED_STATUS) {
22249
22422
  errors.push(
22250
22423
  `Checkpoint remediation cycle #${index} execution_status is ${executionStatus} but preflight.final_status is not 'clear'.`
@@ -22260,7 +22433,7 @@ function validateRemediationCycle(index, cycle) {
22260
22433
  }
22261
22434
  function validateRemediationLoop(remediationLoop) {
22262
22435
  const errors = [];
22263
- if (!isObject5(remediationLoop)) {
22436
+ if (!isObject6(remediationLoop)) {
22264
22437
  return errors;
22265
22438
  }
22266
22439
  const cycles = remediationLoop[REMEDIATION_CYCLES_KEY];
@@ -22268,7 +22441,7 @@ function validateRemediationLoop(remediationLoop) {
22268
22441
  return errors;
22269
22442
  }
22270
22443
  cycles.forEach((cycle, index) => {
22271
- if (!isObject5(cycle)) {
22444
+ if (!isObject6(cycle)) {
22272
22445
  errors.push(`Checkpoint remediation cycle #${index} must be an object.`);
22273
22446
  return;
22274
22447
  }
@@ -22279,12 +22452,12 @@ function validateRemediationLoop(remediationLoop) {
22279
22452
 
22280
22453
  // ../../extensions/drm-copilot/src/lib/validate/orchestrator-state-routing.ts
22281
22454
  var ROUTING_MATRIX_RELATIVE_PATH = "config/orchestration-routing.json";
22282
- function isObject6(value) {
22455
+ function isObject7(value) {
22283
22456
  return typeof value === "object" && value !== null && !Array.isArray(value);
22284
22457
  }
22285
22458
  function loadRoutingMatrix(fs9, root) {
22286
- const path10 = `${toPosixPath2(root).replace(/\/+$/, "")}/${ROUTING_MATRIX_RELATIVE_PATH}`;
22287
- return JSON.parse(fs9.readTextFile(path10));
22459
+ const path11 = `${toPosixPath2(root).replace(/\/+$/, "")}/${ROUTING_MATRIX_RELATIVE_PATH}`;
22460
+ return JSON.parse(fs9.readTextFile(path11));
22288
22461
  }
22289
22462
  function stringList(value) {
22290
22463
  if (!Array.isArray(value)) {
@@ -22316,7 +22489,7 @@ function listReceipts(receipts) {
22316
22489
  if (!Array.isArray(receipts)) {
22317
22490
  return [];
22318
22491
  }
22319
- return receipts.filter(isObject6);
22492
+ return receipts.filter(isObject7);
22320
22493
  }
22321
22494
  function receiptAgents(state) {
22322
22495
  const agents = /* @__PURE__ */ new Set();
@@ -22335,7 +22508,7 @@ function receiptSkills(state) {
22335
22508
  return skills;
22336
22509
  }
22337
22510
  for (const receipt of receipts) {
22338
- if (!isObject6(receipt)) {
22511
+ if (!isObject7(receipt)) {
22339
22512
  continue;
22340
22513
  }
22341
22514
  const skill = receipt["skill"];
@@ -22354,7 +22527,7 @@ function mcpTools(state) {
22354
22527
  return tools;
22355
22528
  }
22356
22529
  for (const receipt of receipts) {
22357
- if (!isObject6(receipt)) {
22530
+ if (!isObject7(receipt)) {
22358
22531
  continue;
22359
22532
  }
22360
22533
  const tool = receipt["tool"];
@@ -22386,7 +22559,7 @@ function validateLifecycleOperations(state) {
22386
22559
  }
22387
22560
  const errors = [];
22388
22561
  operations.forEach((operation, index) => {
22389
- if (!isObject6(operation)) {
22562
+ if (!isObject7(operation)) {
22390
22563
  errors.push(
22391
22564
  `Checkpoint lifecycle_operations #${index} must be an object.`
22392
22565
  );
@@ -22402,11 +22575,11 @@ function validateLifecycleOperations(state) {
22402
22575
  }
22403
22576
  function validateRoutingContract(state, options = {}) {
22404
22577
  const matrix = options.routingMatrix;
22405
- if (!isObject6(matrix)) {
22578
+ if (!isObject7(matrix)) {
22406
22579
  return ["Routing matrix missing routes object."];
22407
22580
  }
22408
22581
  const rawRoutes = matrix["routes"];
22409
- if (!isObject6(rawRoutes)) {
22582
+ if (!isObject7(rawRoutes)) {
22410
22583
  return ["Routing matrix missing routes object."];
22411
22584
  }
22412
22585
  const routeIdValue = state["route_id"] !== void 0 ? state["route_id"] : state["path_selected"];
@@ -22415,7 +22588,7 @@ function validateRoutingContract(state, options = {}) {
22415
22588
  }
22416
22589
  const routeId = routeIdValue;
22417
22590
  const rawRoute = rawRoutes[routeId];
22418
- if (!isObject6(rawRoute)) {
22591
+ if (!isObject7(rawRoute)) {
22419
22592
  return [
22420
22593
  `Checkpoint selected route has no routing-matrix entry: ${routeId}.`
22421
22594
  ];
@@ -22533,13 +22706,13 @@ var DELEGATING_AGENTS = /* @__PURE__ */ new Set([
22533
22706
  "prd-feature",
22534
22707
  "pr-author"
22535
22708
  ]);
22536
- function isObject7(value) {
22709
+ function isObject8(value) {
22537
22710
  return typeof value === "object" && value !== null && !Array.isArray(value);
22538
22711
  }
22539
22712
  function validateListDelegationReceipts(receipts) {
22540
22713
  const errors = [];
22541
22714
  receipts.forEach((receipt, index) => {
22542
- if (!isObject7(receipt)) {
22715
+ if (!isObject8(receipt)) {
22543
22716
  errors.push(`Checkpoint delegation receipt #${index} must be an object.`);
22544
22717
  return;
22545
22718
  }
@@ -22571,7 +22744,7 @@ function validateNamespacedDelegationReceipts(receipts) {
22571
22744
  if (promotionReceipts === void 0 || promotionReceipts === null) {
22572
22745
  return errors;
22573
22746
  }
22574
- if (!isObject7(promotionReceipts)) {
22747
+ if (!isObject8(promotionReceipts)) {
22575
22748
  errors.push(
22576
22749
  "Checkpoint delegation_receipts.promotion must be an object namespace."
22577
22750
  );
@@ -22601,7 +22774,7 @@ function delegatedAgents(stateMap) {
22601
22774
  const receipts = stateMap["delegation_receipts"];
22602
22775
  if (Array.isArray(receipts)) {
22603
22776
  receipts.forEach((receipt) => {
22604
- if (!isObject7(receipt)) {
22777
+ if (!isObject8(receipt)) {
22605
22778
  return;
22606
22779
  }
22607
22780
  const agentName = receipt["agent_name"];
@@ -22626,7 +22799,7 @@ function validateModelRoutingExistence(stateMap) {
22626
22799
  const receipts = stateMap["model_routing_receipts"];
22627
22800
  if (Array.isArray(receipts)) {
22628
22801
  receipts.forEach((receipt) => {
22629
- if (!isObject7(receipt)) {
22802
+ if (!isObject8(receipt)) {
22630
22803
  return;
22631
22804
  }
22632
22805
  const agent = receipt["agent"];
@@ -22653,7 +22826,7 @@ function validateOrchestratorStateText(text, options = {}) {
22653
22826
  `Checkpoint is not valid JSON: ${exc instanceof Error ? exc.message : String(exc)}`
22654
22827
  ];
22655
22828
  }
22656
- if (!isObject7(state)) {
22829
+ if (!isObject8(state)) {
22657
22830
  return ["Checkpoint root must be a JSON object."];
22658
22831
  }
22659
22832
  const stateMap = state;
@@ -22678,7 +22851,7 @@ function validateOrchestratorStateText(text, options = {}) {
22678
22851
  if (receipts !== void 0 && receipts !== null) {
22679
22852
  if (Array.isArray(receipts)) {
22680
22853
  errors.push(...validateListDelegationReceipts(receipts));
22681
- } else if (isObject7(receipts)) {
22854
+ } else if (isObject8(receipts)) {
22682
22855
  errors.push(...validateNamespacedDelegationReceipts(receipts));
22683
22856
  } else {
22684
22857
  errors.push(
@@ -23114,7 +23287,7 @@ function validateArtifact(input) {
23114
23287
  // ../../extensions/drm-copilot/src/lib/validate/validate-orchestration-service-call.ts
23115
23288
  function validateOrchestrationServiceCall(input) {
23116
23289
  const artifactFullPath = toPosixPath2(
23117
- path8.join(input.workspaceRoot, input.artifactPath)
23290
+ path9.join(input.workspaceRoot, input.artifactPath)
23118
23291
  );
23119
23292
  const text = input.fileSystem.readTextFile(artifactFullPath);
23120
23293
  const errors = validateArtifact({
@@ -23990,13 +24163,13 @@ var GhClient = class {
23990
24163
  * @param path Repo-relative file path.
23991
24164
  * @returns The decoded file content, or `null`.
23992
24165
  */
23993
- fetchRepoFile(path10) {
24166
+ fetchRepoFile(path11) {
23994
24167
  this.ensureAvailable();
23995
24168
  const repo = this.repoName();
23996
24169
  if (!repo) {
23997
24170
  return null;
23998
24171
  }
23999
- const apiPath = `repos/${repo}/contents/${path10.replace(/^\/+/u, "")}`;
24172
+ const apiPath = `repos/${repo}/contents/${path11.replace(/^\/+/u, "")}`;
24000
24173
  let payload;
24001
24174
  try {
24002
24175
  payload = this.requestJson([this.ghExecutable, "api", apiPath], {
@@ -24611,8 +24784,8 @@ function resolveFeatureDir2(fs9, baseDir, feature) {
24611
24784
  }
24612
24785
  return null;
24613
24786
  }
24614
- function readText(fs9, path10) {
24615
- return fs9.exists(path10) ? fs9.readTextFile(path10) : "";
24787
+ function readText(fs9, path11) {
24788
+ return fs9.exists(path11) ? fs9.readTextFile(path11) : "";
24616
24789
  }
24617
24790
  function latestGlobPath(fs9, directory, pattern) {
24618
24791
  const matches = [...fs9.glob(directory, pattern)].sort(compareCodePoint4);
@@ -24670,9 +24843,9 @@ function resolveReadinessSignal(fs9, featureDir) {
24670
24843
  }
24671
24844
  return [null, null];
24672
24845
  }
24673
- function relativeToPosix4(root, path10) {
24846
+ function relativeToPosix4(root, path11) {
24674
24847
  const normalizedRoot = toPosixPath2(root).replace(/\/+$/u, "");
24675
- const normalized = toPosixPath2(path10);
24848
+ const normalized = toPosixPath2(path11);
24676
24849
  if (normalized.startsWith(`${normalizedRoot}/`)) {
24677
24850
  return normalized.slice(normalizedRoot.length + 1);
24678
24851
  }
@@ -24974,9 +25147,9 @@ function buildExcerpt(feature, storyParts, specParts, planSection, verificationB
24974
25147
  function buildContextFiles(params) {
24975
25148
  const { fs: fs9, root, feature, candidatePaths, readinessSource } = params;
24976
25149
  const contextFiles = [];
24977
- for (const path10 of candidatePaths) {
24978
- if (fs9.exists(path10)) {
24979
- contextFiles.push(relativeToPosix4(root, path10));
25150
+ for (const path11 of candidatePaths) {
25151
+ if (fs9.exists(path11)) {
25152
+ contextFiles.push(relativeToPosix4(root, path11));
24980
25153
  }
24981
25154
  }
24982
25155
  if (readinessSource !== null) {
@@ -25186,13 +25359,13 @@ function parseNameStatusMap(nameStatusText) {
25186
25359
  continue;
25187
25360
  }
25188
25361
  const status = parts[0].trim();
25189
- const path10 = formatDiffPath2(parts[parts.length - 1].trim());
25190
- mapping.set(path10, status);
25362
+ const path11 = formatDiffPath2(parts[parts.length - 1].trim());
25363
+ mapping.set(path11, status);
25191
25364
  }
25192
25365
  return mapping;
25193
25366
  }
25194
- function isScopingDoc(path10) {
25195
- const lowered = path10.toLowerCase();
25367
+ function isScopingDoc(path11) {
25368
+ const lowered = path11.toLowerCase();
25196
25369
  return lowered.startsWith("docs/features/") && (lowered.endsWith("/spec.md") || lowered.endsWith("/plan.md") || lowered.endsWith("/bug-remediation-plan.md") || lowered.endsWith("/user-story.md") || lowered.endsWith("/readme.md"));
25197
25370
  }
25198
25371
  function scopingDocChanges(options) {
@@ -25202,11 +25375,11 @@ function scopingDocChanges(options) {
25202
25375
  }
25203
25376
  const changes = [];
25204
25377
  const nameStatusMap = parseNameStatusMap(nameStatusText);
25205
- for (const [path10, status] of nameStatusMap) {
25206
- if (!isScopingDoc(path10)) {
25378
+ for (const [path11, status] of nameStatusMap) {
25379
+ if (!isScopingDoc(path11)) {
25207
25380
  continue;
25208
25381
  }
25209
- const [additions, deletions] = numstatDetails.get(path10) ?? [0, 0];
25382
+ const [additions, deletions] = numstatDetails.get(path11) ?? [0, 0];
25210
25383
  const reasons = [];
25211
25384
  let material = false;
25212
25385
  if (status.startsWith("A")) {
@@ -25222,7 +25395,7 @@ function scopingDocChanges(options) {
25222
25395
  mergeBase,
25223
25396
  headSha,
25224
25397
  "--",
25225
- path10
25398
+ path11
25226
25399
  ]);
25227
25400
  let headingTouched = false;
25228
25401
  for (const line of splitLines2(diffText)) {
@@ -25251,7 +25424,7 @@ function scopingDocChanges(options) {
25251
25424
  }
25252
25425
  }
25253
25426
  let excerpt = null;
25254
- const docPath = `${stripTrailingSlash(root)}/${path10}`;
25427
+ const docPath = `${stripTrailingSlash(root)}/${path11}`;
25255
25428
  if (material && fs9.exists(docPath)) {
25256
25429
  const content = fs9.readTextFile(docPath);
25257
25430
  const excerptParts = [];
@@ -25265,7 +25438,7 @@ ${truncateLines(sectionText, 40)}`);
25265
25438
  excerpt = excerptParts.length > 0 ? excerptParts.slice(0, 3).join("\n\n") : null;
25266
25439
  }
25267
25440
  changes.push({
25268
- path: path10,
25441
+ path: path11,
25269
25442
  additions,
25270
25443
  deletions,
25271
25444
  changeType: status,
@@ -25285,7 +25458,7 @@ function bucketText(name, entries) {
25285
25458
  );
25286
25459
  const lines = [
25287
25460
  `${name}: ${entries.length} files`,
25288
- ...sortedEntries.slice(0, 10).map(([path10, [adds, dels]]) => `- ${path10} (+${adds}/-${dels})`)
25461
+ ...sortedEntries.slice(0, 10).map(([path11, [adds, dels]]) => `- ${path11} (+${adds}/-${dels})`)
25289
25462
  ];
25290
25463
  return lines.join("\n");
25291
25464
  }
@@ -25363,7 +25536,7 @@ function collectPrContext(options) {
25363
25536
  const changedPaths = extractChangedPaths(contextResult.text);
25364
25537
  const featureDocs = gatherFeatureExcerpts2(fs9, resolvedRoot, changedPaths);
25365
25538
  const additionalContextFiles = sortedSet3(
25366
- featureDocs.flatMap((doc) => doc.contextFiles).filter((path10) => path10)
25539
+ featureDocs.flatMap((doc) => doc.contextFiles).filter((path11) => path11)
25367
25540
  );
25368
25541
  const featureIssueRefs = sortedSet3(
25369
25542
  featureDocs.flatMap((doc) => doc.issueRefs).filter((ref) => ref.trim())
@@ -25499,14 +25672,14 @@ function collectPrContext(options) {
25499
25672
  const bucketCore = [];
25500
25673
  const bucketRenames = [];
25501
25674
  const bucketDocs = [];
25502
- for (const [path10, status] of statusMap) {
25503
- const stats = perFileStats.get(path10) ?? [0, 0];
25675
+ for (const [path11, status] of statusMap) {
25676
+ const stats = perFileStats.get(path11) ?? [0, 0];
25504
25677
  if (status.startsWith("R")) {
25505
- bucketRenames.push([path10, stats]);
25506
- } else if (path10.endsWith(".py") || path10.endsWith(".ps1")) {
25507
- bucketCore.push([path10, stats]);
25508
- } else if (path10.startsWith("docs/") || path10.startsWith(".github") || path10.includes("AGENTS")) {
25509
- bucketDocs.push([path10, stats]);
25678
+ bucketRenames.push([path11, stats]);
25679
+ } else if (path11.endsWith(".py") || path11.endsWith(".ps1")) {
25680
+ bucketCore.push([path11, stats]);
25681
+ } else if (path11.startsWith("docs/") || path11.startsWith(".github") || path11.includes("AGENTS")) {
25682
+ bucketDocs.push([path11, stats]);
25510
25683
  }
25511
25684
  }
25512
25685
  return {
@@ -25819,9 +25992,9 @@ function buildScopingSummaryLines(collected) {
25819
25992
  const lines = [];
25820
25993
  if (collected.materialScoping.length > 0) {
25821
25994
  lines.push("Scoping docs changed (material):");
25822
- for (const { path: path10, reasons, excerpt } of collected.materialScoping) {
25995
+ for (const { path: path11, reasons, excerpt } of collected.materialScoping) {
25823
25996
  const reasonText = `Reasons: ${reasons.length > 0 ? reasons.join(", ") : "(unspecified)"}`;
25824
- lines.push(`- ${path10} (${reasonText})`);
25997
+ lines.push(`- ${path11} (${reasonText})`);
25825
25998
  if (excerpt) {
25826
25999
  lines.push(truncateLines(excerpt, 40));
25827
26000
  }
@@ -25829,9 +26002,9 @@ function buildScopingSummaryLines(collected) {
25829
26002
  }
25830
26003
  if (collected.nonMaterialScoping.length > 0) {
25831
26004
  lines.push("Scoping docs changed (non-material):");
25832
- for (const { path: path10, reasons } of collected.nonMaterialScoping.slice(0, 5)) {
26005
+ for (const { path: path11, reasons } of collected.nonMaterialScoping.slice(0, 5)) {
25833
26006
  const reasonText = `Reasons: ${reasons.length > 0 ? reasons.join(", ") : "(unspecified)"}`;
25834
- lines.push(`- ${path10} (${reasonText})`);
26007
+ lines.push(`- ${path11} (${reasonText})`);
25835
26008
  }
25836
26009
  }
25837
26010
  if (lines.length === 0) {
@@ -25855,8 +26028,8 @@ function buildCloseCandidatesSectionFromCollected(collected) {
25855
26028
  authorReason: collected.authorReason
25856
26029
  });
25857
26030
  }
25858
- function parentDir(path10) {
25859
- const normalized = toPosixPath2(path10);
26031
+ function parentDir(path11) {
26032
+ const normalized = toPosixPath2(path11);
25860
26033
  const index = normalized.lastIndexOf("/");
25861
26034
  return index <= 0 ? "" : normalized.slice(0, index);
25862
26035
  }
@@ -26236,20 +26409,20 @@ var RealPotentialFileSystem = class {
26236
26409
  return nodePath6.resolve(expanded);
26237
26410
  }
26238
26411
  /** @returns True when `path` exists. */
26239
- exists(path10) {
26240
- return fs6.existsSync(path10);
26412
+ exists(path11) {
26413
+ return fs6.existsSync(path11);
26241
26414
  }
26242
26415
  /** @returns The UTF-8 file content. */
26243
- readText(path10) {
26244
- return fs6.readFileSync(path10, "utf8");
26416
+ readText(path11) {
26417
+ return fs6.readFileSync(path11, "utf8");
26245
26418
  }
26246
26419
  /** Write `lines` joined with `\n` as UTF-8 text. */
26247
- writeLines(path10, lines) {
26248
- fs6.writeFileSync(path10, lines.join("\n"), "utf8");
26420
+ writeLines(path11, lines) {
26421
+ fs6.writeFileSync(path11, lines.join("\n"), "utf8");
26249
26422
  }
26250
26423
  /** Create `path` and any missing parents (idempotent). */
26251
- ensureDir(path10) {
26252
- fs6.mkdirSync(path10, { recursive: true });
26424
+ ensureDir(path11) {
26425
+ fs6.mkdirSync(path11, { recursive: true });
26253
26426
  }
26254
26427
  /** Move `src` to `dest`, ensuring the destination parent exists first. */
26255
26428
  move(src, dest) {
@@ -26533,8 +26706,8 @@ var RealFolderFileSystem = class {
26533
26706
  * @param path Path to test.
26534
26707
  * @returns True when `path` exists (file or directory).
26535
26708
  */
26536
- exists(path10) {
26537
- return nodeFs.existsSync(path10);
26709
+ exists(path11) {
26710
+ return nodeFs.existsSync(path11);
26538
26711
  }
26539
26712
  /**
26540
26713
  * Create `path` including missing parents.
@@ -26544,8 +26717,8 @@ var RealFolderFileSystem = class {
26544
26717
  *
26545
26718
  * @param path Directory path to create.
26546
26719
  */
26547
- ensureDir(path10) {
26548
- nodeFs.mkdirSync(path10, { recursive: true });
26720
+ ensureDir(path11) {
26721
+ nodeFs.mkdirSync(path11, { recursive: true });
26549
26722
  }
26550
26723
  /**
26551
26724
  * Copy the file bytes from `src` to `dest`.
@@ -26597,15 +26770,15 @@ var RealFolderFileSystem = class {
26597
26770
  * @returns Forward-slash file paths directly under `path`, or `[]` when the
26598
26771
  * directory is missing.
26599
26772
  */
26600
- listFiles(path10) {
26601
- if (!nodeFs.existsSync(path10)) {
26773
+ listFiles(path11) {
26774
+ if (!nodeFs.existsSync(path11)) {
26602
26775
  return [];
26603
26776
  }
26604
- const entries = nodeFs.readdirSync(path10, { withFileTypes: true });
26777
+ const entries = nodeFs.readdirSync(path11, { withFileTypes: true });
26605
26778
  const files = [];
26606
26779
  for (const entry of entries) {
26607
26780
  if (entry.isFile()) {
26608
- files.push(joinPosix13(toPosixPath2(path10), entry.name));
26781
+ files.push(joinPosix13(toPosixPath2(path11), entry.name));
26609
26782
  }
26610
26783
  }
26611
26784
  return files;
@@ -26614,8 +26787,8 @@ var RealFolderFileSystem = class {
26614
26787
  * @param path File to read.
26615
26788
  * @returns The file content decoded as UTF-8.
26616
26789
  */
26617
- readText(path10) {
26618
- return nodeFs.readFileSync(path10, "utf8");
26790
+ readText(path11) {
26791
+ return nodeFs.readFileSync(path11, "utf8");
26619
26792
  }
26620
26793
  /**
26621
26794
  * Write `content` to `path`, creating the parent directory first.
@@ -26623,10 +26796,10 @@ var RealFolderFileSystem = class {
26623
26796
  * @param path File to write.
26624
26797
  * @param content Text content to write as UTF-8.
26625
26798
  */
26626
- writeText(path10, content) {
26627
- const parent = toPosixPath2(nodePath8.dirname(path10));
26799
+ writeText(path11, content) {
26800
+ const parent = toPosixPath2(nodePath8.dirname(path11));
26628
26801
  nodeFs.mkdirSync(parent, { recursive: true });
26629
- nodeFs.writeFileSync(path10, content, "utf8");
26802
+ nodeFs.writeFileSync(path11, content, "utf8");
26630
26803
  }
26631
26804
  /**
26632
26805
  * Move `src` to `dest`, replacing an existing destination file.
@@ -26969,22 +27142,22 @@ function defaultCodeLauncher2(files, deps = {
26969
27142
  }
26970
27143
 
26971
27144
  // ../../extensions/drm-copilot/src/lib/new-active-feature-folder/io.ts
26972
- function baseName(path10) {
26973
- const normalized = toPosixPath2(path10).replace(/\/+$/, "");
27145
+ function baseName(path11) {
27146
+ const normalized = toPosixPath2(path11).replace(/\/+$/, "");
26974
27147
  const slash = normalized.lastIndexOf("/");
26975
27148
  return slash === -1 ? normalized : normalized.slice(slash + 1);
26976
27149
  }
26977
- function suffix(path10) {
26978
- const name = baseName(path10);
27150
+ function suffix(path11) {
27151
+ const name = baseName(path11);
26979
27152
  const dot = name.lastIndexOf(".");
26980
27153
  if (dot <= 0) {
26981
27154
  return "";
26982
27155
  }
26983
27156
  return name.slice(dot);
26984
27157
  }
26985
- function stem(path10) {
26986
- const name = baseName(path10);
26987
- const ext = suffix(path10);
27158
+ function stem(path11) {
27159
+ const name = baseName(path11);
27160
+ const ext = suffix(path11);
26988
27161
  return ext ? name.slice(0, name.length - ext.length) : name;
26989
27162
  }
26990
27163
  function findPotentialFile(featureName, workspace2, fs9) {
@@ -27036,6 +27209,13 @@ function copyTemplate(featureType, templateDir, targetDir, fs9) {
27036
27209
  }
27037
27210
  }
27038
27211
  }
27212
+ } else if (featureType === "epic") {
27213
+ for (const name of ["epic.md", "epic-status.md"]) {
27214
+ const src = joinPosix13(templateDir, name);
27215
+ if (fs9.exists(src)) {
27216
+ fs9.copyFile(src, joinPosix13(targetDir, name));
27217
+ }
27218
+ }
27039
27219
  } else {
27040
27220
  fs9.copyTree(templateDir, targetDir);
27041
27221
  }
@@ -27121,11 +27301,11 @@ function defaultIssueFetcher(issueNumber, runner, ghLookup = defaultGhLookup) {
27121
27301
  }
27122
27302
 
27123
27303
  // ../../extensions/drm-copilot/src/lib/new-active-feature-folder/docs.ts
27124
- function applyHeaderAndSections(path10, featureName, issueField, ownerField, updatedField, parentField, statusField, versionField, fs9, updates) {
27125
- if (!fs9.exists(path10)) {
27304
+ function applyHeaderAndSections(path11, featureName, issueField, ownerField, updatedField, parentField, statusField, versionField, fs9, updates) {
27305
+ if (!fs9.exists(path11)) {
27126
27306
  return;
27127
27307
  }
27128
- let content = fs9.readText(path10);
27308
+ let content = fs9.readText(path11);
27129
27309
  content = setHeaderPlaceholder(
27130
27310
  content,
27131
27311
  featureName,
@@ -27139,7 +27319,7 @@ function applyHeaderAndSections(path10, featureName, issueField, ownerField, upd
27139
27319
  for (const [sectionName, body] of updates) {
27140
27320
  content = setSection(content, sectionName, body);
27141
27321
  }
27142
- fs9.writeText(path10, content);
27322
+ fs9.writeText(path11, content);
27143
27323
  }
27144
27324
  function updateFeatureDocs(featureType, featureName, targetDir, issueField, ownerField, updatedField, parentField, statusField, versionField, planUpdatedField, fs9, sections, planPath) {
27145
27325
  const filesToOpen = [];
@@ -27233,9 +27413,9 @@ function updateFeatureDocs(featureType, featureName, targetDir, issueField, owne
27233
27413
  );
27234
27414
  filesToOpen.push(spec, plan);
27235
27415
  } else if (featureType === "epic") {
27236
- const initiative = joinPosix13(targetDir, "initiative.md");
27416
+ const epic = joinPosix13(targetDir, "epic.md");
27237
27417
  applyHeaderAndSections(
27238
- initiative,
27418
+ epic,
27239
27419
  featureName,
27240
27420
  issueField,
27241
27421
  ownerField,
@@ -27246,7 +27426,7 @@ function updateFeatureDocs(featureType, featureName, targetDir, issueField, owne
27246
27426
  fs9,
27247
27427
  []
27248
27428
  );
27249
- filesToOpen.push(initiative);
27429
+ filesToOpen.push(epic);
27250
27430
  } else if (featureType === "bug") {
27251
27431
  const spec = joinPosix13(targetDir, "spec.md");
27252
27432
  const plan = planPath ?? joinPosix13(targetDir, "plan.md");
@@ -27413,15 +27593,18 @@ function createActiveFolder(options) {
27413
27593
  if (!normalizedIssueNumber) {
27414
27594
  normalizedIssueNumber = parseIssueNumber(potentialContent);
27415
27595
  }
27416
- const folderSlug = buildFolderSlug(
27417
- resolvedFeatureName,
27418
- potentialFile,
27419
- normalizedIssueNumber
27420
- );
27421
- const targetDir = joinPosix13(
27422
- workspacePath,
27423
- `docs/features/active/${folderSlug}`
27424
- );
27596
+ let targetDir;
27597
+ if (featureType === "epic") {
27598
+ const epicSlug = buildFolderSlug(resolvedFeatureName, null, null);
27599
+ targetDir = joinPosix13(workspacePath, `docs/features/epics/${epicSlug}`);
27600
+ } else {
27601
+ const folderSlug = buildFolderSlug(
27602
+ resolvedFeatureName,
27603
+ potentialFile,
27604
+ normalizedIssueNumber
27605
+ );
27606
+ targetDir = joinPosix13(workspacePath, `docs/features/active/${folderSlug}`);
27607
+ }
27425
27608
  if (filesystem.exists(targetDir) && !force) {
27426
27609
  throw new Error(
27427
27610
  `Target exists: ${targetDir}. Re-run with --force to overwrite.`
@@ -27561,7 +27744,7 @@ function createActiveFolder(options) {
27561
27744
  emit(`Fallback reason: ${fallbackReason}`);
27562
27745
  }
27563
27746
  if (filesToOpen.length > 0) {
27564
- const existing = filesToOpen.filter((path10) => filesystem.exists(path10));
27747
+ const existing = filesToOpen.filter((path11) => filesystem.exists(path11));
27565
27748
  if (potentialIssuePath) {
27566
27749
  existing.push(potentialIssuePath);
27567
27750
  }
@@ -27569,8 +27752,8 @@ function createActiveFolder(options) {
27569
27752
  const opened = codeLauncher(existing);
27570
27753
  if (!opened) {
27571
27754
  emit("VS Code 'code' command not found. Files to edit:");
27572
- for (const path10 of existing) {
27573
- emit(` ${path10}`);
27755
+ for (const path11 of existing) {
27756
+ emit(` ${path11}`);
27574
27757
  }
27575
27758
  }
27576
27759
  }
@@ -27581,21 +27764,21 @@ function createActiveFolder(options) {
27581
27764
  potentialIssuePath: potentialIssuePath ?? null
27582
27765
  };
27583
27766
  }
27584
- function isAbsolutePosix(path10) {
27585
- return path10.startsWith("/") || /^[A-Za-z]:\//.test(path10);
27767
+ function isAbsolutePosix(path11) {
27768
+ return path11.startsWith("/") || /^[A-Za-z]:\//.test(path11);
27586
27769
  }
27587
27770
  function isRelativeTo(child, root) {
27588
27771
  const normalizedChild = toPosixPath2(child);
27589
27772
  const normalizedRoot = toPosixPath2(root);
27590
27773
  return normalizedChild === normalizedRoot || normalizedChild.startsWith(`${normalizedRoot}/`);
27591
27774
  }
27592
- function posixBaseName(path10) {
27593
- const normalized = toPosixPath2(path10).replace(/\/+$/, "");
27775
+ function posixBaseName(path11) {
27776
+ const normalized = toPosixPath2(path11).replace(/\/+$/, "");
27594
27777
  const slash = normalized.lastIndexOf("/");
27595
27778
  return slash === -1 ? normalized : normalized.slice(slash + 1);
27596
27779
  }
27597
- function posixStem2(path10) {
27598
- const name = posixBaseName(path10);
27780
+ function posixStem2(path11) {
27781
+ const name = posixBaseName(path11);
27599
27782
  const dot = name.lastIndexOf(".");
27600
27783
  return dot <= 0 ? name : name.slice(0, dot);
27601
27784
  }
@@ -27626,6 +27809,299 @@ function newActiveFeatureFolderServiceCall(input) {
27626
27809
  };
27627
27810
  }
27628
27811
 
27812
+ // ../../extensions/drm-copilot/src/lib/subagent-tree/tree-assembler.ts
27813
+ var ROOT_KEY = "__root__";
27814
+ function assembleTree(scanned) {
27815
+ const transcriptsByKey = /* @__PURE__ */ new Map();
27816
+ transcriptsByKey.set(ROOT_KEY, scanned.root);
27817
+ for (const subagent of scanned.subagents) {
27818
+ transcriptsByKey.set(subagent.meta.agentId, subagent.transcript);
27819
+ }
27820
+ const matchedChildrenByParentKey = /* @__PURE__ */ new Map();
27821
+ const orphans = [];
27822
+ for (const subagent of scanned.subagents) {
27823
+ const parentKey = findParentKey(subagent.meta.toolUseId, transcriptsByKey);
27824
+ if (parentKey === void 0) {
27825
+ orphans.push(subagent);
27826
+ continue;
27827
+ }
27828
+ const siblings = matchedChildrenByParentKey.get(parentKey) ?? [];
27829
+ siblings.push(subagent);
27830
+ matchedChildrenByParentKey.set(parentKey, siblings);
27831
+ }
27832
+ orphans.sort(compareByAgentId);
27833
+ return buildNode({
27834
+ key: ROOT_KEY,
27835
+ agentType: "root",
27836
+ description: "",
27837
+ depth: 0,
27838
+ models: scanned.root.models,
27839
+ transcriptsByKey,
27840
+ matchedChildrenByParentKey,
27841
+ orphans
27842
+ });
27843
+ }
27844
+ function findParentKey(toolUseId, transcriptsByKey) {
27845
+ for (const [key, transcript] of transcriptsByKey) {
27846
+ if (transcript.agentToolUseIds.includes(toolUseId)) {
27847
+ return key;
27848
+ }
27849
+ }
27850
+ return void 0;
27851
+ }
27852
+ function compareByAgentId(a, b) {
27853
+ if (a.meta.agentId < b.meta.agentId) {
27854
+ return -1;
27855
+ }
27856
+ if (a.meta.agentId > b.meta.agentId) {
27857
+ return 1;
27858
+ }
27859
+ return 0;
27860
+ }
27861
+ function sortBySpawnIndex(children, parentTranscript) {
27862
+ return [...children].sort((a, b) => {
27863
+ const indexA = parentTranscript.agentToolUseIds.indexOf(a.meta.toolUseId);
27864
+ const indexB = parentTranscript.agentToolUseIds.indexOf(b.meta.toolUseId);
27865
+ if (indexA !== indexB) {
27866
+ return indexA - indexB;
27867
+ }
27868
+ return compareByAgentId(a, b);
27869
+ });
27870
+ }
27871
+ function buildNode(input) {
27872
+ const {
27873
+ key,
27874
+ agentType,
27875
+ description,
27876
+ depth,
27877
+ models,
27878
+ transcriptsByKey,
27879
+ matchedChildrenByParentKey,
27880
+ orphans
27881
+ } = input;
27882
+ const transcript = transcriptsByKey.get(key);
27883
+ const matchedChildren = matchedChildrenByParentKey.get(key) ?? [];
27884
+ const orderedMatched = transcript ? sortBySpawnIndex(matchedChildren, transcript) : matchedChildren;
27885
+ const isRoot = key === ROOT_KEY;
27886
+ const orderedChildren = isRoot ? [...orderedMatched, ...orphans] : orderedMatched;
27887
+ const children = orderedChildren.map(
27888
+ (subagent) => buildNode({
27889
+ key: subagent.meta.agentId,
27890
+ agentType: subagent.meta.agentType,
27891
+ description: subagent.meta.description,
27892
+ depth: subagent.meta.spawnDepth,
27893
+ models: subagent.transcript.models,
27894
+ transcriptsByKey,
27895
+ matchedChildrenByParentKey,
27896
+ orphans
27897
+ })
27898
+ );
27899
+ return {
27900
+ agentType,
27901
+ description,
27902
+ depth,
27903
+ models: [...models].sort(),
27904
+ children
27905
+ };
27906
+ }
27907
+
27908
+ // ../../extensions/drm-copilot/src/lib/subagent-tree/transcript-parser.ts
27909
+ function parseTranscriptLines(lines) {
27910
+ const models = [];
27911
+ const seenModels = /* @__PURE__ */ new Set();
27912
+ const agentToolUseIds = [];
27913
+ for (const line of lines) {
27914
+ const trimmed = line.trim();
27915
+ if (trimmed.length === 0) {
27916
+ continue;
27917
+ }
27918
+ const parsed = tryParseJson(trimmed);
27919
+ if (!isRecord2(parsed)) {
27920
+ continue;
27921
+ }
27922
+ const message = parsed["message"];
27923
+ if (!isRecord2(message)) {
27924
+ continue;
27925
+ }
27926
+ recordModel(message["model"], models, seenModels);
27927
+ collectAgentToolUseIds(message["content"], agentToolUseIds);
27928
+ }
27929
+ return { models, agentToolUseIds };
27930
+ }
27931
+ function tryParseJson(text) {
27932
+ try {
27933
+ return JSON.parse(text);
27934
+ } catch {
27935
+ return void 0;
27936
+ }
27937
+ }
27938
+ function isRecord2(value) {
27939
+ return typeof value === "object" && value !== null && !Array.isArray(value);
27940
+ }
27941
+ function recordModel(model, models, seenModels) {
27942
+ if (typeof model === "string" && model.length > 0 && !seenModels.has(model)) {
27943
+ seenModels.add(model);
27944
+ models.push(model);
27945
+ }
27946
+ }
27947
+ function collectAgentToolUseIds(content, agentToolUseIds) {
27948
+ if (!Array.isArray(content)) {
27949
+ return;
27950
+ }
27951
+ for (const block of content) {
27952
+ if (!isRecord2(block)) {
27953
+ continue;
27954
+ }
27955
+ if (block["type"] === "tool_use" && block["name"] === "Agent" && typeof block["id"] === "string") {
27956
+ agentToolUseIds.push(block["id"]);
27957
+ }
27958
+ }
27959
+ }
27960
+
27961
+ // ../../extensions/drm-copilot/src/lib/subagent-tree/transcript-scanner.ts
27962
+ var META_SUFFIX = ".meta.json";
27963
+ var TRANSCRIPT_SUFFIX = ".jsonl";
27964
+ var META_FILENAME_PATTERN = /agent-([^/\\]+)\.meta\.json$/;
27965
+ function scanTranscripts(rootSessionPath, fileSystem) {
27966
+ if (!rootSessionPath.endsWith(TRANSCRIPT_SUFFIX)) {
27967
+ throw new Error(
27968
+ `scanTranscripts: rootSessionPath must end in "${TRANSCRIPT_SUFFIX}", got: ${rootSessionPath}`
27969
+ );
27970
+ }
27971
+ const root = readTranscript(rootSessionPath, fileSystem);
27972
+ const subagentsDir = `${rootSessionPath.slice(0, -TRANSCRIPT_SUFFIX.length)}/subagents`;
27973
+ const metaPaths = fileSystem.glob(subagentsDir, "agent-*.meta.json");
27974
+ const subagents = metaPaths.map((metaPath) => readSubagent(metaPath, fileSystem)).filter((subagent) => subagent !== void 0);
27975
+ return { root, subagents };
27976
+ }
27977
+ function readTranscript(path11, fileSystem) {
27978
+ const content = fileSystem.readTextFile(path11);
27979
+ return parseTranscriptLines(content.split(/\r?\n/));
27980
+ }
27981
+ function readSubagent(metaPath, fileSystem) {
27982
+ const filenameMatch = META_FILENAME_PATTERN.exec(metaPath);
27983
+ const agentId = filenameMatch?.[1];
27984
+ if (agentId === void 0) {
27985
+ return void 0;
27986
+ }
27987
+ const metaContent = fileSystem.readTextFile(metaPath);
27988
+ const meta2 = parseSubagentMeta(agentId, metaContent);
27989
+ if (!meta2) {
27990
+ return void 0;
27991
+ }
27992
+ const transcriptPath = metaPath.slice(0, -META_SUFFIX.length) + TRANSCRIPT_SUFFIX;
27993
+ const transcript = readTranscript(transcriptPath, fileSystem);
27994
+ return { meta: meta2, transcript };
27995
+ }
27996
+ function parseSubagentMeta(agentId, content) {
27997
+ let parsed;
27998
+ try {
27999
+ parsed = JSON.parse(content);
28000
+ } catch {
28001
+ return void 0;
28002
+ }
28003
+ if (typeof parsed !== "object" || parsed === null) {
28004
+ return void 0;
28005
+ }
28006
+ const record2 = parsed;
28007
+ const agentType = record2["agentType"];
28008
+ const description = record2["description"];
28009
+ const toolUseId = record2["toolUseId"];
28010
+ const spawnDepth = record2["spawnDepth"];
28011
+ if (typeof agentType !== "string" || typeof description !== "string" || typeof toolUseId !== "string" || typeof spawnDepth !== "number") {
28012
+ return void 0;
28013
+ }
28014
+ const worktreePath = record2["worktreePath"];
28015
+ const worktreeBranch = record2["worktreeBranch"];
28016
+ return {
28017
+ agentId,
28018
+ agentType,
28019
+ description,
28020
+ toolUseId,
28021
+ spawnDepth,
28022
+ ...typeof worktreePath === "string" ? { worktreePath } : {},
28023
+ ...typeof worktreeBranch === "string" ? { worktreeBranch } : {}
28024
+ };
28025
+ }
28026
+
28027
+ // ../../extensions/drm-copilot/src/lib/subagent-tree/tree-formatter.ts
28028
+ function formatTree(node) {
28029
+ return renderLines(node).join("\n");
28030
+ }
28031
+ function renderLines(node) {
28032
+ const indent = " ".repeat(node.depth);
28033
+ const sortedModels = [...node.models].sort();
28034
+ const line = `${indent}${node.agentType} \xB7 [${sortedModels.join(",")}] \xB7 ${node.depth} \xB7 ${node.description}`;
28035
+ const childLines = node.children.flatMap((child) => renderLines(child));
28036
+ return [line, ...childLines];
28037
+ }
28038
+
28039
+ // ../../extensions/drm-copilot/src/lib/subagent-tree/index.ts
28040
+ function buildSubagentTree(rootSessionPath, deps) {
28041
+ const scanned = scanTranscripts(rootSessionPath, deps.fileSystem);
28042
+ return assembleTree(scanned);
28043
+ }
28044
+
28045
+ // ../../extensions/drm-copilot/src/lib/subagent-tree/workspace-encoding.ts
28046
+ var WORKTREE_INFIX = "-wt-";
28047
+ function encodeWorkspacePath(workspacePath) {
28048
+ return workspacePath.replace(/[\\/:]/g, "-");
28049
+ }
28050
+ function matchEncodedDirectories(directoryNames, encodedWorkspaceName) {
28051
+ const target = encodedWorkspaceName.toLowerCase();
28052
+ const worktreePrefix = `${target}${WORKTREE_INFIX}`;
28053
+ return directoryNames.filter((directoryName) => {
28054
+ const lowerDirectoryName = directoryName.toLowerCase();
28055
+ return lowerDirectoryName === target || lowerDirectoryName.startsWith(worktreePrefix);
28056
+ });
28057
+ }
28058
+
28059
+ // ../../extensions/drm-copilot/src/lib/subagent-tree/session-transcript-resolver.ts
28060
+ var SESSION_ID_PATTERN = /^[0-9A-Za-z-]{8,64}$/;
28061
+ var SESSION_ID_RULE = "^[0-9A-Za-z-]{8,64}$ (8-64 characters of digits, ASCII letters, or hyphen)";
28062
+ function resolveSessionTranscriptPath(sessionId, workspaceRoot, claudeProjectsRoot, fileSystem) {
28063
+ if (!SESSION_ID_PATTERN.test(sessionId)) {
28064
+ throw new Error(
28065
+ `Invalid session id '${sessionId}': must match ${SESSION_ID_RULE}.`
28066
+ );
28067
+ }
28068
+ const encodedWorkspaceName = encodeWorkspacePath(workspaceRoot);
28069
+ const matchingDirectories = matchEncodedDirectories(
28070
+ fileSystem.listDirectory(claudeProjectsRoot),
28071
+ encodedWorkspaceName
28072
+ );
28073
+ for (const directoryName of matchingDirectories) {
28074
+ const transcriptPath = `${claudeProjectsRoot}/${directoryName}/${sessionId}.jsonl`;
28075
+ if (fileSystem.isFile(transcriptPath)) {
28076
+ return transcriptPath;
28077
+ }
28078
+ }
28079
+ const searched = matchingDirectories.length === 0 ? "(no directories matched the encoded workspace path)" : matchingDirectories.map((directoryName) => `${claudeProjectsRoot}/${directoryName}`).join(", ");
28080
+ throw new Error(
28081
+ `No transcript found for session id '${sessionId}' under ${claudeProjectsRoot}. Searched: ${searched}.`
28082
+ );
28083
+ }
28084
+
28085
+ // ../../extensions/drm-copilot/src/repo-automation-service-subagent-tree.ts
28086
+ function renderSubagentTreeServiceCall(input, env = process.env) {
28087
+ const claudeProjectsRoot = getClaudeProjectsRoot(env);
28088
+ const transcriptPath = resolveSessionTranscriptPath(
28089
+ input.sessionId,
28090
+ input.workspaceRoot,
28091
+ claudeProjectsRoot,
28092
+ input.fileSystem
28093
+ );
28094
+ const renderedTree = formatTree(
28095
+ buildSubagentTree(transcriptPath, { fileSystem: input.fileSystem })
28096
+ );
28097
+ return {
28098
+ tool: "render_subagent_tree",
28099
+ workspaceRoot: input.workspaceRoot,
28100
+ summary: `Rendered subagent tree for session ${input.sessionId} (${transcriptPath}).`,
28101
+ renderedTree
28102
+ };
28103
+ }
28104
+
27629
28105
  // ../../extensions/drm-copilot/src/repo-automation-service.ts
27630
28106
  var DefaultRepoAutomationService = class {
27631
28107
  extensionRoot;
@@ -27795,23 +28271,14 @@ var DefaultRepoAutomationService = class {
27795
28271
  buildValidateOrchestrationServiceCallInput(this.fileSystem, input)
27796
28272
  );
27797
28273
  }
27798
- async executeScript(options) {
27799
- const execution = await executeBundledScriptFromExtensionRoot(this.output, {
27800
- runtimeKind: options.runtimeKind,
27801
- bundledRelativePath: options.bundledRelativePath,
27802
- commandId: options.invocationId,
27803
- args: options.args,
27804
- extensionRoot: this.extensionRoot,
27805
- workspaceRoot: options.workspaceRoot
28274
+ async renderSubagentTree(input) {
28275
+ return renderSubagentTreeServiceCall({
28276
+ ...input,
28277
+ fileSystem: this.fileSystem
27806
28278
  });
27807
- const parsedArtifactPath = options.stdoutArtifactPattern === void 0 ? void 0 : parseFirstArtifactPath(execution, options.stdoutArtifactPattern);
27808
- const artifacts = options.artifactPaths ?? (parsedArtifactPath === void 0 ? void 0 : [parsedArtifactPath]);
27809
- return {
27810
- tool: options.tool,
27811
- workspaceRoot: options.workspaceRoot,
27812
- summary: options.summary,
27813
- ...artifacts === void 0 ? {} : { artifacts }
27814
- };
28279
+ }
28280
+ async executeScript(options) {
28281
+ return executeScriptServiceCall(this.output, this.extensionRoot, options);
27815
28282
  }
27816
28283
  };
27817
28284
  function createRepoAutomationService(options) {
@@ -27820,10 +28287,10 @@ function createRepoAutomationService(options) {
27820
28287
 
27821
28288
  // ../../extensions/drm-copilot/src/mcp-server.ts
27822
28289
  function resolveExtensionRoot() {
27823
- return path9.resolve(__dirname, "..");
28290
+ return path10.resolve(__dirname, "..");
27824
28291
  }
27825
28292
  function readPackageVersion(extensionRoot) {
27826
- const packageJsonPath = path9.join(extensionRoot, "package.json");
28293
+ const packageJsonPath = path10.join(extensionRoot, "package.json");
27827
28294
  try {
27828
28295
  const packageJson = JSON.parse(
27829
28296
  fs8.readFileSync(packageJsonPath, "utf-8")