hatch3r 1.5.0 → 1.5.1

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/dist/cli/index.js CHANGED
@@ -14,7 +14,7 @@ var HATCH3R_VERSION;
14
14
  var init_version = __esm({
15
15
  "src/version.ts"() {
16
16
  "use strict";
17
- HATCH3R_VERSION = "1.5.0";
17
+ HATCH3R_VERSION = "1.5.1";
18
18
  }
19
19
  });
20
20
 
@@ -4990,7 +4990,7 @@ async function buildContentIndex(contentRoot) {
4990
4990
  }
4991
4991
  return { items, byType, byId, byTypeAndId, collisions };
4992
4992
  }
4993
- function resolveSelection(preset, projectType, teamSize, index, customSelections, projectLanguages) {
4993
+ function resolveSelection(preset, projectType, teamSize, index, customSelections, projectLanguages, options) {
4994
4994
  let selected;
4995
4995
  const relevantLangTags = /* @__PURE__ */ new Set();
4996
4996
  if (projectLanguages) {
@@ -5019,26 +5019,28 @@ function resolveSelection(preset, projectType, teamSize, index, customSelections
5019
5019
  (item) => item.protected || item.tags.length === 0 || !item.tags.every((t) => excludeSet.has(t))
5020
5020
  );
5021
5021
  }
5022
- if (projectType === "greenfield") {
5023
- selected = selected.filter(
5024
- (item) => item.protected || !item.tags.includes("brownfield") || item.tags.some((t) => t !== "brownfield" && t !== "team" && t !== "solo")
5025
- );
5026
- } else {
5027
- selected = selected.filter(
5028
- (item) => item.protected || !item.tags.includes("greenfield") || item.tags.some((t) => t !== "greenfield" && t !== "team" && t !== "solo")
5029
- );
5030
- }
5031
- if (teamSize === "solo") {
5032
- selected = selected.filter((item) => {
5033
- if (item.protected) return true;
5034
- if (!item.tags.includes("team") && !item.tags.includes("board")) return true;
5035
- return item.tags.some(
5036
- (t) => t !== "team" && t !== "board" && t !== "solo" && t !== "greenfield" && t !== "brownfield"
5022
+ if (!options?.skipContextFilters) {
5023
+ if (projectType === "greenfield") {
5024
+ selected = selected.filter(
5025
+ (item) => item.protected || !item.tags.includes("brownfield") || item.tags.some((t) => t !== "brownfield" && t !== "team" && t !== "solo")
5037
5026
  );
5038
- });
5027
+ } else {
5028
+ selected = selected.filter(
5029
+ (item) => item.protected || !item.tags.includes("greenfield") || item.tags.some((t) => t !== "greenfield" && t !== "team" && t !== "solo")
5030
+ );
5031
+ }
5032
+ if (teamSize === "solo") {
5033
+ selected = selected.filter((item) => {
5034
+ if (item.protected) return true;
5035
+ if (!item.tags.includes("team") && !item.tags.includes("board")) return true;
5036
+ return item.tags.some(
5037
+ (t) => t !== "team" && t !== "board" && t !== "solo" && t !== "greenfield" && t !== "brownfield"
5038
+ );
5039
+ });
5040
+ }
5039
5041
  }
5040
5042
  }
5041
- if (projectLanguages && projectLanguages.length > 0) {
5043
+ if (!options?.skipContextFilters && projectLanguages && projectLanguages.length > 0) {
5042
5044
  selected = selected.filter((item) => {
5043
5045
  if (item.protected) return true;
5044
5046
  const itemLangTags = item.tags.filter(isLanguageTag);
@@ -5303,8 +5305,8 @@ function getAllContentIds(selection) {
5303
5305
  }
5304
5306
  return ids;
5305
5307
  }
5306
- function estimatePresetItemCount(preset, projectType, teamSize, index, projectLanguages) {
5307
- const selection = resolveSelection(preset, projectType, teamSize, index, void 0, projectLanguages);
5308
+ function estimatePresetItemCount(preset, projectType, teamSize, index, projectLanguages, options) {
5309
+ const selection = resolveSelection(preset, projectType, teamSize, index, void 0, projectLanguages, options);
5308
5310
  return Object.values(selection.items).reduce((sum, arr) => sum + arr.length, 0);
5309
5311
  }
5310
5312
  function countSelectionItems(selection) {
@@ -5467,7 +5469,7 @@ import { execFileSync as execFileSync4 } from "child_process";
5467
5469
  import { fileURLToPath as fileURLToPath3 } from "url";
5468
5470
  import { dirname as dirname11, join as join22 } from "path";
5469
5471
  import chalk7 from "chalk";
5470
- import inquirer3 from "inquirer";
5472
+ import inquirer4 from "inquirer";
5471
5473
  async function readFileOrNull(filePath) {
5472
5474
  try {
5473
5475
  return await readFile19(filePath, "utf-8");
@@ -5798,7 +5800,7 @@ var init_update = __esm({
5798
5800
  content.projectType = "brownfield";
5799
5801
  content.teamSize = "team";
5800
5802
  } else {
5801
- const { projectType } = await inquirer3.prompt([
5803
+ const { projectType } = await inquirer4.prompt([
5802
5804
  {
5803
5805
  type: "select",
5804
5806
  name: "projectType",
@@ -5810,7 +5812,7 @@ var init_update = __esm({
5810
5812
  default: "brownfield"
5811
5813
  }
5812
5814
  ]);
5813
- const { teamSize } = await inquirer3.prompt([
5815
+ const { teamSize } = await inquirer4.prompt([
5814
5816
  {
5815
5817
  type: "select",
5816
5818
  name: "teamSize",
@@ -5839,7 +5841,7 @@ var init_update = __esm({
5839
5841
  if (headless) {
5840
5842
  platform = "github";
5841
5843
  } else {
5842
- const answer = await inquirer3.prompt([
5844
+ const answer = await inquirer4.prompt([
5843
5845
  {
5844
5846
  type: "select",
5845
5847
  name: "platform",
@@ -5861,7 +5863,7 @@ var init_update = __esm({
5861
5863
  updated.project = updated.project || updated.repo;
5862
5864
  notices.push("Migrated to GitHub platform (auto-detected from existing config)");
5863
5865
  } else {
5864
- const answers = await inquirer3.prompt([
5866
+ const answers = await inquirer4.prompt([
5865
5867
  { type: "input", name: "namespace", message: platform === "azure-devops" ? "Azure DevOps organization:" : "GitLab namespace (group or username):", default: updated.owner || void 0 },
5866
5868
  { type: "input", name: "project", message: platform === "azure-devops" ? "Azure DevOps project:" : "Project name:", default: updated.repo || void 0 },
5867
5869
  { type: "input", name: "repo", message: "Repository name:", default: updated.repo || void 0 }
@@ -5925,7 +5927,7 @@ var init_update = __esm({
5925
5927
  if (headless) {
5926
5928
  enabled = true;
5927
5929
  } else {
5928
- const answer = await inquirer3.prompt([{
5930
+ const answer = await inquirer4.prompt([{
5929
5931
  type: "confirm",
5930
5932
  name: "enabled",
5931
5933
  message: "hatch3r now supports worktree file isolation for parallel agent sessions. Enable it?",
@@ -6101,7 +6103,7 @@ init_ui();
6101
6103
  init_types();
6102
6104
  import { rm as rm4 } from "fs/promises";
6103
6105
  import chalk6 from "chalk";
6104
- import inquirer2 from "inquirer";
6106
+ import inquirer3 from "inquirer";
6105
6107
 
6106
6108
  // src/clean/index.ts
6107
6109
  init_archive();
@@ -6367,7 +6369,7 @@ import { access as access8, mkdir as mkdir7, readFile as readFile18 } from "fs/p
6367
6369
  import { fileURLToPath as fileURLToPath2 } from "url";
6368
6370
  import { basename as basename2, dirname as dirname10, join as join21 } from "path";
6369
6371
  import chalk5 from "chalk";
6370
- import inquirer from "inquirer";
6372
+ import inquirer2 from "inquirer";
6371
6373
 
6372
6374
  // src/detect/repoAnalyzer.ts
6373
6375
  init_packageManager();
@@ -6686,6 +6688,47 @@ init_agentsContent();
6686
6688
  init_ui();
6687
6689
  init_paths();
6688
6690
 
6691
+ // src/cli/shared/customContentChoices.ts
6692
+ import inquirer from "inquirer";
6693
+ var CONTENT_TAG_LABELS = {
6694
+ core: "Core",
6695
+ planning: "Planning",
6696
+ implementation: "Implementation",
6697
+ review: "Review",
6698
+ devops: "DevOps",
6699
+ maintenance: "Maintenance",
6700
+ greenfield: "Greenfield",
6701
+ brownfield: "Brownfield",
6702
+ board: "Board",
6703
+ security: "Security",
6704
+ a11y: "Accessibility",
6705
+ performance: "Performance",
6706
+ customize: "Customization",
6707
+ other: "Other"
6708
+ };
6709
+ function buildTagGroupedCustomContentChoices(items, isChecked) {
6710
+ const tagGroups = /* @__PURE__ */ new Map();
6711
+ for (const item of items) {
6712
+ const primaryTag = item.tags[0] ?? "other";
6713
+ if (!tagGroups.has(primaryTag)) tagGroups.set(primaryTag, []);
6714
+ tagGroups.get(primaryTag).push(item);
6715
+ }
6716
+ const groupedChoices = [];
6717
+ for (const [tag, groupItems] of tagGroups) {
6718
+ groupedChoices.push(
6719
+ new inquirer.Separator(`\u2500\u2500 ${CONTENT_TAG_LABELS[tag] ?? tag} (${groupItems.length}) \u2500\u2500`)
6720
+ );
6721
+ for (const item of groupItems) {
6722
+ groupedChoices.push({
6723
+ name: `${item.type}: ${item.id.replace(/^(cmd-)?hatch3r-/, "")} \u2014 ${item.description.slice(0, 60)}`,
6724
+ value: item.id,
6725
+ checked: isChecked(item)
6726
+ });
6727
+ }
6728
+ }
6729
+ return groupedChoices;
6730
+ }
6731
+
6689
6732
  // src/cli/shared/constants.ts
6690
6733
  init_types();
6691
6734
  import { readFileSync as readFileSync2 } from "fs";
@@ -6800,14 +6843,14 @@ var PRESETS = [
6800
6843
  },
6801
6844
  {
6802
6845
  id: "standard",
6803
- name: "Standard (recommended)",
6846
+ name: "Standard",
6804
6847
  description: "Full development lifecycle without niche audits",
6805
6848
  includeTags: ["core", "planning", "implementation", "review", "devops", "maintenance"],
6806
6849
  excludeTags: ["board", "a11y", "performance", "customize"]
6807
6850
  },
6808
6851
  {
6809
6852
  id: "full",
6810
- name: "Full",
6853
+ name: "Full (recommended)",
6811
6854
  description: "Everything including board management and all audits",
6812
6855
  includeTags: [],
6813
6856
  // empty = include all
@@ -7274,7 +7317,7 @@ async function syncSingleRepo(workspaceRoot, wsManifest, wsChecksum, repoEntry,
7274
7317
  // src/cli/commands/init.ts
7275
7318
  var __dirname2 = dirname10(fileURLToPath2(import.meta.url));
7276
7319
  var CONTENT_ROOT2 = findPackageRoot(__dirname2);
7277
- var DEFAULT_TOOLS = ["cursor"];
7320
+ var DEFAULT_TOOLS = ["claude"];
7278
7321
  var DEFAULT_FEATURE_KEYS = Object.keys(DEFAULT_FEATURES);
7279
7322
  var DEFAULT_MCP = ["playwright", "github", "context7"];
7280
7323
  function selectionHasBoardContent(selection) {
@@ -7489,7 +7532,7 @@ async function checkExisting(rootDir, skipPrompt, newSelection) {
7489
7532
  }
7490
7533
  }
7491
7534
  }
7492
- const { proceed } = await inquirer.prompt([
7535
+ const { proceed } = await inquirer2.prompt([
7493
7536
  {
7494
7537
  type: "confirm",
7495
7538
  name: "proceed",
@@ -7526,7 +7569,7 @@ async function initCommand(opts = {}) {
7526
7569
  info(chalk5.dim(`No git repo found. ${detectedRepos.length} git repo(s) detected in subdirectories \u2014 initializing as workspace.`));
7527
7570
  } else {
7528
7571
  info(`No git repo found, but ${detectedRepos.length} git repo(s) detected in subdirectories.`);
7529
- const { useWorkspace } = await inquirer.prompt([
7572
+ const { useWorkspace } = await inquirer2.prompt([
7530
7573
  {
7531
7574
  type: "confirm",
7532
7575
  name: "useWorkspace",
@@ -7587,7 +7630,7 @@ async function initCommand(opts = {}) {
7587
7630
  const mcpServers2 = features2.mcp ? Array.from(/* @__PURE__ */ new Set([platformMcp, ...DEFAULT_MCP.filter((s) => s !== "github")])) : [];
7588
7631
  const defaultBranch2 = parseGitDefaultBranch();
7589
7632
  const isGreenfield = repoInfo.languages.length === 1 && repoInfo.languages[0] === "unknown" && repoInfo.existingTools.length === 0 && !repoInfo.hasExistingAgents;
7590
- const presetId = validateFlag(opts.preset, ["minimal", "standard", "full"], "standard", "preset");
7633
+ const presetId = validateFlag(opts.preset, ["minimal", "standard", "full"], "full", "preset");
7591
7634
  const projectType2 = validateFlag(opts.projectType, ["greenfield", "brownfield"], isGreenfield ? "greenfield" : "brownfield", "project-type");
7592
7635
  const teamSize2 = validateFlag(opts.teamSize, ["solo", "team"], "solo", "team-size");
7593
7636
  const preset = getPreset(presetId);
@@ -7605,7 +7648,7 @@ async function initCommand(opts = {}) {
7605
7648
  console.log();
7606
7649
  const remoteUrl = getGitRemoteUrl();
7607
7650
  const detectedPlatform = detectPlatformFromRemote(remoteUrl);
7608
- const platformAnswer = await inquirer.prompt([
7651
+ const platformAnswer = await inquirer2.prompt([
7609
7652
  {
7610
7653
  type: "select",
7611
7654
  name: "platform",
@@ -7624,7 +7667,7 @@ async function initCommand(opts = {}) {
7624
7667
  let namespace;
7625
7668
  let project;
7626
7669
  if (platform === "azure-devops") {
7627
- const adoAnswers = await inquirer.prompt([
7670
+ const adoAnswers = await inquirer2.prompt([
7628
7671
  { type: "input", name: "org", message: "Azure DevOps organization:", default: remote.owner || void 0 },
7629
7672
  { type: "input", name: "project", message: "Azure DevOps project:" },
7630
7673
  { type: "input", name: "repo", message: "Repository name:", default: remote.repo || void 0 }
@@ -7634,7 +7677,7 @@ async function initCommand(opts = {}) {
7634
7677
  namespace = owner;
7635
7678
  project = sanitizeInput(adoAnswers.project);
7636
7679
  } else if (platform === "gitlab") {
7637
- const glAnswers = await inquirer.prompt([
7680
+ const glAnswers = await inquirer2.prompt([
7638
7681
  { type: "input", name: "namespace", message: "GitLab namespace (group or username):", default: remote.owner || void 0 },
7639
7682
  { type: "input", name: "project", message: "Project name:", default: remote.repo || void 0 }
7640
7683
  ]);
@@ -7643,7 +7686,7 @@ async function initCommand(opts = {}) {
7643
7686
  namespace = owner;
7644
7687
  project = repo;
7645
7688
  } else {
7646
- const repoAnswers = await inquirer.prompt([
7689
+ const repoAnswers = await inquirer2.prompt([
7647
7690
  { type: "input", name: "owner", message: "GitHub owner (org or username):", default: remote.owner || void 0 },
7648
7691
  { type: "input", name: "repo", message: "Repository name:", default: remote.repo || void 0 }
7649
7692
  ]);
@@ -7653,7 +7696,7 @@ async function initCommand(opts = {}) {
7653
7696
  project = repo;
7654
7697
  }
7655
7698
  const defaultBranchDefault = parseGitDefaultBranch();
7656
- const defaultBranchAnswers = await inquirer.prompt([
7699
+ const defaultBranchAnswers = await inquirer2.prompt([
7657
7700
  {
7658
7701
  type: "input",
7659
7702
  name: "defaultBranch",
@@ -7666,7 +7709,7 @@ async function initCommand(opts = {}) {
7666
7709
  const isAutoGreenfield = repoInfo.languages.length === 1 && repoInfo.languages[0] === "unknown" && repoInfo.existingTools.length === 0 && !repoInfo.hasExistingAgents;
7667
7710
  const greenfieldExcl = countProjectTypeExclusions("greenfield", filterIndex.items);
7668
7711
  const brownfieldExcl = countProjectTypeExclusions("brownfield", filterIndex.items);
7669
- const projectTypeAnswer = await inquirer.prompt([
7712
+ const projectTypeAnswer = await inquirer2.prompt([
7670
7713
  {
7671
7714
  type: "select",
7672
7715
  name: "projectType",
@@ -7680,7 +7723,7 @@ async function initCommand(opts = {}) {
7680
7723
  ]);
7681
7724
  const projectType = projectTypeAnswer.projectType;
7682
7725
  const soloExcl = countTeamSizeExclusions("solo", filterIndex.items);
7683
- const teamSizeAnswer = await inquirer.prompt([
7726
+ const teamSizeAnswer = await inquirer2.prompt([
7684
7727
  {
7685
7728
  type: "select",
7686
7729
  name: "teamSize",
@@ -7694,7 +7737,7 @@ async function initCommand(opts = {}) {
7694
7737
  ]);
7695
7738
  const teamSize = teamSizeAnswer.teamSize;
7696
7739
  const totalItems = filterIndex.items.length;
7697
- const presetAnswer = await inquirer.prompt([
7740
+ const presetAnswer = await inquirer2.prompt([
7698
7741
  {
7699
7742
  type: "select",
7700
7743
  name: "preset",
@@ -7709,7 +7752,7 @@ async function initCommand(opts = {}) {
7709
7752
  value: p.id
7710
7753
  };
7711
7754
  }),
7712
- default: "standard"
7755
+ default: "full"
7713
7756
  }
7714
7757
  ]);
7715
7758
  const selectedPreset = getPreset(presetAnswer.preset);
@@ -7717,40 +7760,11 @@ async function initCommand(opts = {}) {
7717
7760
  let customSelections;
7718
7761
  if (selectedPreset.id === "custom") {
7719
7762
  const contentIndex = filterIndex;
7720
- const tagGroups = /* @__PURE__ */ new Map();
7721
- for (const item of contentIndex.items) {
7722
- const primaryTag = item.tags[0] ?? "other";
7723
- if (!tagGroups.has(primaryTag)) tagGroups.set(primaryTag, []);
7724
- tagGroups.get(primaryTag).push(item);
7725
- }
7726
- const TAG_LABELS = {
7727
- core: "Core",
7728
- planning: "Planning",
7729
- implementation: "Implementation",
7730
- review: "Review",
7731
- devops: "DevOps",
7732
- maintenance: "Maintenance",
7733
- greenfield: "Greenfield",
7734
- brownfield: "Brownfield",
7735
- board: "Board",
7736
- security: "Security",
7737
- a11y: "Accessibility",
7738
- performance: "Performance",
7739
- customize: "Customization",
7740
- other: "Other"
7741
- };
7742
- const groupedChoices = [];
7743
- for (const [tag, items] of tagGroups) {
7744
- groupedChoices.push(new inquirer.Separator(`\u2500\u2500 ${TAG_LABELS[tag] ?? tag} (${items.length}) \u2500\u2500`));
7745
- for (const item of items) {
7746
- groupedChoices.push({
7747
- name: `${item.type}: ${item.id.replace(/^(cmd-)?hatch3r-/, "")} \u2014 ${item.description.slice(0, 60)}`,
7748
- value: item.id,
7749
- checked: item.protected || item.tags.includes("core")
7750
- });
7751
- }
7752
- }
7753
- const customAnswer = await inquirer.prompt([
7763
+ const groupedChoices = buildTagGroupedCustomContentChoices(
7764
+ contentIndex.items,
7765
+ (item) => item.protected || item.tags.includes("core")
7766
+ );
7767
+ const customAnswer = await inquirer2.prompt([
7754
7768
  {
7755
7769
  type: "checkbox",
7756
7770
  name: "items",
@@ -7762,7 +7776,7 @@ async function initCommand(opts = {}) {
7762
7776
  customSelections = customAnswer.items;
7763
7777
  }
7764
7778
  const toolDefaults = repoInfo.existingTools.length > 0 ? repoInfo.existingTools : DEFAULT_TOOLS;
7765
- const toolAnswers = await inquirer.prompt([
7779
+ const toolAnswers = await inquirer2.prompt([
7766
7780
  {
7767
7781
  type: "checkbox",
7768
7782
  name: "tools",
@@ -7780,7 +7794,7 @@ async function initCommand(opts = {}) {
7780
7794
  info(chalk5.dim(` ${note}`));
7781
7795
  }
7782
7796
  }
7783
- const featureAnswers = await inquirer.prompt([
7797
+ const featureAnswers = await inquirer2.prompt([
7784
7798
  {
7785
7799
  type: "checkbox",
7786
7800
  name: "features",
@@ -7801,7 +7815,7 @@ async function initCommand(opts = {}) {
7801
7815
  const defaultMcpForPlatform = Array.from(
7802
7816
  /* @__PURE__ */ new Set([platformMcp, ...DEFAULT_MCP.filter((s) => s !== "github")])
7803
7817
  );
7804
- const mcpAnswers = await inquirer.prompt([
7818
+ const mcpAnswers = await inquirer2.prompt([
7805
7819
  {
7806
7820
  type: "checkbox",
7807
7821
  name: "mcp",
@@ -7838,7 +7852,7 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
7838
7852
  const platformMcp = PLATFORM_MCP_SERVER[platform2];
7839
7853
  const mcpServers2 = features2.mcp ? Array.from(/* @__PURE__ */ new Set([platformMcp, ...DEFAULT_MCP.filter((s) => s !== "github")])) : [];
7840
7854
  const index = await buildContentIndex(CONTENT_ROOT2);
7841
- const contentSelection2 = resolveSelection(getPreset("standard"), "brownfield", "solo", index);
7855
+ const contentSelection2 = resolveSelection(getPreset("full"), "brownfield", "solo", index);
7842
7856
  const wsManifest2 = createWorkspaceManifest(
7843
7857
  basename2(rootDir) || "workspace",
7844
7858
  { platform: platform2, tools: tools2, features: features2, mcp: { servers: mcpServers2 }, content: contentSelection2 },
@@ -7867,7 +7881,7 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
7867
7881
  }
7868
7882
  console.log();
7869
7883
  if (!headless) {
7870
- const { acceptIdentity } = await inquirer.prompt([
7884
+ const { acceptIdentity } = await inquirer2.prompt([
7871
7885
  {
7872
7886
  type: "confirm",
7873
7887
  name: "acceptIdentity",
@@ -7879,7 +7893,7 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
7879
7893
  for (const r of enriched) {
7880
7894
  console.log(chalk5.bold(`
7881
7895
  ${r.name ?? r.path}:`));
7882
- const identity = await inquirer.prompt([
7896
+ const identity = await inquirer2.prompt([
7883
7897
  { type: "input", name: "owner", message: " Owner:", default: r.owner || void 0 },
7884
7898
  { type: "input", name: "repo", message: " Repo:", default: r.repo || void 0 },
7885
7899
  { type: "input", name: "defaultBranch", message: " Default branch:", default: r.defaultBranch || "main" }
@@ -7901,7 +7915,7 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
7901
7915
  const platformMcp = PLATFORM_MCP_SERVER[platform];
7902
7916
  mcpServers = features.mcp ? Array.from(/* @__PURE__ */ new Set([platformMcp, ...DEFAULT_MCP.filter((s) => s !== "github")])) : [];
7903
7917
  const isGreenfield = repoInfo.languages.length === 1 && repoInfo.languages[0] === "unknown" && repoInfo.existingTools.length === 0 && !repoInfo.hasExistingAgents;
7904
- const presetId = validateFlag(opts.preset, ["minimal", "standard", "full"], "standard", "preset");
7918
+ const presetId = validateFlag(opts.preset, ["minimal", "standard", "full"], "full", "preset");
7905
7919
  const projectType = validateFlag(opts.projectType, ["greenfield", "brownfield"], isGreenfield ? "greenfield" : "brownfield", "project-type");
7906
7920
  const teamSize = validateFlag(opts.teamSize, ["solo", "team"], "solo", "team-size");
7907
7921
  const preset = getPreset(presetId);
@@ -7913,7 +7927,7 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
7913
7927
  const isAutoGreenfield = repoInfo.languages.length === 1 && repoInfo.languages[0] === "unknown" && repoInfo.existingTools.length === 0 && !repoInfo.hasExistingAgents;
7914
7928
  const wsGreenfieldExcl = countProjectTypeExclusions("greenfield", wsFilterIndex.items);
7915
7929
  const wsBrownfieldExcl = countProjectTypeExclusions("brownfield", wsFilterIndex.items);
7916
- const projectTypeAnswer = await inquirer.prompt([
7930
+ const projectTypeAnswer = await inquirer2.prompt([
7917
7931
  {
7918
7932
  type: "select",
7919
7933
  name: "projectType",
@@ -7927,7 +7941,7 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
7927
7941
  ]);
7928
7942
  const projectType = projectTypeAnswer.projectType;
7929
7943
  const wsSoloExcl = countTeamSizeExclusions("solo", wsFilterIndex.items);
7930
- const teamSizeAnswer = await inquirer.prompt([
7944
+ const teamSizeAnswer = await inquirer2.prompt([
7931
7945
  {
7932
7946
  type: "select",
7933
7947
  name: "teamSize",
@@ -7941,7 +7955,7 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
7941
7955
  ]);
7942
7956
  const teamSize = teamSizeAnswer.teamSize;
7943
7957
  const wsTotalItems = wsFilterIndex.items.length;
7944
- const presetAnswer = await inquirer.prompt([
7958
+ const presetAnswer = await inquirer2.prompt([
7945
7959
  {
7946
7960
  type: "select",
7947
7961
  name: "preset",
@@ -7956,47 +7970,18 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
7956
7970
  value: p.id
7957
7971
  };
7958
7972
  }),
7959
- default: "standard"
7973
+ default: "full"
7960
7974
  }
7961
7975
  ]);
7962
7976
  const selectedPreset = getPreset(presetAnswer.preset);
7963
7977
  let customSelections;
7964
7978
  if (selectedPreset.id === "custom") {
7965
7979
  const contentIndex = wsFilterIndex;
7966
- const wsTagGroups = /* @__PURE__ */ new Map();
7967
- for (const item of contentIndex.items) {
7968
- const primaryTag = item.tags[0] ?? "other";
7969
- if (!wsTagGroups.has(primaryTag)) wsTagGroups.set(primaryTag, []);
7970
- wsTagGroups.get(primaryTag).push(item);
7971
- }
7972
- const WS_TAG_LABELS = {
7973
- core: "Core",
7974
- planning: "Planning",
7975
- implementation: "Implementation",
7976
- review: "Review",
7977
- devops: "DevOps",
7978
- maintenance: "Maintenance",
7979
- greenfield: "Greenfield",
7980
- brownfield: "Brownfield",
7981
- board: "Board",
7982
- security: "Security",
7983
- a11y: "Accessibility",
7984
- performance: "Performance",
7985
- customize: "Customization",
7986
- other: "Other"
7987
- };
7988
- const wsGroupedChoices = [];
7989
- for (const [tag, items] of wsTagGroups) {
7990
- wsGroupedChoices.push(new inquirer.Separator(`\u2500\u2500 ${WS_TAG_LABELS[tag] ?? tag} (${items.length}) \u2500\u2500`));
7991
- for (const item of items) {
7992
- wsGroupedChoices.push({
7993
- name: `${item.type}: ${item.id.replace(/^(cmd-)?hatch3r-/, "")} \u2014 ${item.description.slice(0, 60)}`,
7994
- value: item.id,
7995
- checked: item.protected || item.tags.includes("core")
7996
- });
7997
- }
7998
- }
7999
- const customAnswer = await inquirer.prompt([
7980
+ const wsGroupedChoices = buildTagGroupedCustomContentChoices(
7981
+ contentIndex.items,
7982
+ (item) => item.protected || item.tags.includes("core")
7983
+ );
7984
+ const customAnswer = await inquirer2.prompt([
8000
7985
  {
8001
7986
  type: "checkbox",
8002
7987
  name: "items",
@@ -8008,7 +7993,7 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
8008
7993
  customSelections = customAnswer.items;
8009
7994
  }
8010
7995
  const toolDefaults = repoInfo.existingTools.length > 0 ? repoInfo.existingTools : DEFAULT_TOOLS;
8011
- const toolAnswers = await inquirer.prompt([
7996
+ const toolAnswers = await inquirer2.prompt([
8012
7997
  {
8013
7998
  type: "checkbox",
8014
7999
  name: "tools",
@@ -8026,7 +8011,7 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
8026
8011
  info(chalk5.dim(` ${note}`));
8027
8012
  }
8028
8013
  }
8029
- const featureAnswers = await inquirer.prompt([
8014
+ const featureAnswers = await inquirer2.prompt([
8030
8015
  {
8031
8016
  type: "checkbox",
8032
8017
  name: "features",
@@ -8047,7 +8032,7 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
8047
8032
  const defaultMcpForPlatform = Array.from(
8048
8033
  /* @__PURE__ */ new Set([platformMcp, ...DEFAULT_MCP.filter((s) => s !== "github")])
8049
8034
  );
8050
- const mcpAnswers = await inquirer.prompt([
8035
+ const mcpAnswers = await inquirer2.prompt([
8051
8036
  {
8052
8037
  type: "checkbox",
8053
8038
  name: "mcp",
@@ -8097,7 +8082,7 @@ async function runWorkspaceInit(rootDir, detectedRepos, repoInfo, opts) {
8097
8082
  }));
8098
8083
  } else {
8099
8084
  const wslTheme = isWSL() ? { icon: { checked: chalk5.green("[x]"), unchecked: "[ ]", cursor: ">" } } : void 0;
8100
- const { syncRepos } = await inquirer.prompt([
8085
+ const { syncRepos } = await inquirer2.prompt([
8101
8086
  {
8102
8087
  type: "checkbox",
8103
8088
  name: "syncRepos",
@@ -8265,7 +8250,7 @@ async function cleanCommand(opts = {}) {
8265
8250
  return;
8266
8251
  }
8267
8252
  if (!opts.yes) {
8268
- const { proceed } = await inquirer2.prompt([
8253
+ const { proceed } = await inquirer3.prompt([
8269
8254
  {
8270
8255
  type: "confirm",
8271
8256
  name: "proceed",
@@ -8296,7 +8281,7 @@ async function cleanCommand(opts = {}) {
8296
8281
  }
8297
8282
  if (!opts.yes && config) {
8298
8283
  console.log("");
8299
- const { reinit } = await inquirer2.prompt([
8284
+ const { reinit } = await inquirer3.prompt([
8300
8285
  {
8301
8286
  type: "confirm",
8302
8287
  name: "reinit",
@@ -8386,7 +8371,7 @@ import { fileURLToPath as fileURLToPath4 } from "url";
8386
8371
  import { readFile as readFile20 } from "fs/promises";
8387
8372
  import { dirname as dirname12, join as join23 } from "path";
8388
8373
  import chalk8 from "chalk";
8389
- import inquirer4 from "inquirer";
8374
+ import inquirer5 from "inquirer";
8390
8375
  init_content();
8391
8376
  init_agentsContent();
8392
8377
  init_safeWrite();
@@ -8452,7 +8437,7 @@ async function configCommand() {
8452
8437
  `This repo is managed by workspace at ${wsContext.workspaceRoot}. Changes here may be overwritten on next workspace sync.`
8453
8438
  );
8454
8439
  console.log();
8455
- const { action } = await inquirer4.prompt([
8440
+ const { action } = await inquirer5.prompt([
8456
8441
  {
8457
8442
  type: "select",
8458
8443
  name: "action",
@@ -8484,7 +8469,7 @@ async function configCommand() {
8484
8469
  }
8485
8470
  printCurrentConfig(manifest);
8486
8471
  const wslTheme = isWSL() ? { icon: { checked: chalk8.green("[x]"), unchecked: "[ ]", cursor: ">" } } : void 0;
8487
- const platformAnswer = await inquirer4.prompt([
8472
+ const platformAnswer = await inquirer5.prompt([
8488
8473
  {
8489
8474
  type: "select",
8490
8475
  name: "platform",
@@ -8503,7 +8488,7 @@ async function configCommand() {
8503
8488
  let namespace;
8504
8489
  let project;
8505
8490
  if (platform === "azure-devops") {
8506
- const adoAnswers = await inquirer4.prompt([
8491
+ const adoAnswers = await inquirer5.prompt([
8507
8492
  { type: "input", name: "org", message: "Azure DevOps organization:", default: manifest.owner || void 0 },
8508
8493
  { type: "input", name: "project", message: "Azure DevOps project:", default: manifest.project || void 0 },
8509
8494
  { type: "input", name: "repo", message: "Repository name:", default: manifest.repo || void 0 }
@@ -8513,7 +8498,7 @@ async function configCommand() {
8513
8498
  namespace = owner;
8514
8499
  project = sanitizeInput(adoAnswers.project);
8515
8500
  } else if (platform === "gitlab") {
8516
- const glAnswers = await inquirer4.prompt([
8501
+ const glAnswers = await inquirer5.prompt([
8517
8502
  { type: "input", name: "namespace", message: "GitLab namespace (group or username):", default: manifest.namespace || manifest.owner || void 0 },
8518
8503
  { type: "input", name: "project", message: "Project name:", default: manifest.project || manifest.repo || void 0 }
8519
8504
  ]);
@@ -8522,7 +8507,7 @@ async function configCommand() {
8522
8507
  namespace = owner;
8523
8508
  project = repo;
8524
8509
  } else {
8525
- const repoAnswers = await inquirer4.prompt([
8510
+ const repoAnswers = await inquirer5.prompt([
8526
8511
  { type: "input", name: "owner", message: "GitHub owner (org or username):", default: manifest.owner || void 0 },
8527
8512
  { type: "input", name: "repo", message: "Repository name:", default: manifest.repo || void 0 }
8528
8513
  ]);
@@ -8532,7 +8517,7 @@ async function configCommand() {
8532
8517
  project = repo;
8533
8518
  }
8534
8519
  const currentBranch = manifest.board?.defaultBranch ?? "main";
8535
- const branchAnswer = await inquirer4.prompt([
8520
+ const branchAnswer = await inquirer5.prompt([
8536
8521
  {
8537
8522
  type: "input",
8538
8523
  name: "defaultBranch",
@@ -8541,7 +8526,7 @@ async function configCommand() {
8541
8526
  }
8542
8527
  ]);
8543
8528
  const defaultBranch = branchAnswer.defaultBranch.trim() || currentBranch;
8544
- const toolAnswers = await inquirer4.prompt([
8529
+ const toolAnswers = await inquirer5.prompt([
8545
8530
  {
8546
8531
  type: "checkbox",
8547
8532
  name: "tools",
@@ -8557,7 +8542,7 @@ async function configCommand() {
8557
8542
  throw new HatchError("At least one tool must be selected.", 1, "VALIDATION_ERROR");
8558
8543
  }
8559
8544
  const currentFeatureKeys = Object.keys(DEFAULT_FEATURES).filter((k) => manifest.features[k]);
8560
- const featureAnswers = await inquirer4.prompt([
8545
+ const featureAnswers = await inquirer5.prompt([
8561
8546
  {
8562
8547
  type: "checkbox",
8563
8548
  name: "features",
@@ -8575,7 +8560,7 @@ async function configCommand() {
8575
8560
  let mcpServers = [];
8576
8561
  if (features.mcp) {
8577
8562
  const platformMcp = PLATFORM_MCP_SERVER[platform];
8578
- const mcpAnswers = await inquirer4.prompt([
8563
+ const mcpAnswers = await inquirer5.prompt([
8579
8564
  {
8580
8565
  type: "checkbox",
8581
8566
  name: "mcp",
@@ -8592,7 +8577,7 @@ async function configCommand() {
8592
8577
  }
8593
8578
  const hasWorktreeTool = tools.some((t) => WORKTREE_CAPABLE_TOOLS.has(t));
8594
8579
  if (hasWorktreeTool) {
8595
- const wtAnswer = await inquirer4.prompt([{
8580
+ const wtAnswer = await inquirer5.prompt([{
8596
8581
  type: "confirm",
8597
8582
  name: "enabled",
8598
8583
  message: "Enable worktree file isolation (for parallel agent sessions)?",
@@ -8604,147 +8589,126 @@ async function configCommand() {
8604
8589
  };
8605
8590
  }
8606
8591
  const contentChanges = { added: [], removed: [] };
8592
+ let contentMetadataChanged = false;
8607
8593
  if (manifest.content) {
8608
- const manageContent = await inquirer4.prompt([
8594
+ info(
8595
+ chalk8.dim("Config adds/removes content items. To customize an item's behavior without ") + chalk8.dim("removing it, use .hatch3r/<type>/<id>.customize.yaml instead.")
8596
+ );
8597
+ console.log();
8598
+ const contentRoot = findPackageRoot(__dirname4);
8599
+ const agentsDir = join23(rootDir, AGENTS_DIR);
8600
+ const index = await buildContentIndex(contentRoot);
8601
+ const previousContent = manifest.content;
8602
+ const { projectType, teamSize } = manifest.content;
8603
+ const totalItems = index.items.length;
8604
+ const presetAnswer = await inquirer5.prompt([
8609
8605
  {
8610
- type: "confirm",
8611
- name: "manage",
8612
- message: "Manage content items?",
8613
- default: false
8606
+ type: "select",
8607
+ name: "preset",
8608
+ message: "Select content profile:",
8609
+ choices: PRESETS.map((p) => {
8610
+ const excluded = countPresetExclusions(p, index);
8611
+ const estimated = p.id !== "custom" ? estimatePresetItemCount(p, projectType, teamSize, index, void 0, { skipContextFilters: true }) : 0;
8612
+ const countHint = estimated > 0 ? ` (~${estimated} items)` : "";
8613
+ const suffix = excluded > 0 ? ` (excludes ${excluded} of ${totalItems})` : "";
8614
+ return {
8615
+ name: `${p.name} \u2014 ${p.description}${countHint}${suffix}`,
8616
+ value: p.id
8617
+ };
8618
+ }),
8619
+ default: manifest.content.preset
8614
8620
  }
8615
8621
  ]);
8616
- if (manageContent.manage) {
8617
- info(
8618
- chalk8.dim("Config adds/removes content items. To customize an item's behavior without ") + chalk8.dim("removing it, use .hatch3r/<type>/<id>.customize.yaml instead.")
8619
- );
8620
- console.log();
8621
- const contentRoot = findPackageRoot(__dirname4);
8622
- const agentsDir = join23(rootDir, AGENTS_DIR);
8623
- const index = await buildContentIndex(contentRoot);
8624
- const currentIds = /* @__PURE__ */ new Set();
8625
- for (const ids of Object.values(manifest.content.items)) {
8626
- for (const id of ids) currentIds.add(id);
8627
- }
8628
- const contentAnswer = await inquirer4.prompt([
8622
+ const selectedPreset = getPreset(presetAnswer.preset);
8623
+ let customSelections;
8624
+ if (selectedPreset.id === "custom") {
8625
+ const currentIds = getAllContentIds(manifest.content);
8626
+ const groupedChoices = buildTagGroupedCustomContentChoices(index.items, (item) => currentIds.has(item.id));
8627
+ const customAnswer = await inquirer5.prompt([
8629
8628
  {
8630
8629
  type: "checkbox",
8631
8630
  name: "items",
8632
- message: "Select content items (space to toggle):",
8633
- choices: index.items.map((item) => ({
8634
- name: `${item.type}: ${item.id.replace(/^(cmd-)?hatch3r-/, "")} \u2014 ${item.description.slice(0, 60)}`,
8635
- value: item.id,
8636
- checked: currentIds.has(item.id)
8637
- })),
8631
+ message: "Select content items:",
8632
+ choices: groupedChoices,
8638
8633
  ...wslTheme && { theme: wslTheme }
8639
8634
  }
8640
8635
  ]);
8641
- const newIds = new Set(contentAnswer.items);
8642
- const pendingRemovals = [];
8643
- for (const id of currentIds) {
8644
- if (!newIds.has(id)) pendingRemovals.push(id);
8645
- }
8646
- if (pendingRemovals.length > 0) {
8647
- const dependencyWarnings = [];
8648
- for (const removedId of pendingRemovals) {
8649
- const dependents = [];
8650
- for (const keepId of contentAnswer.items) {
8651
- const keepItem = index.byId.get(keepId);
8652
- if (!keepItem) continue;
8653
- try {
8654
- const filePath = keepItem.type === "skill" ? join23(agentsDir, keepItem.relativePath, "SKILL.md") : join23(agentsDir, keepItem.relativePath);
8655
- const content = await readFile20(filePath, "utf-8");
8656
- const refs = extractContentReferences(content);
8657
- if (refs.includes(removedId)) {
8658
- dependents.push(keepId);
8659
- }
8660
- } catch {
8636
+ customSelections = customAnswer.items;
8637
+ }
8638
+ const newSelection = resolveSelection(selectedPreset, projectType, teamSize, index, customSelections, void 0, { skipContextFilters: true });
8639
+ const oldIds = getAllContentIds(manifest.content);
8640
+ const newIds = getAllContentIds(newSelection);
8641
+ const pendingRemovals = [];
8642
+ for (const id of oldIds) {
8643
+ if (!newIds.has(id)) pendingRemovals.push(id);
8644
+ }
8645
+ if (pendingRemovals.length > 0) {
8646
+ const dependencyWarnings = [];
8647
+ for (const removedId of pendingRemovals) {
8648
+ const dependents = [];
8649
+ for (const keepId of newIds) {
8650
+ const keepItem = index.byId.get(keepId);
8651
+ if (!keepItem) continue;
8652
+ try {
8653
+ const filePath = keepItem.type === "skill" ? join23(agentsDir, keepItem.relativePath, "SKILL.md") : join23(agentsDir, keepItem.relativePath);
8654
+ const content = await readFile20(filePath, "utf-8");
8655
+ const refs = extractContentReferences(content);
8656
+ if (refs.includes(removedId)) {
8657
+ dependents.push(keepId);
8661
8658
  }
8662
- }
8663
- if (dependents.length > 0) {
8664
- dependencyWarnings.push(
8665
- `Removing "${removedId}" \u2014 referenced by: ${dependents.join(", ")}`
8666
- );
8667
- }
8668
- }
8669
- const proposedSelection = {
8670
- ...manifest.content,
8671
- items: {
8672
- agents: [],
8673
- skills: [],
8674
- rules: [],
8675
- commands: [],
8676
- prompts: [],
8677
- hooks: [],
8678
- githubAgents: []
8679
- }
8680
- };
8681
- for (const id of contentAnswer.items) {
8682
- const proposedItem = index.byId.get(id);
8683
- if (proposedItem) {
8684
- const key = TYPE_TO_SELECTION_KEY[proposedItem.type];
8685
- if (key) proposedSelection.items[key].push(proposedItem.id);
8659
+ } catch {
8686
8660
  }
8687
8661
  }
8688
- const orchWarnings = validateOrchestrationDependencies(proposedSelection);
8689
- dependencyWarnings.push(...orchWarnings);
8690
- if (dependencyWarnings.length > 0) {
8691
- console.log();
8692
- warn("Dependency warnings for removed content:");
8693
- for (const w of dependencyWarnings) {
8694
- console.log(chalk8.dim(` ${w}`));
8695
- }
8696
- console.log();
8662
+ if (dependents.length > 0) {
8663
+ dependencyWarnings.push(
8664
+ `Removing "${removedId}" \u2014 referenced by: ${dependents.join(", ")}`
8665
+ );
8697
8666
  }
8698
8667
  }
8699
- for (const id of contentAnswer.items) {
8700
- if (!currentIds.has(id)) {
8701
- const item = index.byId.get(id);
8702
- if (item) {
8703
- contentChanges.added.push({ type: item.type, id: item.id });
8704
- await addContentItem(contentRoot, agentsDir, item);
8705
- }
8668
+ const orchWarnings = validateOrchestrationDependencies(newSelection);
8669
+ dependencyWarnings.push(...orchWarnings);
8670
+ if (dependencyWarnings.length > 0) {
8671
+ console.log();
8672
+ warn("Dependency warnings for removed content:");
8673
+ for (const w of dependencyWarnings) {
8674
+ console.log(chalk8.dim(` ${w}`));
8706
8675
  }
8676
+ console.log();
8707
8677
  }
8708
- for (const id of currentIds) {
8709
- if (!newIds.has(id)) {
8710
- const item = index.byId.get(id);
8711
- if (item) {
8712
- contentChanges.removed.push({ type: item.type, id: item.id });
8713
- await removeContentItem(agentsDir, item, { rootDir });
8714
- }
8678
+ }
8679
+ for (const id of newIds) {
8680
+ if (!oldIds.has(id)) {
8681
+ const item = index.byId.get(id);
8682
+ if (item) {
8683
+ contentChanges.added.push({ type: item.type, id: item.id });
8684
+ await addContentItem(contentRoot, agentsDir, item);
8715
8685
  }
8716
8686
  }
8717
- const newItems = {
8718
- agents: [],
8719
- skills: [],
8720
- rules: [],
8721
- commands: [],
8722
- prompts: [],
8723
- hooks: [],
8724
- githubAgents: []
8725
- };
8726
- for (const id of contentAnswer.items) {
8687
+ }
8688
+ for (const id of oldIds) {
8689
+ if (!newIds.has(id)) {
8727
8690
  const item = index.byId.get(id);
8728
8691
  if (item) {
8729
- const key = TYPE_TO_SELECTION_KEY[item.type];
8730
- if (key) newItems[key].push(item.id);
8692
+ contentChanges.removed.push({ type: item.type, id: item.id });
8693
+ await removeContentItem(agentsDir, item, { rootDir });
8731
8694
  }
8732
8695
  }
8733
- manifest.content.items = newItems;
8734
- if (contentChanges.added.length > 0 || contentChanges.removed.length > 0) {
8735
- const canonicalAgentsMd = await generateCanonicalAgentsMd(agentsDir);
8736
- await safeWriteFile(join23(agentsDir, "AGENTS.md"), canonicalAgentsMd);
8737
- const rootAgentsMd = await generateRootAgentsMd(agentsDir);
8738
- await safeWriteFile(join23(rootDir, "AGENTS.md"), rootAgentsMd.full, {
8739
- managedContent: rootAgentsMd.inner
8740
- });
8741
- }
8696
+ }
8697
+ manifest.content = newSelection;
8698
+ contentMetadataChanged = previousContent.preset !== newSelection.preset || previousContent.projectType !== newSelection.projectType || previousContent.teamSize !== newSelection.teamSize;
8699
+ if (contentChanges.added.length > 0 || contentChanges.removed.length > 0) {
8700
+ const canonicalAgentsMd = await generateCanonicalAgentsMd(agentsDir);
8701
+ await safeWriteFile(join23(agentsDir, "AGENTS.md"), canonicalAgentsMd);
8702
+ const rootAgentsMd = await generateRootAgentsMd(agentsDir);
8703
+ await safeWriteFile(join23(rootDir, "AGENTS.md"), rootAgentsMd.full, {
8704
+ managedContent: rootAgentsMd.inner
8705
+ });
8742
8706
  }
8743
8707
  }
8744
8708
  const diff = computeDiff(manifest, tools, features, mcpServers, platform, owner, repo, namespace, project);
8745
8709
  diff.addedContent = contentChanges.added;
8746
8710
  diff.removedContent = contentChanges.removed;
8747
- if (isDiffEmpty(diff) && defaultBranch === currentBranch) {
8711
+ if (isDiffEmpty(diff) && defaultBranch === currentBranch && !contentMetadataChanged) {
8748
8712
  console.log();
8749
8713
  info("No changes detected.");
8750
8714
  console.log();
@@ -8905,7 +8869,7 @@ async function configCommand() {
8905
8869
  const currentRepos = wsManifestFinal.repos.map((r) => r.path);
8906
8870
  console.log(chalk8.dim(` Repos: ${currentRepos.join(", ") || "(none)"}`));
8907
8871
  console.log(chalk8.dim(` Sync strategy: ${wsManifestFinal.syncStrategy}`));
8908
- const { manageWorkspace } = await inquirer4.prompt([
8872
+ const { manageWorkspace } = await inquirer5.prompt([
8909
8873
  {
8910
8874
  type: "confirm",
8911
8875
  name: "manageWorkspace",
@@ -8918,7 +8882,7 @@ async function configCommand() {
8918
8882
  const existingPaths = new Set(wsManifestFinal.repos.map((r) => r.path));
8919
8883
  const newRepos = detectedRepos.filter((r) => !existingPaths.has(r.path));
8920
8884
  if (newRepos.length > 0) {
8921
- const { addRepos } = await inquirer4.prompt([
8885
+ const { addRepos } = await inquirer5.prompt([
8922
8886
  {
8923
8887
  type: "checkbox",
8924
8888
  name: "addRepos",
@@ -8936,7 +8900,7 @@ async function configCommand() {
8936
8900
  }
8937
8901
  }
8938
8902
  if (wsManifestFinal.repos.length > 0) {
8939
- const { syncRepos } = await inquirer4.prompt([
8903
+ const { syncRepos } = await inquirer5.prompt([
8940
8904
  {
8941
8905
  type: "checkbox",
8942
8906
  name: "syncRepos",
@@ -8955,7 +8919,7 @@ async function configCommand() {
8955
8919
  }
8956
8920
  }
8957
8921
  if (wsManifestFinal.repos.length > 0) {
8958
- const { editIdentity } = await inquirer4.prompt([
8922
+ const { editIdentity } = await inquirer5.prompt([
8959
8923
  {
8960
8924
  type: "select",
8961
8925
  name: "editIdentity",
@@ -8981,7 +8945,7 @@ async function configCommand() {
8981
8945
  for (const repo2 of wsManifestFinal.repos) {
8982
8946
  console.log(chalk8.bold(`
8983
8947
  ${repo2.name ?? repo2.path}:`));
8984
- const identity = await inquirer4.prompt([
8948
+ const identity = await inquirer5.prompt([
8985
8949
  { type: "input", name: "owner", message: " Owner:", default: repo2.owner || void 0 },
8986
8950
  { type: "input", name: "repo", message: " Repo:", default: repo2.repo || void 0 },
8987
8951
  { type: "input", name: "defaultBranch", message: " Default branch:", default: repo2.defaultBranch || "main" }
@@ -8992,7 +8956,7 @@ async function configCommand() {
8992
8956
  }
8993
8957
  }
8994
8958
  }
8995
- const { strategy } = await inquirer4.prompt([
8959
+ const { strategy } = await inquirer5.prompt([
8996
8960
  {
8997
8961
  type: "select",
8998
8962
  name: "strategy",
@@ -9008,7 +8972,7 @@ async function configCommand() {
9008
8972
  await writeWorkspaceManifest(rootDir, wsManifestFinal);
9009
8973
  const syncCount = wsManifestFinal.repos.filter((r) => r.sync).length;
9010
8974
  if (syncCount > 0) {
9011
- const { syncNow } = await inquirer4.prompt([
8975
+ const { syncNow } = await inquirer5.prompt([
9012
8976
  {
9013
8977
  type: "confirm",
9014
8978
  name: "syncNow",
@@ -10814,7 +10778,7 @@ program.name("hatch3r").description(
10814
10778
  program.command("init").description("Install a complete agent setup into the current repo (first-run: creates .agents/ directory)").option(
10815
10779
  "--tools <tools>",
10816
10780
  `Comma-separated tools (${TOOL_CHOICES})`
10817
- ).option("--yes", "Skip interactive prompts, use defaults").option("--preset <preset>", "Content preset: minimal, standard, full (default: standard)").option("--project-type <type>", "Project type: greenfield, brownfield").option("--team-size <size>", "Team size: solo, team").option("--workspace", "Initialize as a multi-repo workspace").action(initCommand);
10781
+ ).option("--yes", "Skip interactive prompts, use defaults").option("--preset <preset>", "Content preset: minimal, standard, full (default: full)").option("--project-type <type>", "Project type: greenfield, brownfield").option("--team-size <size>", "Team size: solo, team").option("--workspace", "Initialize as a multi-repo workspace").action(initCommand);
10818
10782
  program.command("sync").description("Re-generate tool outputs from canonical .agents/ state (run after editing .agents/)").option("--repos [paths...]", "Sync workspace content to sub-repos (all opted-in if no paths given)").option("--dry-run", "Show what would change without modifying files").option("--diff", "Show a before/after diff summary for each generated file").option("--force", "Overwrite locally modified files in sub-repos").option("--minimal", "Generate stripped-down output (no comments, minimal formatting) to reduce token usage").option("--verbose", "Show detailed output for each file processed").action(syncCommand);
10819
10783
  program.command("status").description("Check sync status between canonical .agents/ and generated files").option("--verbose", "Show detailed per-file status information").action(statusCommand);
10820
10784
  program.command("update").description("Pull latest hatch3r templates with safe merge (preserves customizations)").option("--yes", "Skip interactive prompts, use defaults").option("--diff", "Show a before/after diff summary for each generated file").action(updateCommand);