maxsimcli 4.7.0 → 4.8.0

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.cjs CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3
2
  //#region \0rolldown/runtime.js
4
3
  var __create = Object.create;
5
4
  var __defProp$1 = Object.defineProperty;
@@ -42,7 +41,6 @@ let node_process = require("node:process");
42
41
  node_process = __toESM(node_process);
43
42
  let node_tty = require("node:tty");
44
43
  node_tty = __toESM(node_tty);
45
- let node_module = require("node:module");
46
44
 
47
45
  //#region src/core/types.ts
48
46
  function cmdOk(result, rawValue) {
@@ -607,7 +605,7 @@ var require_has_flag = /* @__PURE__ */ __commonJSMin(((exports, module) => {
607
605
  //#endregion
608
606
  //#region ../../node_modules/supports-color/index.js
609
607
  var require_supports_color = /* @__PURE__ */ __commonJSMin(((exports, module) => {
610
- const os$6 = require("os");
608
+ const os$5 = require("os");
611
609
  const tty$2 = require("tty");
612
610
  const hasFlag = require_has_flag();
613
611
  const { env } = process;
@@ -634,7 +632,7 @@ var require_supports_color = /* @__PURE__ */ __commonJSMin(((exports, module) =>
634
632
  const min = forceColor || 0;
635
633
  if (env.TERM === "dumb") return min;
636
634
  if (process.platform === "win32") {
637
- const osRelease = os$6.release().split(".");
635
+ const osRelease = os$5.release().split(".");
638
636
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
639
637
  return 1;
640
638
  }
@@ -4799,17 +4797,12 @@ const isSummaryFile = (f) => f.endsWith("-SUMMARY.md") || f === "SUMMARY.md";
4799
4797
  const planId = (f) => f.replace("-PLAN.md", "").replace("PLAN.md", "");
4800
4798
  const summaryId = (f) => f.replace("-SUMMARY.md", "").replace("SUMMARY.md", "");
4801
4799
  /** List subdirectory names, optionally sorted by phase number. */
4802
- function listSubDirs(dir, sortByPhase = false) {
4803
- const dirs = node_fs.default.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
4804
- return sortByPhase ? dirs.sort((a, b) => comparePhaseNum(a, b)) : dirs;
4805
- }
4806
- /** Async version of listSubDirs using fs.promises. */
4807
- async function listSubDirsAsync(dir, sortByPhase = false) {
4800
+ async function listSubDirs(dir, sortByPhase = false) {
4808
4801
  const dirs = (await node_fs.promises.readdir(dir, { withFileTypes: true })).filter((e) => e.isDirectory()).map((e) => e.name);
4809
4802
  return sortByPhase ? dirs.sort((a, b) => comparePhaseNum(a, b)) : dirs;
4810
4803
  }
4811
- /** Async version of safeReadFile using fs.promises. */
4812
- async function safeReadFileAsync(filePath) {
4804
+ /** Read a file, returning null if it doesn't exist or fails. */
4805
+ async function safeReadFile(filePath) {
4813
4806
  try {
4814
4807
  return await node_fs.promises.readFile(filePath, "utf-8");
4815
4808
  } catch {
@@ -4830,104 +4823,7 @@ function debugLog(contextOrError, error) {
4830
4823
  function escapePhaseNum(phase) {
4831
4824
  return String(phase).replace(/\./g, "\\.");
4832
4825
  }
4833
- function safeReadFile(filePath) {
4834
- try {
4835
- return node_fs.default.readFileSync(filePath, "utf-8");
4836
- } catch {
4837
- return null;
4838
- }
4839
- }
4840
4826
  let _configCache = null;
4841
- function loadConfig(cwd) {
4842
- if (_configCache && _configCache.cwd === cwd) return _configCache.config;
4843
- const cfgPath = configPath(cwd);
4844
- const defaults = {
4845
- model_profile: "balanced",
4846
- commit_docs: true,
4847
- search_gitignored: false,
4848
- branching_strategy: "none",
4849
- phase_branch_template: "maxsim/phase-{phase}-{slug}",
4850
- milestone_branch_template: "maxsim/{milestone}-{slug}",
4851
- research: true,
4852
- plan_checker: true,
4853
- verifier: true,
4854
- parallelization: true,
4855
- brave_search: false
4856
- };
4857
- try {
4858
- const raw = node_fs.default.readFileSync(cfgPath, "utf-8");
4859
- const parsed = JSON.parse(raw);
4860
- const get = (key, nested) => {
4861
- if (parsed[key] !== void 0) return parsed[key];
4862
- if (nested) {
4863
- const section = parsed[nested.section];
4864
- if (section && typeof section === "object" && section !== null && nested.field in section) return section[nested.field];
4865
- }
4866
- };
4867
- const parallelization = (() => {
4868
- const val = get("parallelization");
4869
- if (typeof val === "boolean") return val;
4870
- if (typeof val === "object" && val !== null && "enabled" in val) return val.enabled;
4871
- return defaults.parallelization;
4872
- })();
4873
- const result = {
4874
- model_profile: get("model_profile") ?? defaults.model_profile,
4875
- commit_docs: get("commit_docs", {
4876
- section: "planning",
4877
- field: "commit_docs"
4878
- }) ?? defaults.commit_docs,
4879
- search_gitignored: get("search_gitignored", {
4880
- section: "planning",
4881
- field: "search_gitignored"
4882
- }) ?? defaults.search_gitignored,
4883
- branching_strategy: get("branching_strategy", {
4884
- section: "git",
4885
- field: "branching_strategy"
4886
- }) ?? defaults.branching_strategy,
4887
- phase_branch_template: get("phase_branch_template", {
4888
- section: "git",
4889
- field: "phase_branch_template"
4890
- }) ?? defaults.phase_branch_template,
4891
- milestone_branch_template: get("milestone_branch_template", {
4892
- section: "git",
4893
- field: "milestone_branch_template"
4894
- }) ?? defaults.milestone_branch_template,
4895
- research: get("research", {
4896
- section: "workflow",
4897
- field: "research"
4898
- }) ?? defaults.research,
4899
- plan_checker: get("plan_checker", {
4900
- section: "workflow",
4901
- field: "plan_checker"
4902
- }) ?? get("plan_checker", {
4903
- section: "workflow",
4904
- field: "plan_check"
4905
- }) ?? defaults.plan_checker,
4906
- verifier: get("verifier", {
4907
- section: "workflow",
4908
- field: "verifier"
4909
- }) ?? defaults.verifier,
4910
- parallelization,
4911
- brave_search: get("brave_search") ?? defaults.brave_search,
4912
- model_overrides: parsed["model_overrides"]
4913
- };
4914
- _configCache = {
4915
- cwd,
4916
- config: result
4917
- };
4918
- return result;
4919
- } catch (e) {
4920
- if (node_fs.default.existsSync(cfgPath)) {
4921
- console.warn(`[maxsim] Warning: config.json exists but could not be parsed — using defaults.`);
4922
- debugLog("config-load-failed", e);
4923
- }
4924
- _configCache = {
4925
- cwd,
4926
- config: defaults
4927
- };
4928
- return defaults;
4929
- }
4930
- }
4931
4827
  async function isGitIgnored(cwd, targetPath) {
4932
4828
  try {
4933
4829
  return (await simpleGit(cwd).checkIgnore(targetPath)).length > 0;
@@ -4997,128 +4893,8 @@ function getPhasePattern(escapedPhaseNum, flags = "gim") {
4997
4893
  if (escapedPhaseNum) return new RegExp(`^#{2,4}\\s*Phase\\s+${escapedPhaseNum}:\\s*([^\\n]+)`, flags);
4998
4894
  return new RegExp(`^#{2,4}\\s*Phase\\s+(\\d+[A-Z]?(?:\\.\\d+)?)\\s*:\\s*([^\\n]+)`, flags);
4999
4895
  }
5000
- function searchPhaseInDir(baseDir, relBase, normalized) {
5001
- try {
5002
- const match = listSubDirs(baseDir, true).find((d) => d.startsWith(normalized));
5003
- if (!match) return null;
5004
- const dirMatch = match.match(/^(\d+[A-Z]?(?:\.\d+)?)-?(.*)/i);
5005
- const phaseNumber = dirMatch ? dirMatch[1] : normalized;
5006
- const phaseName = dirMatch && dirMatch[2] ? dirMatch[2] : null;
5007
- const phaseDir = node_path.default.join(baseDir, match);
5008
- const phaseFiles = node_fs.default.readdirSync(phaseDir);
5009
- const plans = phaseFiles.filter(isPlanFile).sort();
5010
- const summaries = phaseFiles.filter(isSummaryFile).sort();
5011
- const hasResearch = phaseFiles.some((f) => f.endsWith("-RESEARCH.md") || f === "RESEARCH.md");
5012
- const hasContext = phaseFiles.some((f) => f.endsWith("-CONTEXT.md") || f === "CONTEXT.md");
5013
- const hasVerification = phaseFiles.some((f) => f.endsWith("-VERIFICATION.md") || f === "VERIFICATION.md");
5014
- const completedPlanIds = new Set(summaries.map(summaryId));
5015
- const incompletePlans = plans.filter((p) => !completedPlanIds.has(planId(p)));
5016
- return {
5017
- found: true,
5018
- directory: node_path.default.join(relBase, match),
5019
- phase_number: phaseNumber,
5020
- phase_name: phaseName,
5021
- phase_slug: phaseName ? phaseName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") : null,
5022
- plans,
5023
- summaries,
5024
- incomplete_plans: incompletePlans,
5025
- has_research: hasResearch,
5026
- has_context: hasContext,
5027
- has_verification: hasVerification
5028
- };
5029
- } catch (e) {
5030
- debugLog("search-phase-in-dir-failed", {
5031
- dir: baseDir,
5032
- phase: normalized,
5033
- error: errorMsg(e)
5034
- });
5035
- return null;
5036
- }
5037
- }
5038
- function findPhaseInternal(cwd, phase) {
5039
- if (!phase) return null;
5040
- const pd = phasesPath(cwd);
5041
- const normalized = normalizePhaseName(phase);
5042
- const current = searchPhaseInDir(pd, node_path.default.join(".planning", "phases"), normalized);
5043
- if (current) return current;
5044
- const milestonesDir = planningPath(cwd, "milestones");
5045
- try {
5046
- node_fs.default.statSync(milestonesDir);
5047
- } catch {
5048
- return null;
5049
- }
5050
- try {
5051
- const archiveDirs = node_fs.default.readdirSync(milestonesDir, { withFileTypes: true }).filter((e) => e.isDirectory() && /^v[\d.]+-phases$/.test(e.name)).map((e) => e.name).sort().reverse();
5052
- for (const archiveName of archiveDirs) {
5053
- const versionMatch = archiveName.match(/^(v[\d.]+)-phases$/);
5054
- if (!versionMatch) continue;
5055
- const version = versionMatch[1];
5056
- const result = searchPhaseInDir(node_path.default.join(milestonesDir, archiveName), node_path.default.join(".planning", "milestones", archiveName), normalized);
5057
- if (result) {
5058
- result.archived = version;
5059
- return result;
5060
- }
5061
- }
5062
- } catch (e) {
5063
- debugLog("find-phase-milestone-search-failed", e);
5064
- }
5065
- return null;
5066
- }
5067
- function getArchivedPhaseDirs(cwd) {
5068
- const milestonesDir = planningPath(cwd, "milestones");
5069
- const results = [];
5070
- try {
5071
- const phaseDirs = node_fs.default.readdirSync(milestonesDir, { withFileTypes: true }).filter((e) => e.isDirectory() && /^v[\d.]+-phases$/.test(e.name)).map((e) => e.name).sort().reverse();
5072
- for (const archiveName of phaseDirs) {
5073
- const versionMatch = archiveName.match(/^(v[\d.]+)-phases$/);
5074
- if (!versionMatch) continue;
5075
- const version = versionMatch[1];
5076
- const archivePath = node_path.default.join(milestonesDir, archiveName);
5077
- const dirs = listSubDirs(archivePath, true);
5078
- for (const dir of dirs) results.push({
5079
- name: dir,
5080
- milestone: version,
5081
- basePath: node_path.default.join(".planning", "milestones", archiveName),
5082
- fullPath: node_path.default.join(archivePath, dir)
5083
- });
5084
- }
5085
- } catch (e) {
5086
- debugLog("get-archived-phase-dirs-failed", e);
5087
- }
5088
- return results;
5089
- }
5090
- function getRoadmapPhaseInternal(cwd, phaseNum) {
5091
- if (!phaseNum) return null;
5092
- const rp = roadmapPath(cwd);
5093
- try {
5094
- const content = node_fs.default.readFileSync(rp, "utf-8");
5095
- const phasePattern = getPhasePattern(escapePhaseNum(phaseNum), "i");
5096
- const headerMatch = content.match(phasePattern);
5097
- if (!headerMatch) return null;
5098
- const phaseName = headerMatch[1].trim();
5099
- const headerIndex = headerMatch.index;
5100
- const nextHeaderMatch = content.slice(headerIndex).match(/\n#{2,4}\s+Phase\s+\d/i);
5101
- const sectionEnd = nextHeaderMatch ? headerIndex + nextHeaderMatch.index : content.length;
5102
- const section = content.slice(headerIndex, sectionEnd).trim();
5103
- const goalMatch = section.match(/\*\*Goal(?::\*\*|\*\*:)\s*([^\n]+)/i);
5104
- const goal = goalMatch ? goalMatch[1].trim() : null;
5105
- return {
5106
- found: true,
5107
- phase_number: phaseNum.toString(),
5108
- phase_name: phaseName,
5109
- goal,
5110
- section
5111
- };
5112
- } catch (e) {
5113
- debugLog("get-roadmap-phase-failed", {
5114
- phase: phaseNum,
5115
- error: errorMsg(e)
5116
- });
5117
- return null;
5118
- }
5119
- }
5120
- function resolveModelInternal(cwd, agentType, config) {
5121
- config = config ?? loadConfig(cwd);
4896
+ async function resolveModelInternal(cwd, agentType, config) {
4897
+ config = config ?? await loadConfig(cwd);
5122
4898
  const override = config.model_overrides?.[agentType];
5123
4899
  if (override) return override === "opus" ? "inherit" : override;
5124
4900
  const profile = config.model_profile || "balanced";
@@ -5127,15 +4903,6 @@ function resolveModelInternal(cwd, agentType, config) {
5127
4903
  const resolved = agentModels[profile] || agentModels["balanced"] || "sonnet";
5128
4904
  return resolved === "opus" ? "inherit" : resolved;
5129
4905
  }
5130
- function pathExistsInternal(cwd, targetPath) {
5131
- const fullPath = node_path.default.isAbsolute(targetPath) ? targetPath : node_path.default.join(cwd, targetPath);
5132
- try {
5133
- node_fs.default.statSync(fullPath);
5134
- return true;
5135
- } catch {
5136
- return false;
5137
- }
5138
- }
5139
4906
  function generateSlugInternal(text) {
5140
4907
  if (!text) return null;
5141
4908
  return (0, import_slugify.default)(text, {
@@ -5143,23 +4910,7 @@ function generateSlugInternal(text) {
5143
4910
  strict: true
5144
4911
  });
5145
4912
  }
5146
- function getMilestoneInfo(cwd) {
5147
- try {
5148
- const roadmap = node_fs.default.readFileSync(roadmapPath(cwd), "utf-8");
5149
- const versionMatch = roadmap.match(/v(\d+\.\d+)/);
5150
- const nameMatch = roadmap.match(/## .*v\d+\.\d+[:\s]+([^\n(]+)/);
5151
- return {
5152
- version: versionMatch ? versionMatch[0] : "v1.0",
5153
- name: nameMatch ? nameMatch[1].trim() : "milestone"
5154
- };
5155
- } catch {
5156
- return {
5157
- version: "v1.0",
5158
- name: "milestone"
5159
- };
5160
- }
5161
- }
5162
- async function pathExistsAsync(p) {
4913
+ async function pathExistsInternal(p) {
5163
4914
  try {
5164
4915
  await node_fs.promises.access(p);
5165
4916
  return true;
@@ -5167,9 +4918,99 @@ async function pathExistsAsync(p) {
5167
4918
  return false;
5168
4919
  }
5169
4920
  }
5170
- async function searchPhaseInDirAsync(baseDir, relBase, normalized) {
4921
+ async function loadConfig(cwd) {
4922
+ if (_configCache && _configCache.cwd === cwd) return _configCache.config;
4923
+ const cfgPath = configPath(cwd);
4924
+ const defaults = {
4925
+ model_profile: "balanced",
4926
+ commit_docs: true,
4927
+ search_gitignored: false,
4928
+ branching_strategy: "none",
4929
+ phase_branch_template: "maxsim/phase-{phase}-{slug}",
4930
+ milestone_branch_template: "maxsim/{milestone}-{slug}",
4931
+ research: true,
4932
+ plan_checker: true,
4933
+ verifier: true,
4934
+ parallelization: true,
4935
+ brave_search: false
4936
+ };
4937
+ try {
4938
+ const raw = await node_fs.promises.readFile(cfgPath, "utf-8");
4939
+ const parsed = JSON.parse(raw);
4940
+ const get = (key, nested) => {
4941
+ if (parsed[key] !== void 0) return parsed[key];
4942
+ if (nested) {
4943
+ const section = parsed[nested.section];
4944
+ if (section && typeof section === "object" && section !== null && nested.field in section) return section[nested.field];
4945
+ }
4946
+ };
4947
+ const parallelization = (() => {
4948
+ const val = get("parallelization");
4949
+ if (typeof val === "boolean") return val;
4950
+ if (typeof val === "object" && val !== null && "enabled" in val) return val.enabled;
4951
+ return defaults.parallelization;
4952
+ })();
4953
+ const result = {
4954
+ model_profile: get("model_profile") ?? defaults.model_profile,
4955
+ commit_docs: get("commit_docs", {
4956
+ section: "planning",
4957
+ field: "commit_docs"
4958
+ }) ?? defaults.commit_docs,
4959
+ search_gitignored: get("search_gitignored", {
4960
+ section: "planning",
4961
+ field: "search_gitignored"
4962
+ }) ?? defaults.search_gitignored,
4963
+ branching_strategy: get("branching_strategy", {
4964
+ section: "git",
4965
+ field: "branching_strategy"
4966
+ }) ?? defaults.branching_strategy,
4967
+ phase_branch_template: get("phase_branch_template", {
4968
+ section: "git",
4969
+ field: "phase_branch_template"
4970
+ }) ?? defaults.phase_branch_template,
4971
+ milestone_branch_template: get("milestone_branch_template", {
4972
+ section: "git",
4973
+ field: "milestone_branch_template"
4974
+ }) ?? defaults.milestone_branch_template,
4975
+ research: get("research", {
4976
+ section: "workflow",
4977
+ field: "research"
4978
+ }) ?? defaults.research,
4979
+ plan_checker: get("plan_checker", {
4980
+ section: "workflow",
4981
+ field: "plan_checker"
4982
+ }) ?? get("plan_checker", {
4983
+ section: "workflow",
4984
+ field: "plan_check"
4985
+ }) ?? defaults.plan_checker,
4986
+ verifier: get("verifier", {
4987
+ section: "workflow",
4988
+ field: "verifier"
4989
+ }) ?? defaults.verifier,
4990
+ parallelization,
4991
+ brave_search: get("brave_search") ?? defaults.brave_search,
4992
+ model_overrides: parsed["model_overrides"]
4993
+ };
4994
+ _configCache = {
4995
+ cwd,
4996
+ config: result
4997
+ };
4998
+ return result;
4999
+ } catch (e) {
5000
+ if (await pathExistsInternal(cfgPath)) {
5001
+ console.warn(`[maxsim] Warning: config.json exists but could not be parsed — using defaults.`);
5002
+ debugLog("config-load-failed", e);
5003
+ }
5004
+ _configCache = {
5005
+ cwd,
5006
+ config: defaults
5007
+ };
5008
+ return defaults;
5009
+ }
5010
+ }
5011
+ async function searchPhaseInDir(baseDir, relBase, normalized) {
5171
5012
  try {
5172
- const match = (await listSubDirsAsync(baseDir, true)).find((d) => d.startsWith(normalized));
5013
+ const match = (await listSubDirs(baseDir, true)).find((d) => d.startsWith(normalized));
5173
5014
  if (!match) return null;
5174
5015
  const dirMatch = match.match(/^(\d+[A-Z]?(?:\.\d+)?)-?(.*)/i);
5175
5016
  const phaseNumber = dirMatch ? dirMatch[1] : normalized;
@@ -5205,17 +5046,17 @@ async function searchPhaseInDirAsync(baseDir, relBase, normalized) {
5205
5046
  return null;
5206
5047
  }
5207
5048
  }
5208
- async function findPhaseInternalAsync(cwd, phase) {
5049
+ async function findPhaseInternal(cwd, phase) {
5209
5050
  if (!phase) return null;
5210
5051
  const pd = phasesPath(cwd);
5211
5052
  const normalized = normalizePhaseName(phase);
5212
- const current = await searchPhaseInDirAsync(pd, node_path.default.join(".planning", "phases"), normalized);
5053
+ const current = await searchPhaseInDir(pd, node_path.default.join(".planning", "phases"), normalized);
5213
5054
  if (current) return current;
5214
5055
  const archiveDir = planningPath(cwd, "archive");
5215
- if (await pathExistsAsync(archiveDir)) try {
5056
+ if (await pathExistsInternal(archiveDir)) try {
5216
5057
  const versionDirs = (await node_fs.promises.readdir(archiveDir, { withFileTypes: true })).filter((e) => e.isDirectory()).map((e) => e.name).sort().reverse();
5217
5058
  for (const versionName of versionDirs) {
5218
- const result = await searchPhaseInDirAsync(node_path.default.join(archiveDir, versionName), node_path.default.join(".planning", "archive", versionName), normalized);
5059
+ const result = await searchPhaseInDir(node_path.default.join(archiveDir, versionName), node_path.default.join(".planning", "archive", versionName), normalized);
5219
5060
  if (result) {
5220
5061
  result.archived = versionName;
5221
5062
  return result;
@@ -5225,14 +5066,14 @@ async function findPhaseInternalAsync(cwd, phase) {
5225
5066
  debugLog("find-phase-async-archive-search-failed", e);
5226
5067
  }
5227
5068
  const milestonesDir = planningPath(cwd, "milestones");
5228
- if (!await pathExistsAsync(milestonesDir)) return null;
5069
+ if (!await pathExistsInternal(milestonesDir)) return null;
5229
5070
  try {
5230
5071
  const archiveDirs = (await node_fs.promises.readdir(milestonesDir, { withFileTypes: true })).filter((e) => e.isDirectory() && /^v[\d.]+-phases$/.test(e.name)).map((e) => e.name).sort().reverse();
5231
5072
  for (const archiveName of archiveDirs) {
5232
5073
  const versionMatch = archiveName.match(/^(v[\d.]+)-phases$/);
5233
5074
  if (!versionMatch) continue;
5234
5075
  const version = versionMatch[1];
5235
- const result = await searchPhaseInDirAsync(node_path.default.join(milestonesDir, archiveName), node_path.default.join(".planning", "milestones", archiveName), normalized);
5076
+ const result = await searchPhaseInDir(node_path.default.join(milestonesDir, archiveName), node_path.default.join(".planning", "milestones", archiveName), normalized);
5236
5077
  if (result) {
5237
5078
  result.archived = version;
5238
5079
  return result;
@@ -5243,14 +5084,14 @@ async function findPhaseInternalAsync(cwd, phase) {
5243
5084
  }
5244
5085
  return null;
5245
5086
  }
5246
- async function getArchivedPhaseDirsAsync(cwd) {
5087
+ async function getArchivedPhaseDirs(cwd) {
5247
5088
  const results = [];
5248
5089
  const archiveDir = planningPath(cwd, "archive");
5249
5090
  try {
5250
5091
  const versionDirs = (await node_fs.promises.readdir(archiveDir, { withFileTypes: true })).filter((e) => e.isDirectory()).map((e) => e.name).sort().reverse();
5251
5092
  for (const versionName of versionDirs) {
5252
5093
  const versionPath = node_path.default.join(archiveDir, versionName);
5253
- const dirs = await listSubDirsAsync(versionPath, true);
5094
+ const dirs = await listSubDirs(versionPath, true);
5254
5095
  for (const dir of dirs) results.push({
5255
5096
  name: dir,
5256
5097
  milestone: versionName,
@@ -5269,7 +5110,7 @@ async function getArchivedPhaseDirsAsync(cwd) {
5269
5110
  if (!versionMatch) continue;
5270
5111
  const version = versionMatch[1];
5271
5112
  const archiveMilestonePath = node_path.default.join(milestonesDir, archiveName);
5272
- const dirs = await listSubDirsAsync(archiveMilestonePath, true);
5113
+ const dirs = await listSubDirs(archiveMilestonePath, true);
5273
5114
  for (const dir of dirs) results.push({
5274
5115
  name: dir,
5275
5116
  milestone: version,
@@ -5282,15 +5123,43 @@ async function getArchivedPhaseDirsAsync(cwd) {
5282
5123
  }
5283
5124
  return results;
5284
5125
  }
5285
- function archivePath(cwd, milestone) {
5286
- return planningPath(cwd, "archive", milestone ?? getMilestoneInfo(cwd).version);
5126
+ async function getRoadmapPhaseInternal(cwd, phaseNum) {
5127
+ if (!phaseNum) return null;
5128
+ const rp = roadmapPath(cwd);
5129
+ try {
5130
+ const content = await safeReadFile(rp);
5131
+ if (!content) return null;
5132
+ const phasePattern = getPhasePattern(escapePhaseNum(phaseNum), "i");
5133
+ const headerMatch = content.match(phasePattern);
5134
+ if (!headerMatch) return null;
5135
+ const phaseName = headerMatch[1].trim();
5136
+ const headerIndex = headerMatch.index;
5137
+ const nextHeaderMatch = content.slice(headerIndex).match(/\n#{2,4}\s+Phase\s+\d/i);
5138
+ const sectionEnd = nextHeaderMatch ? headerIndex + nextHeaderMatch.index : content.length;
5139
+ const section = content.slice(headerIndex, sectionEnd).trim();
5140
+ const goalMatch = section.match(/\*\*Goal(?::\*\*|\*\*:)\s*([^\n]+)/i);
5141
+ const goal = goalMatch ? goalMatch[1].trim() : null;
5142
+ return {
5143
+ found: true,
5144
+ phase_number: phaseNum.toString(),
5145
+ phase_name: phaseName,
5146
+ goal,
5147
+ section
5148
+ };
5149
+ } catch (e) {
5150
+ debugLog("get-roadmap-phase-async-failed", {
5151
+ phase: phaseNum,
5152
+ error: errorMsg(e)
5153
+ });
5154
+ return null;
5155
+ }
5287
5156
  }
5288
- async function archivePathAsync(cwd, milestone) {
5289
- return planningPath(cwd, "archive", milestone ?? (await getMilestoneInfoAsync(cwd)).version);
5157
+ async function archivePath(cwd, milestone) {
5158
+ return planningPath(cwd, "archive", milestone ?? (await getMilestoneInfo(cwd)).version);
5290
5159
  }
5291
- async function getMilestoneInfoAsync(cwd) {
5160
+ async function getMilestoneInfo(cwd) {
5292
5161
  try {
5293
- const roadmap = await safeReadFileAsync(roadmapPath(cwd));
5162
+ const roadmap = await safeReadFile(roadmapPath(cwd));
5294
5163
  if (!roadmap) return {
5295
5164
  version: "v1.0",
5296
5165
  name: "milestone"
@@ -12051,9 +11920,9 @@ const FRONTMATTER_SCHEMAS = {
12051
11920
  "info_count"
12052
11921
  ] }
12053
11922
  };
12054
- function cmdFrontmatterGet(cwd, filePath, field) {
11923
+ async function cmdFrontmatterGet(cwd, filePath, field) {
12055
11924
  if (!filePath) return cmdErr("file path required");
12056
- const content = safeReadFile(node_path.default.isAbsolute(filePath) ? filePath : node_path.default.join(cwd, filePath));
11925
+ const content = await safeReadFile(node_path.default.isAbsolute(filePath) ? filePath : node_path.default.join(cwd, filePath));
12057
11926
  if (!content) return cmdOk({
12058
11927
  error: "File not found",
12059
11928
  path: filePath
@@ -12115,11 +11984,11 @@ function cmdFrontmatterMerge(cwd, filePath, data) {
12115
11984
  fields: Object.keys(mergeData)
12116
11985
  }, "true");
12117
11986
  }
12118
- function cmdFrontmatterValidate(cwd, filePath, schemaName) {
11987
+ async function cmdFrontmatterValidate(cwd, filePath, schemaName) {
12119
11988
  if (!filePath || !schemaName) return cmdErr("file and schema required");
12120
11989
  const schema = FRONTMATTER_SCHEMAS[schemaName];
12121
11990
  if (!schema) return cmdErr(`Unknown schema: ${schemaName}. Available: ${Object.keys(FRONTMATTER_SCHEMAS).join(", ")}`);
12122
- const content = safeReadFile(node_path.default.isAbsolute(filePath) ? filePath : node_path.default.join(cwd, filePath));
11991
+ const content = await safeReadFile(node_path.default.isAbsolute(filePath) ? filePath : node_path.default.join(cwd, filePath));
12123
11992
  if (!content) return cmdOk({
12124
11993
  error: "File not found",
12125
11994
  path: filePath
@@ -12302,11 +12171,11 @@ function appendToStateSection(content, sectionPattern, entry, placeholderPattern
12302
12171
  return content.replace(sectionPattern, (_m, header) => `${header}${sectionBody}`);
12303
12172
  }
12304
12173
  async function cmdStateLoad(cwd, raw) {
12305
- const config = loadConfig(cwd);
12174
+ const config = await loadConfig(cwd);
12306
12175
  const [stateContent, configExists, roadmapExists] = await Promise.all([
12307
- safeReadFileAsync(statePath(cwd)),
12308
- pathExistsAsync(configPath(cwd)),
12309
- pathExistsAsync(roadmapPath(cwd))
12176
+ safeReadFile(statePath(cwd)),
12177
+ pathExistsInternal(configPath(cwd)),
12178
+ pathExistsInternal(roadmapPath(cwd))
12310
12179
  ]);
12311
12180
  const stateRaw = stateContent ?? "";
12312
12181
  const stateExists = stateRaw.length > 0;
@@ -12397,7 +12266,7 @@ async function cmdStateUpdate(cwd, field, value) {
12397
12266
  }
12398
12267
  async function cmdStateAdvancePlan(cwd, raw) {
12399
12268
  const statePath$5 = statePath(cwd);
12400
- if (!await pathExistsAsync(statePath$5)) return cmdOk({ error: "STATE.md not found" });
12269
+ if (!await pathExistsInternal(statePath$5)) return cmdOk({ error: "STATE.md not found" });
12401
12270
  let content = await node_fs.promises.readFile(statePath$5, "utf-8");
12402
12271
  const currentPlan = parseInt(stateExtractField(content, "Current Plan") ?? "", 10);
12403
12272
  const totalPlans = parseInt(stateExtractField(content, "Total Plans in Phase") ?? "", 10);
@@ -12430,7 +12299,7 @@ async function cmdStateAdvancePlan(cwd, raw) {
12430
12299
  }
12431
12300
  async function cmdStateRecordMetric(cwd, options, raw) {
12432
12301
  const statePath$6 = statePath(cwd);
12433
- if (!await pathExistsAsync(statePath$6)) return cmdOk({ error: "STATE.md not found" });
12302
+ if (!await pathExistsInternal(statePath$6)) return cmdOk({ error: "STATE.md not found" });
12434
12303
  let content = await node_fs.promises.readFile(statePath$6, "utf-8");
12435
12304
  const { phase, plan, duration, tasks, files } = options;
12436
12305
  if (!phase || !plan || !duration) return cmdOk({ error: "phase, plan, and duration required" });
@@ -12456,12 +12325,12 @@ async function cmdStateRecordMetric(cwd, options, raw) {
12456
12325
  }
12457
12326
  async function cmdStateUpdateProgress(cwd, raw) {
12458
12327
  const statePath$7 = statePath(cwd);
12459
- if (!await pathExistsAsync(statePath$7)) return cmdOk({ error: "STATE.md not found" });
12328
+ if (!await pathExistsInternal(statePath$7)) return cmdOk({ error: "STATE.md not found" });
12460
12329
  let content = await node_fs.promises.readFile(statePath$7, "utf-8");
12461
12330
  const phasesDir = phasesPath(cwd);
12462
12331
  let totalPlans = 0;
12463
12332
  let totalSummaries = 0;
12464
- if (await pathExistsAsync(phasesDir)) {
12333
+ if (await pathExistsInternal(phasesDir)) {
12465
12334
  const phaseDirs = (await node_fs.promises.readdir(phasesDir, { withFileTypes: true })).filter((e) => e.isDirectory()).map((e) => e.name);
12466
12335
  const counts = await Promise.all(phaseDirs.map(async (dir) => {
12467
12336
  const files = await node_fs.promises.readdir(node_path.default.join(phasesDir, dir));
@@ -12496,7 +12365,7 @@ async function cmdStateUpdateProgress(cwd, raw) {
12496
12365
  }
12497
12366
  async function cmdStateAddDecision(cwd, options, raw) {
12498
12367
  const statePath$8 = statePath(cwd);
12499
- if (!await pathExistsAsync(statePath$8)) return cmdOk({ error: "STATE.md not found" });
12368
+ if (!await pathExistsInternal(statePath$8)) return cmdOk({ error: "STATE.md not found" });
12500
12369
  const { phase, summary, summary_file, rationale, rationale_file } = options;
12501
12370
  let summaryText;
12502
12371
  let rationaleText = "";
@@ -12526,7 +12395,7 @@ async function cmdStateAddDecision(cwd, options, raw) {
12526
12395
  }
12527
12396
  async function cmdStateAddBlocker(cwd, text, raw) {
12528
12397
  const statePath$9 = statePath(cwd);
12529
- if (!await pathExistsAsync(statePath$9)) return cmdOk({ error: "STATE.md not found" });
12398
+ if (!await pathExistsInternal(statePath$9)) return cmdOk({ error: "STATE.md not found" });
12530
12399
  const blockerOptions = typeof text === "object" && text !== null ? text : { text };
12531
12400
  let blockerText;
12532
12401
  try {
@@ -12552,7 +12421,7 @@ async function cmdStateAddBlocker(cwd, text, raw) {
12552
12421
  }
12553
12422
  async function cmdStateResolveBlocker(cwd, text, raw) {
12554
12423
  const statePath$10 = statePath(cwd);
12555
- if (!await pathExistsAsync(statePath$10)) return cmdOk({ error: "STATE.md not found" });
12424
+ if (!await pathExistsInternal(statePath$10)) return cmdOk({ error: "STATE.md not found" });
12556
12425
  if (!text) return cmdOk({ error: "text required" });
12557
12426
  let content = await node_fs.promises.readFile(statePath$10, "utf-8");
12558
12427
  const sectionPattern = /(#{2,3}\s*(?:Blockers|Blockers\/Concerns|Concerns)\s*\n\s*\n?)([\s\S]*?)(?=\n#{2,3}\s|$)/i;
@@ -12576,7 +12445,7 @@ async function cmdStateResolveBlocker(cwd, text, raw) {
12576
12445
  }
12577
12446
  async function cmdStateRecordSession(cwd, options, raw) {
12578
12447
  const statePath$11 = statePath(cwd);
12579
- if (!await pathExistsAsync(statePath$11)) return cmdOk({ error: "STATE.md not found" });
12448
+ if (!await pathExistsInternal(statePath$11)) return cmdOk({ error: "STATE.md not found" });
12580
12449
  let content = await node_fs.promises.readFile(statePath$11, "utf-8");
12581
12450
  const now = (/* @__PURE__ */ new Date()).toISOString();
12582
12451
  const updated = [];
@@ -12618,7 +12487,7 @@ async function cmdStateRecordSession(cwd, options, raw) {
12618
12487
  }
12619
12488
  async function cmdStateSnapshot(cwd, raw) {
12620
12489
  const statePath$12 = statePath(cwd);
12621
- if (!await pathExistsAsync(statePath$12)) return cmdOk({ error: "STATE.md not found" });
12490
+ if (!await pathExistsInternal(statePath$12)) return cmdOk({ error: "STATE.md not found" });
12622
12491
  const content = await node_fs.promises.readFile(statePath$12, "utf-8");
12623
12492
  const extractField = (fieldName) => stateExtractField(content, fieldName);
12624
12493
  const currentPhase = extractField("Current Phase");
@@ -12685,7 +12554,7 @@ async function cmdStateSnapshot(cwd, raw) {
12685
12554
  async function cmdDetectStaleContext(cwd) {
12686
12555
  const rmPath = roadmapPath(cwd);
12687
12556
  const stPath = statePath(cwd);
12688
- const [roadmapContent, stateContent] = await Promise.all([safeReadFileAsync(rmPath), safeReadFileAsync(stPath)]);
12557
+ const [roadmapContent, stateContent] = await Promise.all([safeReadFile(rmPath), safeReadFile(stPath)]);
12689
12558
  if (!roadmapContent) return cmdErr("ROADMAP.md not found");
12690
12559
  if (!stateContent) return cmdErr("STATE.md not found");
12691
12560
  const completedPhases = [];
@@ -12740,7 +12609,7 @@ async function cmdDetectStaleContext(cwd) {
12740
12609
  * Ported from maxsim/bin/lib/roadmap.cjs
12741
12610
  */
12742
12611
  async function cmdRoadmapGetPhase(cwd, phaseNum) {
12743
- const content = await safeReadFileAsync(roadmapPath(cwd));
12612
+ const content = await safeReadFile(roadmapPath(cwd));
12744
12613
  if (!content) return cmdOk({
12745
12614
  found: false,
12746
12615
  error: "ROADMAP.md not found"
@@ -12785,7 +12654,7 @@ async function cmdRoadmapGetPhase(cwd, phaseNum) {
12785
12654
  }
12786
12655
  }
12787
12656
  async function cmdRoadmapAnalyze(cwd) {
12788
- const content = await safeReadFileAsync(roadmapPath(cwd));
12657
+ const content = await safeReadFile(roadmapPath(cwd));
12789
12658
  if (!content) return cmdOk({
12790
12659
  error: "ROADMAP.md not found",
12791
12660
  milestones: [],
@@ -12818,7 +12687,7 @@ async function cmdRoadmapAnalyze(cwd) {
12818
12687
  }
12819
12688
  let allDirs = [];
12820
12689
  try {
12821
- allDirs = await listSubDirsAsync(phasesDir);
12690
+ allDirs = await listSubDirs(phasesDir);
12822
12691
  } catch {}
12823
12692
  const phases = await Promise.all(parsedPhases.map(async (p) => {
12824
12693
  let diskStatus = "no_directory";
@@ -12893,7 +12762,7 @@ async function cmdRoadmapAnalyze(cwd) {
12893
12762
  async function cmdRoadmapUpdatePlanProgress(cwd, phaseNum) {
12894
12763
  if (!phaseNum) return cmdErr("phase number required for roadmap update-plan-progress");
12895
12764
  const rmPath = roadmapPath(cwd);
12896
- const phaseInfo = await findPhaseInternalAsync(cwd, phaseNum);
12765
+ const phaseInfo = await findPhaseInternal(cwd, phaseNum);
12897
12766
  if (!phaseInfo) return cmdErr(`Phase ${phaseNum} not found`);
12898
12767
  const planCount = phaseInfo.plans.length;
12899
12768
  const summaryCount = phaseInfo.summaries.length;
@@ -12906,7 +12775,7 @@ async function cmdRoadmapUpdatePlanProgress(cwd, phaseNum) {
12906
12775
  const isComplete = summaryCount >= planCount;
12907
12776
  const status = isComplete ? "Complete" : summaryCount > 0 ? "In Progress" : "Planned";
12908
12777
  const today = todayISO();
12909
- const rawContent = await safeReadFileAsync(rmPath);
12778
+ const rawContent = await safeReadFile(rmPath);
12910
12779
  if (!rawContent) return cmdOk({
12911
12780
  updated: false,
12912
12781
  reason: "ROADMAP.md not found",
@@ -12979,7 +12848,7 @@ async function cmdMilestoneComplete(cwd, version, options) {
12979
12848
  const reqPath = planningPath(cwd, "REQUIREMENTS.md");
12980
12849
  const statePath$1 = statePath(cwd);
12981
12850
  const milestonesPath = planningPath(cwd, "MILESTONES.md");
12982
- const archiveDir = archivePath(cwd, version);
12851
+ const archiveDir = await archivePath(cwd, version);
12983
12852
  const phasesDir = phasesPath(cwd);
12984
12853
  const today = todayISO();
12985
12854
  const milestoneName = options.name || version;
@@ -12989,7 +12858,7 @@ async function cmdMilestoneComplete(cwd, version, options) {
12989
12858
  let totalTasks = 0;
12990
12859
  const accomplishments = [];
12991
12860
  try {
12992
- const dirs = await listSubDirsAsync(phasesDir, true);
12861
+ const dirs = await listSubDirs(phasesDir, true);
12993
12862
  for (const dir of dirs) {
12994
12863
  phaseCount++;
12995
12864
  const phaseFiles = await node_fs.promises.readdir(node_path.default.join(phasesDir, dir));
@@ -13009,12 +12878,12 @@ async function cmdMilestoneComplete(cwd, version, options) {
13009
12878
  } catch (e) {
13010
12879
  debugLog(e);
13011
12880
  }
13012
- const stateExists = await pathExistsAsync(statePath$1);
12881
+ const stateExists = await pathExistsInternal(statePath$1);
13013
12882
  if (stateExists) {
13014
12883
  const stateContent = await node_fs.promises.readFile(statePath$1, "utf-8");
13015
12884
  await node_fs.promises.writeFile(node_path.default.join(archiveDir, "STATE.md"), stateContent, "utf-8");
13016
12885
  }
13017
- const roadmapExists = await pathExistsAsync(roadmapPath$1);
12886
+ const roadmapExists = await pathExistsInternal(roadmapPath$1);
13018
12887
  if (roadmapExists) {
13019
12888
  const roadmapContent = await node_fs.promises.readFile(roadmapPath$1, "utf-8");
13020
12889
  await node_fs.promises.writeFile(node_path.default.join(archiveDir, "ROADMAP.md"), roadmapContent, "utf-8");
@@ -13023,16 +12892,16 @@ async function cmdMilestoneComplete(cwd, version, options) {
13023
12892
  const roadmapContent = await node_fs.promises.readFile(roadmapPath$1, "utf-8");
13024
12893
  await node_fs.promises.writeFile(node_path.default.join(archiveDir, `${version}-ROADMAP.md`), roadmapContent, "utf-8");
13025
12894
  }
13026
- if (await pathExistsAsync(reqPath)) {
12895
+ if (await pathExistsInternal(reqPath)) {
13027
12896
  const reqContent = await node_fs.promises.readFile(reqPath, "utf-8");
13028
12897
  const archiveHeader = `# Requirements Archive: ${version} ${milestoneName}\n\n**Archived:** ${today}\n**Status:** SHIPPED\n\nFor current requirements, see \`.planning/REQUIREMENTS.md\`.\n\n---\n\n`;
13029
12898
  await node_fs.promises.writeFile(node_path.default.join(archiveDir, `${version}-REQUIREMENTS.md`), archiveHeader + reqContent, "utf-8");
13030
12899
  }
13031
12900
  const auditFile = node_path.default.join(cwd, ".planning", `${version}-MILESTONE-AUDIT.md`);
13032
- if (await pathExistsAsync(auditFile)) await node_fs.promises.rename(auditFile, node_path.default.join(archiveDir, `${version}-MILESTONE-AUDIT.md`));
12901
+ if (await pathExistsInternal(auditFile)) await node_fs.promises.rename(auditFile, node_path.default.join(archiveDir, `${version}-MILESTONE-AUDIT.md`));
13033
12902
  const accomplishmentsList = accomplishments.map((a) => `- ${a}`).join("\n");
13034
12903
  const milestoneEntry = `## ${version} ${milestoneName} (Shipped: ${today})\n\n**Phases completed:** ${phaseCount} phases, ${totalPlans} plans, ${totalTasks} tasks\n\n**Key accomplishments:**\n${accomplishmentsList || "- (none recorded)"}\n\n---\n\n`;
13035
- if (await pathExistsAsync(milestonesPath)) {
12904
+ if (await pathExistsInternal(milestonesPath)) {
13036
12905
  const existing = await node_fs.promises.readFile(milestonesPath, "utf-8");
13037
12906
  await node_fs.promises.writeFile(milestonesPath, existing + "\n" + milestoneEntry, "utf-8");
13038
12907
  } else await node_fs.promises.writeFile(milestonesPath, `# Milestones\n\n${milestoneEntry}`, "utf-8");
@@ -13078,7 +12947,7 @@ Last session: ${today}
13078
12947
  if (options.archivePhases) try {
13079
12948
  const phaseArchiveDir = node_path.default.join(archiveDir, "phases");
13080
12949
  await node_fs.promises.mkdir(phaseArchiveDir, { recursive: true });
13081
- const phaseDirNames = await listSubDirsAsync(phasesDir);
12950
+ const phaseDirNames = await listSubDirs(phasesDir);
13082
12951
  for (const dir of phaseDirNames) await node_fs.promises.rename(node_path.default.join(phasesDir, dir), node_path.default.join(phaseArchiveDir, dir));
13083
12952
  phasesArchived = phaseDirNames.length > 0;
13084
12953
  } catch (e) {
@@ -13093,12 +12962,12 @@ Last session: ${today}
13093
12962
  tasks: totalTasks,
13094
12963
  accomplishments,
13095
12964
  archived: {
13096
- roadmap: await pathExistsAsync(node_path.default.join(archiveDir, `${version}-ROADMAP.md`)),
13097
- requirements: await pathExistsAsync(node_path.default.join(archiveDir, `${version}-REQUIREMENTS.md`)),
13098
- audit: await pathExistsAsync(node_path.default.join(archiveDir, `${version}-MILESTONE-AUDIT.md`)),
12965
+ roadmap: await pathExistsInternal(node_path.default.join(archiveDir, `${version}-ROADMAP.md`)),
12966
+ requirements: await pathExistsInternal(node_path.default.join(archiveDir, `${version}-REQUIREMENTS.md`)),
12967
+ audit: await pathExistsInternal(node_path.default.join(archiveDir, `${version}-MILESTONE-AUDIT.md`)),
13099
12968
  phases: phasesArchived,
13100
- state_snapshot: await pathExistsAsync(node_path.default.join(archiveDir, "STATE.md")),
13101
- roadmap_snapshot: await pathExistsAsync(node_path.default.join(archiveDir, "ROADMAP.md"))
12969
+ state_snapshot: await pathExistsInternal(node_path.default.join(archiveDir, "STATE.md")),
12970
+ roadmap_snapshot: await pathExistsInternal(node_path.default.join(archiveDir, "ROADMAP.md"))
13102
12971
  },
13103
12972
  milestones_updated: true,
13104
12973
  state_updated: stateExists,
@@ -13600,7 +13469,7 @@ function cmdVerifyPathExists(cwd, targetPath, raw) {
13600
13469
  }, raw ? "false" : void 0);
13601
13470
  }
13602
13471
  }
13603
- function cmdHistoryDigest(cwd, raw) {
13472
+ async function cmdHistoryDigest(cwd, raw) {
13604
13473
  const phasesDir = phasesPath(cwd);
13605
13474
  const digest = {
13606
13475
  phases: {},
@@ -13608,14 +13477,14 @@ function cmdHistoryDigest(cwd, raw) {
13608
13477
  tech_stack: /* @__PURE__ */ new Set()
13609
13478
  };
13610
13479
  const allPhaseDirs = [];
13611
- const archived = getArchivedPhaseDirs(cwd);
13480
+ const archived = await getArchivedPhaseDirs(cwd);
13612
13481
  for (const a of archived) allPhaseDirs.push({
13613
13482
  name: a.name,
13614
13483
  fullPath: a.fullPath,
13615
13484
  milestone: a.milestone
13616
13485
  });
13617
13486
  if (node_fs.default.existsSync(phasesDir)) try {
13618
- const currentDirs = listSubDirs(phasesDir, true);
13487
+ const currentDirs = await listSubDirs(phasesDir, true);
13619
13488
  for (const dir of currentDirs) allPhaseDirs.push({
13620
13489
  name: dir,
13621
13490
  fullPath: node_path.default.join(phasesDir, dir),
@@ -13675,9 +13544,9 @@ function cmdHistoryDigest(cwd, raw) {
13675
13544
  return cmdErr("Failed to generate history digest: " + e.message);
13676
13545
  }
13677
13546
  }
13678
- function cmdResolveModel(cwd, agentType, raw) {
13547
+ async function cmdResolveModel(cwd, agentType, raw) {
13679
13548
  if (!agentType) return cmdErr("agent-type required");
13680
- const profile = loadConfig(cwd).model_profile || "balanced";
13549
+ const profile = (await loadConfig(cwd)).model_profile || "balanced";
13681
13550
  const agentModels = MODEL_PROFILES[agentType];
13682
13551
  if (!agentModels) return cmdOk({
13683
13552
  model: "sonnet",
@@ -13693,7 +13562,7 @@ function cmdResolveModel(cwd, agentType, raw) {
13693
13562
  }
13694
13563
  async function cmdCommit(cwd, message, files, raw, amend) {
13695
13564
  if (!message && !amend) return cmdErr("commit message required");
13696
- if (!loadConfig(cwd).commit_docs) return cmdOk({
13565
+ if (!(await loadConfig(cwd)).commit_docs) return cmdOk({
13697
13566
  committed: false,
13698
13567
  hash: null,
13699
13568
  reason: "skipped_commit_docs_false"
@@ -13825,9 +13694,9 @@ async function cmdWebsearch(query, options, raw) {
13825
13694
  }, raw ? "" : void 0);
13826
13695
  }
13827
13696
  }
13828
- function cmdProgressRender(cwd, format, raw) {
13697
+ async function cmdProgressRender(cwd, format, raw) {
13829
13698
  const phasesDir = phasesPath(cwd);
13830
- const milestone = getMilestoneInfo(cwd);
13699
+ const milestone = await getMilestoneInfo(cwd);
13831
13700
  const phases = [];
13832
13701
  let totalPlans = 0;
13833
13702
  let totalSummaries = 0;
@@ -13934,11 +13803,11 @@ function cmdTodoComplete(cwd, filename, raw) {
13934
13803
  date: today
13935
13804
  }, raw ? "completed" : void 0);
13936
13805
  }
13937
- function cmdScaffold(cwd, type, options, raw) {
13806
+ async function cmdScaffold(cwd, type, options, raw) {
13938
13807
  const { phase, name } = options;
13939
13808
  const padded = phase ? normalizePhaseName(phase) : "00";
13940
13809
  const today = todayISO();
13941
- const phaseInfo = phase ? findPhaseInternal(cwd, phase) : null;
13810
+ const phaseInfo = phase ? await findPhaseInternal(cwd, phase) : null;
13942
13811
  const phaseDir = phaseInfo ? node_path.default.join(cwd, phaseInfo.directory) : null;
13943
13812
  if (phase && !phaseDir && type !== "phase-dir") return cmdErr(`Phase ${phase} directory not found`);
13944
13813
  let filePath;
@@ -14064,9 +13933,9 @@ async function cmdVerifySummary(cwd, summaryPath, checkFileCount) {
14064
13933
  errors
14065
13934
  }, passed ? "passed" : "failed");
14066
13935
  }
14067
- function cmdVerifyPlanStructure(cwd, filePath) {
13936
+ async function cmdVerifyPlanStructure(cwd, filePath) {
14068
13937
  if (!filePath) return cmdErr("file path required");
14069
- const content = safeReadFile(node_path.default.isAbsolute(filePath) ? filePath : node_path.default.join(cwd, filePath));
13938
+ const content = await safeReadFile(node_path.default.isAbsolute(filePath) ? filePath : node_path.default.join(cwd, filePath));
14070
13939
  if (!content) return cmdOk({
14071
13940
  error: "File not found",
14072
13941
  path: filePath
@@ -14120,9 +13989,9 @@ function cmdVerifyPlanStructure(cwd, filePath) {
14120
13989
  frontmatter_fields: Object.keys(fm)
14121
13990
  }, errors.length === 0 ? "valid" : "invalid");
14122
13991
  }
14123
- function cmdVerifyPhaseCompleteness(cwd, phase) {
13992
+ async function cmdVerifyPhaseCompleteness(cwd, phase) {
14124
13993
  if (!phase) return cmdErr("phase required");
14125
- const phaseInfo = findPhaseInternal(cwd, phase);
13994
+ const phaseInfo = await findPhaseInternal(cwd, phase);
14126
13995
  if (!phaseInfo) return cmdOk({
14127
13996
  error: "Phase not found",
14128
13997
  phase
@@ -14155,9 +14024,9 @@ function cmdVerifyPhaseCompleteness(cwd, phase) {
14155
14024
  warnings
14156
14025
  }, errors.length === 0 ? "complete" : "incomplete");
14157
14026
  }
14158
- function cmdVerifyReferences(cwd, filePath) {
14027
+ async function cmdVerifyReferences(cwd, filePath) {
14159
14028
  if (!filePath) return cmdErr("file path required");
14160
- const content = safeReadFile(node_path.default.isAbsolute(filePath) ? filePath : node_path.default.join(cwd, filePath));
14029
+ const content = await safeReadFile(node_path.default.isAbsolute(filePath) ? filePath : node_path.default.join(cwd, filePath));
14161
14030
  if (!content) return cmdOk({
14162
14031
  error: "File not found",
14163
14032
  path: filePath
@@ -14207,9 +14076,9 @@ async function cmdVerifyCommits(cwd, hashes) {
14207
14076
  total: hashes.length
14208
14077
  }, invalid.length === 0 ? "valid" : "invalid");
14209
14078
  }
14210
- function cmdVerifyArtifacts(cwd, planFilePath) {
14079
+ async function cmdVerifyArtifacts(cwd, planFilePath) {
14211
14080
  if (!planFilePath) return cmdErr("plan file path required");
14212
- const content = safeReadFile(node_path.default.isAbsolute(planFilePath) ? planFilePath : node_path.default.join(cwd, planFilePath));
14081
+ const content = await safeReadFile(node_path.default.isAbsolute(planFilePath) ? planFilePath : node_path.default.join(cwd, planFilePath));
14213
14082
  if (!content) return cmdOk({
14214
14083
  error: "File not found",
14215
14084
  path: planFilePath
@@ -14234,7 +14103,7 @@ function cmdVerifyArtifacts(cwd, planFilePath) {
14234
14103
  passed: false
14235
14104
  };
14236
14105
  if (exists) {
14237
- const fileContent = safeReadFile(artFullPath) || "";
14106
+ const fileContent = await safeReadFile(artFullPath) || "";
14238
14107
  const lineCount = fileContent.split("\n").length;
14239
14108
  if (artObj.min_lines && lineCount < artObj.min_lines) check.issues.push(`Only ${lineCount} lines, need ${artObj.min_lines}`);
14240
14109
  if (artObj.contains && !fileContent.includes(artObj.contains)) check.issues.push(`Missing pattern: ${artObj.contains}`);
@@ -14254,9 +14123,9 @@ function cmdVerifyArtifacts(cwd, planFilePath) {
14254
14123
  artifacts: results
14255
14124
  }, passed === results.length ? "valid" : "invalid");
14256
14125
  }
14257
- function cmdVerifyKeyLinks(cwd, planFilePath) {
14126
+ async function cmdVerifyKeyLinks(cwd, planFilePath) {
14258
14127
  if (!planFilePath) return cmdErr("plan file path required");
14259
- const content = safeReadFile(node_path.default.isAbsolute(planFilePath) ? planFilePath : node_path.default.join(cwd, planFilePath));
14128
+ const content = await safeReadFile(node_path.default.isAbsolute(planFilePath) ? planFilePath : node_path.default.join(cwd, planFilePath));
14260
14129
  if (!content) return cmdOk({
14261
14130
  error: "File not found",
14262
14131
  path: planFilePath
@@ -14277,7 +14146,7 @@ function cmdVerifyKeyLinks(cwd, planFilePath) {
14277
14146
  verified: false,
14278
14147
  detail: ""
14279
14148
  };
14280
- const sourceContent = safeReadFile(node_path.default.join(cwd, linkObj.from || ""));
14149
+ const sourceContent = await safeReadFile(node_path.default.join(cwd, linkObj.from || ""));
14281
14150
  if (!sourceContent) check.detail = "Source file not found";
14282
14151
  else if (linkObj.pattern) try {
14283
14152
  const regex = new RegExp(linkObj.pattern);
@@ -14285,7 +14154,7 @@ function cmdVerifyKeyLinks(cwd, planFilePath) {
14285
14154
  check.verified = true;
14286
14155
  check.detail = "Pattern found in source";
14287
14156
  } else {
14288
- const targetContent = safeReadFile(node_path.default.join(cwd, linkObj.to || ""));
14157
+ const targetContent = await safeReadFile(node_path.default.join(cwd, linkObj.to || ""));
14289
14158
  if (targetContent && regex.test(targetContent)) {
14290
14159
  check.verified = true;
14291
14160
  check.detail = "Pattern found in target";
@@ -14308,7 +14177,7 @@ function cmdVerifyKeyLinks(cwd, planFilePath) {
14308
14177
  links: results
14309
14178
  }, verified === results.length ? "valid" : "invalid");
14310
14179
  }
14311
- function cmdValidateConsistency(cwd) {
14180
+ async function cmdValidateConsistency(cwd) {
14312
14181
  const rmPath = roadmapPath(cwd);
14313
14182
  const phasesDir = phasesPath(cwd);
14314
14183
  const errors = [];
@@ -14328,7 +14197,7 @@ function cmdValidateConsistency(cwd) {
14328
14197
  while ((m = phasePattern.exec(roadmapContent)) !== null) roadmapPhases.add(m[1]);
14329
14198
  const diskPhases = /* @__PURE__ */ new Set();
14330
14199
  try {
14331
- const dirs = listSubDirs(phasesDir);
14200
+ const dirs = await listSubDirs(phasesDir);
14332
14201
  for (const dir of dirs) {
14333
14202
  const dm = dir.match(/^(\d+[A-Z]?(?:\.\d+)?)/i);
14334
14203
  if (dm) diskPhases.add(dm[1]);
@@ -14344,7 +14213,7 @@ function cmdValidateConsistency(cwd) {
14344
14213
  const integerPhases = [...diskPhases].filter((p) => !p.includes(".")).map((p) => parseInt(p, 10)).sort((a, b) => a - b);
14345
14214
  for (let i = 1; i < integerPhases.length; i++) if (integerPhases[i] !== integerPhases[i - 1] + 1) warnings.push(`Gap in phase numbering: ${integerPhases[i - 1]} → ${integerPhases[i]}`);
14346
14215
  try {
14347
- const dirs = listSubDirs(phasesDir, true);
14216
+ const dirs = await listSubDirs(phasesDir, true);
14348
14217
  for (const dir of dirs) {
14349
14218
  const phaseFiles = node_fs.default.readdirSync(node_path.default.join(phasesDir, dir));
14350
14219
  const plans = phaseFiles.filter((f) => isPlanFile(f)).sort();
@@ -14362,7 +14231,7 @@ function cmdValidateConsistency(cwd) {
14362
14231
  debugLog(e);
14363
14232
  }
14364
14233
  try {
14365
- const dirs = listSubDirs(phasesDir);
14234
+ const dirs = await listSubDirs(phasesDir);
14366
14235
  for (const dir of dirs) {
14367
14236
  const plans = node_fs.default.readdirSync(node_path.default.join(phasesDir, dir)).filter((f) => isPlanFile(f));
14368
14237
  for (const plan of plans) if (!extractFrontmatter(node_fs.default.readFileSync(node_path.default.join(phasesDir, dir, plan), "utf-8")).wave) warnings.push(`${dir}/${plan}: missing 'wave' in frontmatter`);
@@ -14378,7 +14247,7 @@ function cmdValidateConsistency(cwd) {
14378
14247
  warning_count: warnings.length
14379
14248
  }, passed ? "passed" : "failed");
14380
14249
  }
14381
- function cmdValidateHealth(cwd, options) {
14250
+ async function cmdValidateHealth(cwd, options) {
14382
14251
  const planningDir = planningPath(cwd);
14383
14252
  const projectPath = planningPath(cwd, "PROJECT.md");
14384
14253
  const rmPath = roadmapPath(cwd);
@@ -14427,7 +14296,7 @@ function cmdValidateHealth(cwd, options) {
14427
14296
  const phaseRefs = [...node_fs.default.readFileSync(stPath, "utf-8").matchAll(/[Pp]hase\s+(\d+(?:\.\d+)?)/g)].map((m) => m[1]);
14428
14297
  const diskPhases = /* @__PURE__ */ new Set();
14429
14298
  try {
14430
- for (const dir of listSubDirs(phasesDir)) {
14299
+ for (const dir of await listSubDirs(phasesDir)) {
14431
14300
  const dm = dir.match(/^(\d+(?:\.\d+)?)/);
14432
14301
  if (dm) diskPhases.add(dm[1]);
14433
14302
  }
@@ -14462,12 +14331,12 @@ function cmdValidateHealth(cwd, options) {
14462
14331
  repairs.push("resetConfig");
14463
14332
  }
14464
14333
  try {
14465
- for (const dirName of listSubDirs(phasesDir)) if (!dirName.match(/^\d{2}(?:\.\d+)?-[\w-]+$/)) addIssue("warning", "W005", `Phase directory "${dirName}" doesn't follow NN-name format`, "Rename to match pattern (e.g., 01-setup)");
14334
+ for (const dirName of await listSubDirs(phasesDir)) if (!dirName.match(/^\d{2}(?:\.\d+)?-[\w-]+$/)) addIssue("warning", "W005", `Phase directory "${dirName}" doesn't follow NN-name format`, "Rename to match pattern (e.g., 01-setup)");
14466
14335
  } catch (e) {
14467
14336
  debugLog(e);
14468
14337
  }
14469
14338
  try {
14470
- const orphanDirs = listSubDirs(phasesDir);
14339
+ const orphanDirs = await listSubDirs(phasesDir);
14471
14340
  for (const dirName of orphanDirs) {
14472
14341
  const phaseFiles = node_fs.default.readdirSync(node_path.default.join(phasesDir, dirName));
14473
14342
  const plans = phaseFiles.filter((f) => isPlanFile(f));
@@ -14489,7 +14358,7 @@ function cmdValidateHealth(cwd, options) {
14489
14358
  while ((m = phasePattern.exec(roadmapContent)) !== null) roadmapPhases.add(m[1]);
14490
14359
  const diskPhases = /* @__PURE__ */ new Set();
14491
14360
  try {
14492
- for (const dir of listSubDirs(phasesDir)) {
14361
+ for (const dir of await listSubDirs(phasesDir)) {
14493
14362
  const dm = dir.match(/^(\d+[A-Z]?(?:\.\d+)?)/i);
14494
14363
  if (dm) diskPhases.add(dm[1]);
14495
14364
  }
@@ -14536,7 +14405,7 @@ function cmdValidateHealth(cwd, options) {
14536
14405
  path: backupPath
14537
14406
  });
14538
14407
  }
14539
- const milestone = getMilestoneInfo(cwd);
14408
+ const milestone = await getMilestoneInfo(cwd);
14540
14409
  let stateContent = `# Session State\n\n`;
14541
14410
  stateContent += `## Project Reference\n\n`;
14542
14411
  stateContent += `See: .planning/PROJECT.md\n\n`;
@@ -14590,8 +14459,8 @@ const DRIFT_REPORT_NAME = "DRIFT-REPORT.md";
14590
14459
  * Read the drift report from .planning/DRIFT-REPORT.md.
14591
14460
  * Returns parsed frontmatter and body content, or structured error if not found.
14592
14461
  */
14593
- function cmdDriftReadReport(cwd) {
14594
- const content = safeReadFile(planningPath(cwd, DRIFT_REPORT_NAME));
14462
+ async function cmdDriftReadReport(cwd) {
14463
+ const content = await safeReadFile(planningPath(cwd, DRIFT_REPORT_NAME));
14595
14464
  if (!content) return cmdOk({
14596
14465
  found: false,
14597
14466
  path: `.planning/${DRIFT_REPORT_NAME}`,
@@ -14611,10 +14480,10 @@ function cmdDriftReadReport(cwd) {
14611
14480
  * Write content to .planning/DRIFT-REPORT.md.
14612
14481
  * Supports direct content or reading from a file (tmpfile pattern for large reports).
14613
14482
  */
14614
- function cmdDriftWriteReport(cwd, content, contentFile) {
14483
+ async function cmdDriftWriteReport(cwd, content, contentFile) {
14615
14484
  let reportContent;
14616
14485
  if (contentFile) {
14617
- const fileContent = safeReadFile(node_path.default.isAbsolute(contentFile) ? contentFile : node_path.default.join(cwd, contentFile));
14486
+ const fileContent = await safeReadFile(node_path.default.isAbsolute(contentFile) ? contentFile : node_path.default.join(cwd, contentFile));
14618
14487
  if (!fileContent) return cmdErr(`Content file not found: ${contentFile}`);
14619
14488
  reportContent = fileContent;
14620
14489
  } else if (content) reportContent = content;
@@ -14637,8 +14506,8 @@ function cmdDriftWriteReport(cwd, content, contentFile) {
14637
14506
  * Extract all requirements from .planning/REQUIREMENTS.md.
14638
14507
  * Parses requirement lines matching `- [ ] **ID**: description` or `- [x] **ID**: description`.
14639
14508
  */
14640
- function cmdDriftExtractRequirements(cwd) {
14641
- const content = safeReadFile(planningPath(cwd, "REQUIREMENTS.md"));
14509
+ async function cmdDriftExtractRequirements(cwd) {
14510
+ const content = await safeReadFile(planningPath(cwd, "REQUIREMENTS.md"));
14642
14511
  if (!content) return cmdOk({
14643
14512
  found: false,
14644
14513
  path: ".planning/REQUIREMENTS.md",
@@ -14666,8 +14535,8 @@ function cmdDriftExtractRequirements(cwd) {
14666
14535
  * Extract no-go rules from .planning/NO-GOS.md.
14667
14536
  * Returns array of no-go items with section context, or empty if file missing.
14668
14537
  */
14669
- function cmdDriftExtractNoGos(cwd) {
14670
- const content = safeReadFile(planningPath(cwd, "NO-GOS.md"));
14538
+ async function cmdDriftExtractNoGos(cwd) {
14539
+ const content = await safeReadFile(planningPath(cwd, "NO-GOS.md"));
14671
14540
  if (!content) return cmdOk({
14672
14541
  found: false,
14673
14542
  path: ".planning/NO-GOS.md",
@@ -14704,8 +14573,8 @@ function cmdDriftExtractNoGos(cwd) {
14704
14573
  * Read .planning/CONVENTIONS.md and return its full content.
14705
14574
  * Returns the raw content for agent analysis, or null if missing.
14706
14575
  */
14707
- function cmdDriftExtractConventions(cwd) {
14708
- const content = safeReadFile(planningPath(cwd, "CONVENTIONS.md"));
14576
+ async function cmdDriftExtractConventions(cwd) {
14577
+ const content = await safeReadFile(planningPath(cwd, "CONVENTIONS.md"));
14709
14578
  if (!content) return cmdOk({
14710
14579
  found: false,
14711
14580
  path: ".planning/CONVENTIONS.md",
@@ -14721,8 +14590,8 @@ function cmdDriftExtractConventions(cwd) {
14721
14590
  * Read existing DRIFT-REPORT.md frontmatter for diff tracking.
14722
14591
  * Returns previous_hash and checked date, or null if no report exists.
14723
14592
  */
14724
- function cmdDriftPreviousHash(cwd) {
14725
- const content = safeReadFile(planningPath(cwd, DRIFT_REPORT_NAME));
14593
+ async function cmdDriftPreviousHash(cwd) {
14594
+ const content = await safeReadFile(planningPath(cwd, DRIFT_REPORT_NAME));
14726
14595
  if (!content) return cmdOk({
14727
14596
  found: false,
14728
14597
  hash: null,
@@ -14799,7 +14668,7 @@ async function phaseInsertCore(cwd, afterPhase, description, options) {
14799
14668
  const normalizedBase = normalizePhaseName(afterPhase);
14800
14669
  const existingDecimals = [];
14801
14670
  try {
14802
- const dirs = await listSubDirsAsync(phasesDirPath);
14671
+ const dirs = await listSubDirs(phasesDirPath);
14803
14672
  const decimalPattern = new RegExp(`^${normalizedBase}\\.(\\d+)`);
14804
14673
  for (const dir of dirs) {
14805
14674
  const dm = dir.match(decimalPattern);
@@ -14838,12 +14707,12 @@ async function phaseCompleteCore(cwd, phaseNum) {
14838
14707
  const stPath = statePath(cwd);
14839
14708
  const phasesDirPath = phasesPath(cwd);
14840
14709
  const today = todayISO();
14841
- const phaseInfo = await findPhaseInternalAsync(cwd, phaseNum);
14710
+ const phaseInfo = await findPhaseInternal(cwd, phaseNum);
14842
14711
  if (!phaseInfo) throw new Error(`Phase ${phaseNum} not found`);
14843
14712
  const planCount = phaseInfo.plans.length;
14844
14713
  const summaryCount = phaseInfo.summaries.length;
14845
14714
  let requirementsUpdated = false;
14846
- const rmExists = await pathExistsAsync(rmPath);
14715
+ const rmExists = await pathExistsInternal(rmPath);
14847
14716
  if (rmExists) {
14848
14717
  let roadmapContent = await node_fs.promises.readFile(rmPath, "utf-8");
14849
14718
  const checkboxPattern = new RegExp(`(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${escapePhaseNum(phaseNum)}[:\\s][^\\n]*)`, "i");
@@ -14857,7 +14726,7 @@ async function phaseCompleteCore(cwd, phaseNum) {
14857
14726
  await node_fs.promises.writeFile(rmPath, roadmapContent, "utf-8");
14858
14727
  debugLog("phase-complete-write", `ROADMAP.md updated for phase ${phaseNum}`);
14859
14728
  const reqPath = planningPath(cwd, "REQUIREMENTS.md");
14860
- if (await pathExistsAsync(reqPath)) {
14729
+ if (await pathExistsInternal(reqPath)) {
14861
14730
  const reqMatch = roadmapContent.match(new RegExp(`Phase\\s+${escapePhaseNum(phaseNum)}[\\s\\S]*?\\*\\*Requirements:\\*\\*\\s*([^\\n]+)`, "i"));
14862
14731
  if (reqMatch) {
14863
14732
  const reqIds = reqMatch[1].replace(/[\[\]]/g, "").split(/[,\s]+/).map((r) => r.trim()).filter(Boolean);
@@ -14877,7 +14746,7 @@ async function phaseCompleteCore(cwd, phaseNum) {
14877
14746
  let nextPhaseName = null;
14878
14747
  let isLastPhase = true;
14879
14748
  try {
14880
- const dirs = await listSubDirsAsync(phasesDirPath, true);
14749
+ const dirs = await listSubDirs(phasesDirPath, true);
14881
14750
  for (const dir of dirs) {
14882
14751
  const dm = dir.match(/^(\d+[A-Z]?(?:\.\d+)?)-?(.*)/i);
14883
14752
  if (dm) {
@@ -14892,7 +14761,7 @@ async function phaseCompleteCore(cwd, phaseNum) {
14892
14761
  } catch (e) {
14893
14762
  debugLog("phase-complete-next-phase-scan-failed", e);
14894
14763
  }
14895
- const stExists = await pathExistsAsync(stPath);
14764
+ const stExists = await pathExistsInternal(stPath);
14896
14765
  if (stExists) {
14897
14766
  let stateContent = await node_fs.promises.readFile(stPath, "utf-8");
14898
14767
  stateContent = stateContent.replace(/(\*\*Current Phase:\*\*\s*).*/, `$1${nextPhaseNum || phaseNum}`);
@@ -14921,7 +14790,7 @@ async function phaseCompleteCore(cwd, phaseNum) {
14921
14790
  async function cmdPhasesList(cwd, options) {
14922
14791
  const phasesDirPath = phasesPath(cwd);
14923
14792
  const { type, phase, includeArchived, offset, limit } = options;
14924
- if (!await pathExistsAsync(phasesDirPath)) if (type) return cmdOk({
14793
+ if (!await pathExistsInternal(phasesDirPath)) if (type) return cmdOk({
14925
14794
  files: [],
14926
14795
  count: 0,
14927
14796
  total: 0
@@ -14932,9 +14801,9 @@ async function cmdPhasesList(cwd, options) {
14932
14801
  total: 0
14933
14802
  }, "");
14934
14803
  try {
14935
- let dirs = await listSubDirsAsync(phasesDirPath);
14804
+ let dirs = await listSubDirs(phasesDirPath);
14936
14805
  if (includeArchived) {
14937
- const archived = await getArchivedPhaseDirsAsync(cwd);
14806
+ const archived = await getArchivedPhaseDirs(cwd);
14938
14807
  for (const a of archived) dirs.push(`${a.name} [${a.milestone}]`);
14939
14808
  }
14940
14809
  dirs.sort((a, b) => comparePhaseNum(a, b));
@@ -14982,14 +14851,14 @@ async function cmdPhasesList(cwd, options) {
14982
14851
  async function cmdPhaseNextDecimal(cwd, basePhase) {
14983
14852
  const phasesDirPath = phasesPath(cwd);
14984
14853
  const normalized = normalizePhaseName(basePhase);
14985
- if (!await pathExistsAsync(phasesDirPath)) return cmdOk({
14854
+ if (!await pathExistsInternal(phasesDirPath)) return cmdOk({
14986
14855
  found: false,
14987
14856
  base_phase: normalized,
14988
14857
  next: `${normalized}.1`,
14989
14858
  existing: []
14990
14859
  }, `${normalized}.1`);
14991
14860
  try {
14992
- const dirs = await listSubDirsAsync(phasesDirPath);
14861
+ const dirs = await listSubDirs(phasesDirPath);
14993
14862
  const baseExists = dirs.some((d) => d.startsWith(normalized + "-") || d === normalized);
14994
14863
  const decimalPattern = new RegExp(`^${normalized}\\.(\\d+)`);
14995
14864
  const existingDecimals = [];
@@ -15029,7 +14898,7 @@ async function cmdFindPhase(cwd, phase) {
15029
14898
  summaries: []
15030
14899
  };
15031
14900
  try {
15032
- const match = (await listSubDirsAsync(phasesDirPath, true)).find((d) => d.startsWith(normalized));
14901
+ const match = (await listSubDirs(phasesDirPath, true)).find((d) => d.startsWith(normalized));
15033
14902
  if (!match) return cmdOk(notFound, "");
15034
14903
  const dirMatch = match.match(/^(\d+[A-Z]?(?:\.\d+)?)-?(.*)/i);
15035
14904
  const phaseNumber = dirMatch ? dirMatch[1] : normalized;
@@ -15057,7 +14926,7 @@ async function cmdPhasePlanIndex(cwd, phase) {
15057
14926
  const normalized = normalizePhaseName(phase);
15058
14927
  let phaseDir = null;
15059
14928
  try {
15060
- const match = (await listSubDirsAsync(phasesDirPath, true)).find((d) => d.startsWith(normalized));
14929
+ const match = (await listSubDirs(phasesDirPath, true)).find((d) => d.startsWith(normalized));
15061
14930
  if (match) phaseDir = node_path.default.join(phasesDirPath, match);
15062
14931
  } catch (e) {
15063
14932
  debugLog("phase-plan-index-failed", e);
@@ -15150,12 +15019,12 @@ async function cmdPhaseRemove(cwd, targetPhase, options) {
15150
15019
  const rmPath = roadmapPath(cwd);
15151
15020
  const phasesDirPath = phasesPath(cwd);
15152
15021
  const force = options.force || false;
15153
- if (!await pathExistsAsync(rmPath)) return cmdErr("ROADMAP.md not found");
15022
+ if (!await pathExistsInternal(rmPath)) return cmdErr("ROADMAP.md not found");
15154
15023
  const normalized = normalizePhaseName(targetPhase);
15155
15024
  const isDecimal = targetPhase.includes(".");
15156
15025
  let targetDir = null;
15157
15026
  try {
15158
- targetDir = (await listSubDirsAsync(phasesDirPath, true)).find((d) => d.startsWith(normalized + "-") || d === normalized) || null;
15027
+ targetDir = (await listSubDirs(phasesDirPath, true)).find((d) => d.startsWith(normalized + "-") || d === normalized) || null;
15159
15028
  } catch (e) {
15160
15029
  debugLog("phase-remove-find-target-failed", e);
15161
15030
  }
@@ -15175,7 +15044,7 @@ async function cmdPhaseRemove(cwd, targetPhase, options) {
15175
15044
  const baseInt = baseParts[0];
15176
15045
  const removedDecimal = parseInt(baseParts[1], 10);
15177
15046
  try {
15178
- const dirs = await listSubDirsAsync(phasesDirPath, true);
15047
+ const dirs = await listSubDirs(phasesDirPath, true);
15179
15048
  const decPattern = new RegExp(`^${baseInt}\\.(\\d+)-(.+)$`);
15180
15049
  const toRename = [];
15181
15050
  for (const dir of dirs) {
@@ -15216,7 +15085,7 @@ async function cmdPhaseRemove(cwd, targetPhase, options) {
15216
15085
  } else {
15217
15086
  const removedInt = parseInt(normalized, 10);
15218
15087
  try {
15219
- const dirs = await listSubDirsAsync(phasesDirPath, true);
15088
+ const dirs = await listSubDirs(phasesDirPath, true);
15220
15089
  const toRename = [];
15221
15090
  for (const dir of dirs) {
15222
15091
  const dm = dir.match(/^(\d+)([A-Z])?(?:\.(\d+))?-(.+)$/i);
@@ -15290,7 +15159,7 @@ async function cmdPhaseRemove(cwd, targetPhase, options) {
15290
15159
  }
15291
15160
  await node_fs.promises.writeFile(rmPath, roadmapContent, "utf-8");
15292
15161
  const stPath = statePath(cwd);
15293
- const stExists = await pathExistsAsync(stPath);
15162
+ const stExists = await pathExistsInternal(stPath);
15294
15163
  if (stExists) {
15295
15164
  let stateContent = await node_fs.promises.readFile(stPath, "utf-8");
15296
15165
  const totalPattern = /(\*\*Total Phases:\*\*\s*)(\d+)/;
@@ -15348,15 +15217,15 @@ function findPhaseTaggedLines(content, sectionPattern, phaseNum) {
15348
15217
  const DECISIONS_SECTION_PATTERN = /(#{2,3}\s*(?:Decisions|Decisions Made|Accumulated.*Decisions)\s*\n)([\s\S]*?)(?=\n#{2,3}\s|\n##[^#]|$)/i;
15349
15218
  const BLOCKERS_SECTION_PATTERN = /(#{2,3}\s*(?:Blockers|Blockers\/Concerns|Concerns)\s*\n\s*\n?)([\s\S]*?)(?=\n#{2,3}\s|$)/i;
15350
15219
  async function archivePhasePreview(cwd, phaseNum, outcomeSummary) {
15351
- const phaseInfo = await findPhaseInternalAsync(cwd, phaseNum);
15220
+ const phaseInfo = await findPhaseInternal(cwd, phaseNum);
15352
15221
  if (!phaseInfo) return cmdErr(`Phase ${phaseNum} not found`);
15353
- const archiveDir = await archivePathAsync(cwd);
15222
+ const archiveDir = await archivePath(cwd);
15354
15223
  const phaseDirName = node_path.default.basename(phaseInfo.directory);
15355
15224
  const archiveDest = node_path.default.join(archiveDir, phaseDirName);
15356
- const stContent = await safeReadFileAsync(statePath(cwd)) ?? "";
15225
+ const stContent = await safeReadFile(statePath(cwd)) ?? "";
15357
15226
  const decisionsToRemove = findPhaseTaggedLines(stContent, DECISIONS_SECTION_PATTERN, phaseNum);
15358
15227
  const blockersToRemove = findPhaseTaggedLines(stContent, BLOCKERS_SECTION_PATTERN, phaseNum);
15359
- const rmContent = await safeReadFileAsync(roadmapPath(cwd)) ?? "";
15228
+ const rmContent = await safeReadFile(roadmapPath(cwd)) ?? "";
15360
15229
  const escaped = escapePhaseNum(phaseNum);
15361
15230
  const sectionPattern = new RegExp(`#{2,4}\\s*Phase\\s+${escaped}\\s*:[\\s\\S]*?(?=\\n#{2,4}\\s+Phase\\s+\\d|\\n## |$)`, "i");
15362
15231
  const sectionMatch = rmContent.match(sectionPattern);
@@ -15384,9 +15253,9 @@ function pruneSection(content, sectionPattern, phaseNum) {
15384
15253
  return content.replace(sectionPattern, (_m, header) => `${header}${newBody}`);
15385
15254
  }
15386
15255
  async function archivePhaseExecute(cwd, phaseNum, outcomeSummary) {
15387
- const phaseInfo = await findPhaseInternalAsync(cwd, phaseNum);
15256
+ const phaseInfo = await findPhaseInternal(cwd, phaseNum);
15388
15257
  if (!phaseInfo) return cmdErr(`Phase ${phaseNum} not found`);
15389
- const archiveDir = await archivePathAsync(cwd);
15258
+ const archiveDir = await archivePath(cwd);
15390
15259
  const phaseDirName = node_path.default.basename(phaseInfo.directory);
15391
15260
  const archiveDest = node_path.default.join(archiveDir, phaseDirName);
15392
15261
  const phaseDirFull = node_path.default.join(cwd, phaseInfo.directory);
@@ -15404,14 +15273,14 @@ async function archivePhaseExecute(cwd, phaseNum, outcomeSummary) {
15404
15273
  } else throw e;
15405
15274
  }
15406
15275
  const stPath = statePath(cwd);
15407
- let stContent = await safeReadFileAsync(stPath);
15276
+ let stContent = await safeReadFile(stPath);
15408
15277
  if (stContent) {
15409
15278
  stContent = pruneSection(stContent, DECISIONS_SECTION_PATTERN, phaseNum);
15410
15279
  stContent = pruneSection(stContent, BLOCKERS_SECTION_PATTERN, phaseNum);
15411
15280
  await node_fs.promises.writeFile(stPath, stContent, "utf-8");
15412
15281
  }
15413
15282
  const rmPath = roadmapPath(cwd);
15414
- let rmContent = await safeReadFileAsync(rmPath);
15283
+ let rmContent = await safeReadFile(rmPath);
15415
15284
  if (rmContent) {
15416
15285
  const escaped = escapePhaseNum(phaseNum);
15417
15286
  const sectionPattern = new RegExp(`\\n?#{2,4}\\s*Phase\\s+${escaped}\\s*:[\\s\\S]*?(?=\\n#{2,4}\\s+Phase\\s+\\d|\\n## |$)`, "i");
@@ -15436,7 +15305,7 @@ async function archivePhaseExecute(cwd, phaseNum, outcomeSummary) {
15436
15305
  archived: true,
15437
15306
  phase: phaseNum,
15438
15307
  archive_path: node_path.default.relative(cwd, archiveDest).replace(/\\/g, "/"),
15439
- decisions_pruned: findPhaseTaggedLines(await safeReadFileAsync(statePath(cwd)) ?? "", DECISIONS_SECTION_PATTERN, phaseNum).length === 0,
15308
+ decisions_pruned: findPhaseTaggedLines(await safeReadFile(statePath(cwd)) ?? "", DECISIONS_SECTION_PATTERN, phaseNum).length === 0,
15440
15309
  blockers_pruned: true,
15441
15310
  roadmap_collapsed: true
15442
15311
  });
@@ -15447,7 +15316,7 @@ async function cmdGetArchivedPhase(cwd, phaseNum) {
15447
15316
  const found = await searchArchiveLocations(planningPath(cwd, "archive"), normalized);
15448
15317
  if (found) return cmdOk(found);
15449
15318
  const milestonesDir = planningPath(cwd, "milestones");
15450
- if (await pathExistsAsync(milestonesDir)) try {
15319
+ if (await pathExistsInternal(milestonesDir)) try {
15451
15320
  const phaseDirs = (await node_fs.promises.readdir(milestonesDir, { withFileTypes: true })).filter((e) => e.isDirectory() && /^v[\d.]+-phases$/.test(e.name)).map((e) => e.name).sort().reverse();
15452
15321
  for (const archiveName of phaseDirs) {
15453
15322
  const result = await searchForPhaseInDir(node_path.default.join(milestonesDir, archiveName), normalized, archiveName);
@@ -15459,7 +15328,7 @@ async function cmdGetArchivedPhase(cwd, phaseNum) {
15459
15328
  return cmdErr(`Phase ${phaseNum} not found in archive`);
15460
15329
  }
15461
15330
  async function searchArchiveLocations(archiveDir, normalized) {
15462
- if (!await pathExistsAsync(archiveDir)) return null;
15331
+ if (!await pathExistsInternal(archiveDir)) return null;
15463
15332
  try {
15464
15333
  const versionDirs = (await node_fs.promises.readdir(archiveDir, { withFileTypes: true })).filter((e) => e.isDirectory()).map((e) => e.name).sort().reverse();
15465
15334
  for (const versionName of versionDirs) {
@@ -15473,7 +15342,7 @@ async function searchArchiveLocations(archiveDir, normalized) {
15473
15342
  }
15474
15343
  async function searchForPhaseInDir(baseDir, normalized, milestone) {
15475
15344
  try {
15476
- const match = (await listSubDirsAsync(baseDir, true)).find((d) => d.startsWith(normalized));
15345
+ const match = (await listSubDirs(baseDir, true)).find((d) => d.startsWith(normalized));
15477
15346
  if (!match) return null;
15478
15347
  const phaseDir = node_path.default.join(baseDir, match);
15479
15348
  const mdFiles = (await node_fs.promises.readdir(phaseDir)).filter((f) => f.endsWith(".md"));
@@ -15535,10 +15404,10 @@ function cmdTemplateSelect(cwd, planPath) {
15535
15404
  }, "templates/summary-standard.md");
15536
15405
  }
15537
15406
  }
15538
- function cmdTemplateFill(cwd, templateType, options) {
15407
+ async function cmdTemplateFill(cwd, templateType, options) {
15539
15408
  if (!templateType) return cmdErr("template type required: summary, plan, or verification");
15540
15409
  if (!options.phase) return cmdErr("--phase required");
15541
- const phaseInfo = findPhaseInternal(cwd, options.phase);
15410
+ const phaseInfo = await findPhaseInternal(cwd, options.phase);
15542
15411
  if (!phaseInfo) return cmdOk({
15543
15412
  error: "Phase not found",
15544
15413
  phase: options.phase
@@ -15721,10 +15590,10 @@ const ARTEFAKT_FILES = {
15721
15590
  function isValidType(type) {
15722
15591
  return !!type && type in ARTEFAKT_FILES;
15723
15592
  }
15724
- function resolveArtefaktPath(cwd, type, phase) {
15593
+ async function resolveArtefaktPath(cwd, type, phase) {
15725
15594
  const filename = ARTEFAKT_FILES[type];
15726
15595
  if (phase) {
15727
- const phaseInfo = findPhaseInternal(cwd, phase);
15596
+ const phaseInfo = await findPhaseInternal(cwd, phase);
15728
15597
  if (!phaseInfo?.directory) return null;
15729
15598
  return node_path.default.join(cwd, phaseInfo.directory, filename);
15730
15599
  }
@@ -15735,8 +15604,8 @@ const TEMPLATE_FILES = {
15735
15604
  "acceptance-criteria": "acceptance-criteria.md",
15736
15605
  "no-gos": "no-gos.md"
15737
15606
  };
15738
- function getTemplate(type) {
15739
- const content = safeReadFile(node_path.default.join(node_os.default.homedir(), ".claude", "maxsim", "templates", TEMPLATE_FILES[type]));
15607
+ async function getTemplate(type) {
15608
+ const content = await safeReadFile(node_path.default.join(node_os.default.homedir(), ".claude", "maxsim", "templates", TEMPLATE_FILES[type]));
15740
15609
  if (content) return content.replace(/\{\{date\}\}/g, todayISO());
15741
15610
  return getHardcodedTemplate(type);
15742
15611
  }
@@ -15748,11 +15617,11 @@ function getHardcodedTemplate(type) {
15748
15617
  case "no-gos": return `# No-Gos\n\n> Things explicitly out of scope or forbidden.\n\n**Created:** ${today}\n\n## Boundaries\n\n- _No entries yet._\n`;
15749
15618
  }
15750
15619
  }
15751
- function cmdArtefakteRead(cwd, type, phase, raw) {
15620
+ async function cmdArtefakteRead(cwd, type, phase, raw) {
15752
15621
  if (!isValidType(type)) return cmdErr(`Invalid artefakt type: ${type}. Available: ${Object.keys(ARTEFAKT_FILES).join(", ")}`);
15753
- const filePath = resolveArtefaktPath(cwd, type, phase);
15622
+ const filePath = await resolveArtefaktPath(cwd, type, phase);
15754
15623
  if (!filePath) return cmdErr(`Phase ${phase} not found`);
15755
- const content = safeReadFile(filePath);
15624
+ const content = await safeReadFile(filePath);
15756
15625
  if (content === null) return cmdOk({
15757
15626
  exists: false,
15758
15627
  type,
@@ -15766,10 +15635,10 @@ function cmdArtefakteRead(cwd, type, phase, raw) {
15766
15635
  content
15767
15636
  }, raw ? content : void 0);
15768
15637
  }
15769
- function cmdArtefakteWrite(cwd, type, content, phase, raw) {
15638
+ async function cmdArtefakteWrite(cwd, type, content, phase, raw) {
15770
15639
  if (!isValidType(type)) return cmdErr(`Invalid artefakt type: ${type}. Available: ${Object.keys(ARTEFAKT_FILES).join(", ")}`);
15771
- const fileContent = content ?? getTemplate(type);
15772
- const filePath = resolveArtefaktPath(cwd, type, phase);
15640
+ const fileContent = content ?? await getTemplate(type);
15641
+ const filePath = await resolveArtefaktPath(cwd, type, phase);
15773
15642
  if (!filePath) return cmdErr(`Phase ${phase} not found`);
15774
15643
  node_fs.default.mkdirSync(node_path.default.dirname(filePath), { recursive: true });
15775
15644
  node_fs.default.writeFileSync(filePath, fileContent, "utf-8");
@@ -15781,13 +15650,13 @@ function cmdArtefakteWrite(cwd, type, content, phase, raw) {
15781
15650
  path: relPath
15782
15651
  }, raw ? relPath : void 0);
15783
15652
  }
15784
- function cmdArtefakteAppend(cwd, type, entry, phase, raw) {
15653
+ async function cmdArtefakteAppend(cwd, type, entry, phase, raw) {
15785
15654
  if (!entry) return cmdErr("entry required for artefakte append");
15786
15655
  if (!isValidType(type)) return cmdErr(`Invalid artefakt type: ${type}. Available: ${Object.keys(ARTEFAKT_FILES).join(", ")}`);
15787
- const filePath = resolveArtefaktPath(cwd, type, phase);
15656
+ const filePath = await resolveArtefaktPath(cwd, type, phase);
15788
15657
  if (!filePath) return cmdErr(`Phase ${phase} not found`);
15789
- let fileContent = safeReadFile(filePath);
15790
- if (fileContent === null) fileContent = getTemplate(type);
15658
+ let fileContent = await safeReadFile(filePath);
15659
+ if (fileContent === null) fileContent = await getTemplate(type);
15791
15660
  fileContent = fileContent.replace(/^-\s*_No entries yet\._\s*$/m, "");
15792
15661
  const today = todayISO();
15793
15662
  let appendLine;
@@ -15805,12 +15674,12 @@ function cmdArtefakteAppend(cwd, type, entry, phase, raw) {
15805
15674
  path: relPath
15806
15675
  }, raw ? "true" : void 0);
15807
15676
  }
15808
- function cmdArtefakteList(cwd, phase, raw) {
15677
+ async function cmdArtefakteList(cwd, phase, raw) {
15809
15678
  const results = [];
15810
15679
  for (const [type, filename] of Object.entries(ARTEFAKT_FILES)) {
15811
15680
  let filePath;
15812
15681
  if (phase) {
15813
- const phaseInfo = findPhaseInternal(cwd, phase);
15682
+ const phaseInfo = await findPhaseInternal(cwd, phase);
15814
15683
  if (!phaseInfo?.directory) return cmdOk({ error: `Phase ${phase} not found` });
15815
15684
  filePath = node_path.default.join(cwd, phaseInfo.directory, filename);
15816
15685
  } else filePath = planningPath(cwd, filename);
@@ -15893,9 +15762,9 @@ function loadRoadmapContext(cwd) {
15893
15762
  addIfExists(files, cwd, ".planning/ROADMAP.md", "roadmap");
15894
15763
  return files;
15895
15764
  }
15896
- function loadPhaseContext(cwd, phase) {
15765
+ async function loadPhaseContext(cwd, phase) {
15897
15766
  const files = [];
15898
- const phaseInfo = findPhaseInternal(cwd, phase);
15767
+ const phaseInfo = await findPhaseInternal(cwd, phase);
15899
15768
  if (!phaseInfo?.directory) return files;
15900
15769
  const phaseDir = phaseInfo.directory;
15901
15770
  try {
@@ -15913,7 +15782,7 @@ function loadPhaseContext(cwd, phase) {
15913
15782
  }
15914
15783
  return files;
15915
15784
  }
15916
- function loadArtefakteContext(cwd, phase) {
15785
+ async function loadArtefakteContext(cwd, phase) {
15917
15786
  const files = [];
15918
15787
  for (const filename of [
15919
15788
  "DECISIONS.md",
@@ -15921,7 +15790,7 @@ function loadArtefakteContext(cwd, phase) {
15921
15790
  "NO-GOS.md"
15922
15791
  ]) {
15923
15792
  if (phase) {
15924
- const phaseInfo = findPhaseInternal(cwd, phase);
15793
+ const phaseInfo = await findPhaseInternal(cwd, phase);
15925
15794
  if (phaseInfo?.directory) addIfExists(files, cwd, node_path.default.join(phaseInfo.directory, filename), `artefakt-${filename.toLowerCase()}`);
15926
15795
  }
15927
15796
  addIfExists(files, cwd, `.planning/${filename}`, `artefakt-${filename.toLowerCase()}`);
@@ -15938,11 +15807,11 @@ function loadCodebaseContext(cwd, topic) {
15938
15807
  } catch {}
15939
15808
  return files;
15940
15809
  }
15941
- function loadHistoryContext(cwd, currentPhase) {
15810
+ async function loadHistoryContext(cwd, currentPhase) {
15942
15811
  const files = [];
15943
15812
  const pd = phasesPath(cwd);
15944
15813
  try {
15945
- const dirs = listSubDirs(pd, true);
15814
+ const dirs = await listSubDirs(pd, true);
15946
15815
  for (const dir of dirs) {
15947
15816
  if (currentPhase) {
15948
15817
  if (dir.match(/^(\d+[A-Z]?(?:\.\d+)?)/i)?.[1] === currentPhase) continue;
@@ -15956,15 +15825,15 @@ function loadHistoryContext(cwd, currentPhase) {
15956
15825
  }
15957
15826
  return files;
15958
15827
  }
15959
- function cmdContextLoad(cwd, phase, topic, includeHistory) {
15828
+ async function cmdContextLoad(cwd, phase, topic, includeHistory) {
15960
15829
  const allFiles = [];
15961
15830
  allFiles.push(...loadProjectContext(cwd));
15962
15831
  allFiles.push(...loadRoadmapContext(cwd));
15963
- allFiles.push(...loadArtefakteContext(cwd, phase));
15832
+ allFiles.push(...await loadArtefakteContext(cwd, phase));
15964
15833
  const selectedDocs = selectCodebaseDocs(topic);
15965
15834
  allFiles.push(...loadCodebaseContext(cwd, topic));
15966
- if (phase) allFiles.push(...loadPhaseContext(cwd, phase));
15967
- if (includeHistory) allFiles.push(...loadHistoryContext(cwd, phase));
15835
+ if (phase) allFiles.push(...await loadPhaseContext(cwd, phase));
15836
+ if (includeHistory) allFiles.push(...await loadHistoryContext(cwd, phase));
15968
15837
  const seen = /* @__PURE__ */ new Set();
15969
15838
  const deduped = allFiles.filter((f) => {
15970
15839
  if (seen.has(f.path)) return false;
@@ -16005,8 +15874,8 @@ function skillsTemplateDir() {
16005
15874
  /**
16006
15875
  * Read a single skill's metadata from its SKILL.md frontmatter.
16007
15876
  */
16008
- function readSkillInfo(skillDir, dirName) {
16009
- const content = safeReadFile(node_path.default.join(skillDir, "SKILL.md"));
15877
+ async function readSkillInfo(skillDir, dirName) {
15878
+ const content = await safeReadFile(node_path.default.join(skillDir, "SKILL.md"));
16010
15879
  if (!content) return null;
16011
15880
  const fm = extractFrontmatter(content);
16012
15881
  return {
@@ -16018,7 +15887,7 @@ function readSkillInfo(skillDir, dirName) {
16018
15887
  /**
16019
15888
  * List all installed skills from `.claude/skills/`.
16020
15889
  */
16021
- function cmdSkillList(cwd) {
15890
+ async function cmdSkillList(cwd) {
16022
15891
  const dir = skillsDir(cwd);
16023
15892
  if (!node_fs.default.existsSync(dir)) return cmdOk({
16024
15893
  skills: [],
@@ -16028,7 +15897,7 @@ function cmdSkillList(cwd) {
16028
15897
  const skills = [];
16029
15898
  for (const entry of entries) {
16030
15899
  if (!entry.isDirectory()) continue;
16031
- const info = readSkillInfo(node_path.default.join(dir, entry.name), entry.name);
15900
+ const info = await readSkillInfo(node_path.default.join(dir, entry.name), entry.name);
16032
15901
  if (info) skills.push(info);
16033
15902
  }
16034
15903
  return cmdOk({
@@ -16104,268 +15973,6 @@ function listAvailableTemplates() {
16104
15973
  return node_fs.default.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
16105
15974
  }
16106
15975
 
16107
- //#endregion
16108
- //#region src/core/dashboard-launcher.ts
16109
- /**
16110
- * Dashboard Launcher — Shared dashboard lifecycle utilities
16111
- *
16112
- * Used by both cli.ts (tool-router) and install.ts (npx entry point).
16113
- */
16114
- const DEFAULT_PORT = 3333;
16115
- const PORT_RANGE_END = 3343;
16116
- const HEALTH_TIMEOUT_MS = 1e4;
16117
- /**
16118
- * Check if a dashboard health endpoint is responding on the given port.
16119
- */
16120
- async function checkHealth(port, timeoutMs = HEALTH_TIMEOUT_MS) {
16121
- try {
16122
- const controller = new AbortController();
16123
- const timer = setTimeout(() => controller.abort(), timeoutMs);
16124
- const res = await fetch(`http://localhost:${port}/api/health`, { signal: controller.signal });
16125
- clearTimeout(timer);
16126
- if (res.ok) return (await res.json()).status === "ok";
16127
- return false;
16128
- } catch (e) {
16129
- debugLog("health-check-failed", {
16130
- port,
16131
- error: errorMsg(e)
16132
- });
16133
- return false;
16134
- }
16135
- }
16136
- /**
16137
- * Scan the port range for a running dashboard instance.
16138
- * Returns the port number if found, null otherwise.
16139
- */
16140
- async function findRunningDashboard(timeoutMs = HEALTH_TIMEOUT_MS) {
16141
- for (let port = DEFAULT_PORT; port <= PORT_RANGE_END; port++) if (await checkHealth(port, timeoutMs)) return port;
16142
- return null;
16143
- }
16144
- /**
16145
- * Kill processes listening on the given port. Cross-platform.
16146
- */
16147
- function killProcessOnPort(port) {
16148
- if (process.platform === "win32") try {
16149
- const lines = (0, node_child_process.execSync)(`netstat -ano | findstr :${port} | findstr LISTENING`, { encoding: "utf-8" }).trim().split("\n");
16150
- const pids = /* @__PURE__ */ new Set();
16151
- for (const line of lines) {
16152
- const parts = line.trim().split(/\s+/);
16153
- const pid = parts[parts.length - 1];
16154
- if (pid && pid !== "0") pids.add(pid);
16155
- }
16156
- for (const pid of pids) try {
16157
- (0, node_child_process.execSync)(`taskkill /PID ${pid} /F`, { stdio: "ignore" });
16158
- } catch (e) {
16159
- debugLog("kill-process-on-port-taskkill-failed", {
16160
- port,
16161
- pid,
16162
- error: errorMsg(e)
16163
- });
16164
- }
16165
- } catch (e) {
16166
- debugLog("kill-process-on-port-netstat-failed", {
16167
- port,
16168
- platform: "win32",
16169
- error: errorMsg(e)
16170
- });
16171
- }
16172
- else try {
16173
- (0, node_child_process.execSync)(`lsof -i :${port} -t | xargs kill -SIGTERM 2>/dev/null`, { stdio: "ignore" });
16174
- } catch (e) {
16175
- debugLog("kill-process-on-port-lsof-failed", {
16176
- port,
16177
- platform: process.platform,
16178
- error: errorMsg(e)
16179
- });
16180
- }
16181
- }
16182
- /**
16183
- * Resolve the dashboard server entry point path.
16184
- * Tries: local project install, global install, @maxsim/dashboard package, monorepo walk.
16185
- */
16186
- function resolveDashboardServer() {
16187
- const localDashboard = node_path.default.join(process.cwd(), ".claude", "dashboard", "server.js");
16188
- if (node_fs.default.existsSync(localDashboard)) return localDashboard;
16189
- const globalDashboard = node_path.default.join(node_os.default.homedir(), ".claude", "dashboard", "server.js");
16190
- if (node_fs.default.existsSync(globalDashboard)) return globalDashboard;
16191
- try {
16192
- const pkgPath = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href).resolve("@maxsim/dashboard/package.json");
16193
- const pkgDir = node_path.default.dirname(pkgPath);
16194
- const serverJs = node_path.default.join(pkgDir, "server.js");
16195
- if (node_fs.default.existsSync(serverJs)) return serverJs;
16196
- const serverTs = node_path.default.join(pkgDir, "server.ts");
16197
- if (node_fs.default.existsSync(serverTs)) return serverTs;
16198
- } catch (e) {
16199
- debugLog("resolve-dashboard-strategy1-failed", {
16200
- strategy: "@maxsim/dashboard package",
16201
- error: errorMsg(e)
16202
- });
16203
- }
16204
- try {
16205
- let dir = node_path.default.dirname(new URL(require("url").pathToFileURL(__filename).href).pathname);
16206
- if (process.platform === "win32" && dir.startsWith("/")) dir = dir.slice(1);
16207
- for (let i = 0; i < 5; i++) {
16208
- const candidate = node_path.default.join(dir, "packages", "dashboard", "server.ts");
16209
- if (node_fs.default.existsSync(candidate)) return candidate;
16210
- const candidateJs = node_path.default.join(dir, "packages", "dashboard", "server.js");
16211
- if (node_fs.default.existsSync(candidateJs)) return candidateJs;
16212
- dir = node_path.default.dirname(dir);
16213
- }
16214
- } catch (e) {
16215
- debugLog("resolve-dashboard-strategy2-failed", {
16216
- strategy: "monorepo walk",
16217
- error: errorMsg(e)
16218
- });
16219
- }
16220
- return null;
16221
- }
16222
- /**
16223
- * Ensure node-pty is installed in the dashboard directory.
16224
- * Returns true if node-pty is available after this call.
16225
- */
16226
- function ensureNodePty(serverDir) {
16227
- const ptyModulePath = node_path.default.join(serverDir, "node_modules", "node-pty");
16228
- if (node_fs.default.existsSync(ptyModulePath)) return true;
16229
- const dashPkgPath = node_path.default.join(serverDir, "package.json");
16230
- if (!node_fs.default.existsSync(dashPkgPath)) node_fs.default.writeFileSync(dashPkgPath, "{\"private\":true}\n");
16231
- try {
16232
- (0, node_child_process.execSync)("npm install node-pty --save-optional --no-audit --no-fund --loglevel=error", {
16233
- cwd: serverDir,
16234
- stdio: "inherit",
16235
- timeout: 12e4
16236
- });
16237
- return true;
16238
- } catch (e) {
16239
- debugLog("ensure-node-pty-install-failed", {
16240
- serverDir,
16241
- error: errorMsg(e)
16242
- });
16243
- return false;
16244
- }
16245
- }
16246
- /**
16247
- * Read dashboard.json config from the parent directory of the dashboard dir.
16248
- */
16249
- function readDashboardConfig(serverPath) {
16250
- const dashboardDir = node_path.default.dirname(serverPath);
16251
- const dashboardConfigPath = node_path.default.join(node_path.default.dirname(dashboardDir), "dashboard.json");
16252
- let projectCwd = process.cwd();
16253
- let networkMode = false;
16254
- if (node_fs.default.existsSync(dashboardConfigPath)) try {
16255
- const config = JSON.parse(node_fs.default.readFileSync(dashboardConfigPath, "utf8"));
16256
- if (config.projectCwd) projectCwd = config.projectCwd;
16257
- networkMode = config.networkMode ?? false;
16258
- } catch (e) {
16259
- debugLog("read-dashboard-config-failed", {
16260
- path: dashboardConfigPath,
16261
- error: errorMsg(e)
16262
- });
16263
- }
16264
- return {
16265
- projectCwd,
16266
- networkMode
16267
- };
16268
- }
16269
- /**
16270
- * Spawn the dashboard server as a detached background process.
16271
- * Returns the child process PID, or null if spawn failed.
16272
- */
16273
- function spawnDashboard(options) {
16274
- const { serverPath, projectCwd, networkMode = false, nodeEnv = "production" } = options;
16275
- const serverDir = node_path.default.dirname(serverPath);
16276
- const isTsFile = serverPath.endsWith(".ts");
16277
- const child = (0, node_child_process.spawn)("node", isTsFile ? [
16278
- "--import",
16279
- "tsx",
16280
- serverPath
16281
- ] : [serverPath], {
16282
- cwd: serverDir,
16283
- detached: true,
16284
- stdio: "ignore",
16285
- env: {
16286
- ...process.env,
16287
- MAXSIM_PROJECT_CWD: projectCwd,
16288
- MAXSIM_NETWORK_MODE: networkMode ? "1" : "0",
16289
- NODE_ENV: isTsFile ? "development" : nodeEnv
16290
- },
16291
- ...process.platform === "win32" ? { shell: true } : {}
16292
- });
16293
- child.unref();
16294
- return child.pid ?? null;
16295
- }
16296
- /**
16297
- * Poll the port range until a dashboard health endpoint responds.
16298
- * Returns the URL if found within the timeout, null otherwise.
16299
- */
16300
- async function waitForDashboard(pollIntervalMs = 500, pollTimeoutMs = 2e4, healthTimeoutMs = 1e3) {
16301
- const deadline = Date.now() + pollTimeoutMs;
16302
- while (Date.now() < deadline) {
16303
- await new Promise((r) => setTimeout(r, pollIntervalMs));
16304
- for (let p = DEFAULT_PORT; p <= PORT_RANGE_END; p++) if (await checkHealth(p, healthTimeoutMs)) return `http://localhost:${p}`;
16305
- }
16306
- return null;
16307
- }
16308
-
16309
- //#endregion
16310
- //#region src/core/start.ts
16311
- /**
16312
- * Start — Orchestrates Dashboard launch + browser open
16313
- *
16314
- * Provides a unified `maxsimcli start` entry point that:
16315
- * 1. Checks for a running dashboard
16316
- * 2. Starts the dashboard if needed
16317
- * 3. Opens the browser
16318
- * 4. Reports status
16319
- */
16320
- function openBrowser(url) {
16321
- (0, node_child_process.exec)(process.platform === "win32" ? `start "" "${url}"` : process.platform === "darwin" ? `open "${url}"` : `xdg-open "${url}"`, (err) => {
16322
- if (err) debugLog("open-browser-failed", err);
16323
- });
16324
- }
16325
- async function cmdStart(cwd, options) {
16326
- const existingPort = await findRunningDashboard();
16327
- if (existingPort) {
16328
- const url = `http://localhost:${existingPort}`;
16329
- if (!options.noBrowser) openBrowser(url);
16330
- return cmdOk({
16331
- started: true,
16332
- url,
16333
- already_running: true,
16334
- port: existingPort
16335
- }, url);
16336
- }
16337
- const serverPath = resolveDashboardServer();
16338
- if (!serverPath) return cmdErr("Dashboard server not found. Run `npx maxsimcli` to install first.");
16339
- const serverDir = node_path.default.dirname(serverPath);
16340
- const dashConfig = readDashboardConfig(serverPath);
16341
- ensureNodePty(serverDir);
16342
- const pid = spawnDashboard({
16343
- serverPath,
16344
- projectCwd: dashConfig.projectCwd,
16345
- networkMode: options.networkMode
16346
- });
16347
- if (!pid) return cmdErr("Failed to spawn dashboard process.");
16348
- const url = await waitForDashboard();
16349
- if (url) {
16350
- if (!options.noBrowser) openBrowser(url);
16351
- return cmdOk({
16352
- started: true,
16353
- url,
16354
- already_running: false,
16355
- pid
16356
- }, url);
16357
- } else {
16358
- const fallbackUrl = `http://localhost:${DEFAULT_PORT}`;
16359
- return cmdOk({
16360
- started: true,
16361
- url: fallbackUrl,
16362
- already_running: false,
16363
- pid,
16364
- warning: "Dashboard spawned but health check timed out. It may still be starting."
16365
- }, fallbackUrl);
16366
- }
16367
- }
16368
-
16369
15976
  //#endregion
16370
15977
  //#region src/core/init.ts
16371
15978
  /**
@@ -16373,8 +15980,8 @@ async function cmdStart(cwd, options) {
16373
15980
  *
16374
15981
  * Ported from maxsim/bin/lib/init.cjs
16375
15982
  */
16376
- function extractReqIds(cwd, phase) {
16377
- const reqMatch = getRoadmapPhaseInternal(cwd, phase)?.section?.match(/^\*\*Requirements\*\*:[^\S\n]*([^\n]*)$/m);
15983
+ async function extractReqIds(cwd, phase) {
15984
+ const reqMatch = (await getRoadmapPhaseInternal(cwd, phase))?.section?.match(/^\*\*Requirements\*\*:[^\S\n]*([^\n]*)$/m);
16378
15985
  const reqExtracted = reqMatch ? reqMatch[1].replace(/[\[\]]/g, "").split(",").map((s) => s.trim()).filter(Boolean).join(", ") : null;
16379
15986
  return reqExtracted && reqExtracted !== "TBD" ? reqExtracted : null;
16380
15987
  }
@@ -16430,15 +16037,15 @@ function findCodeFiles(dir, maxDepth = 3, limit = 5) {
16430
16037
  walk(dir, 1);
16431
16038
  return results;
16432
16039
  }
16433
- function cmdInitExecutePhase(cwd, phase) {
16040
+ async function cmdInitExecutePhase(cwd, phase) {
16434
16041
  if (!phase) return cmdErr("phase required for init execute-phase");
16435
- const config = loadConfig(cwd);
16436
- const phaseInfo = findPhaseInternal(cwd, phase);
16437
- const milestone = getMilestoneInfo(cwd);
16438
- const phase_req_ids = extractReqIds(cwd, phase);
16042
+ const config = await loadConfig(cwd);
16043
+ const phaseInfo = await findPhaseInternal(cwd, phase);
16044
+ const milestone = await getMilestoneInfo(cwd);
16045
+ const phase_req_ids = await extractReqIds(cwd, phase);
16439
16046
  return cmdOk({
16440
- executor_model: resolveModelInternal(cwd, "maxsim-executor"),
16441
- verifier_model: resolveModelInternal(cwd, "maxsim-verifier"),
16047
+ executor_model: await resolveModelInternal(cwd, "maxsim-executor"),
16048
+ verifier_model: await resolveModelInternal(cwd, "maxsim-verifier"),
16442
16049
  commit_docs: config.commit_docs,
16443
16050
  parallelization: config.parallelization,
16444
16051
  branching_strategy: config.branching_strategy,
@@ -16460,23 +16067,23 @@ function cmdInitExecutePhase(cwd, phase) {
16460
16067
  milestone_version: milestone.version,
16461
16068
  milestone_name: milestone.name,
16462
16069
  milestone_slug: generateSlugInternal(milestone.name),
16463
- state_exists: pathExistsInternal(cwd, ".planning/STATE.md"),
16464
- roadmap_exists: pathExistsInternal(cwd, ".planning/ROADMAP.md"),
16465
- config_exists: pathExistsInternal(cwd, ".planning/config.json"),
16070
+ state_exists: await pathExistsInternal(planningPath(cwd, "STATE.md")),
16071
+ roadmap_exists: await pathExistsInternal(planningPath(cwd, "ROADMAP.md")),
16072
+ config_exists: await pathExistsInternal(planningPath(cwd, "config.json")),
16466
16073
  state_path: ".planning/STATE.md",
16467
16074
  roadmap_path: ".planning/ROADMAP.md",
16468
16075
  config_path: ".planning/config.json"
16469
16076
  });
16470
16077
  }
16471
- function cmdInitPlanPhase(cwd, phase) {
16078
+ async function cmdInitPlanPhase(cwd, phase) {
16472
16079
  if (!phase) return cmdErr("phase required for init plan-phase");
16473
- const config = loadConfig(cwd);
16474
- const phaseInfo = findPhaseInternal(cwd, phase);
16475
- const phase_req_ids = extractReqIds(cwd, phase);
16080
+ const config = await loadConfig(cwd);
16081
+ const phaseInfo = await findPhaseInternal(cwd, phase);
16082
+ const phase_req_ids = await extractReqIds(cwd, phase);
16476
16083
  const result = {
16477
- researcher_model: resolveModelInternal(cwd, "maxsim-phase-researcher"),
16478
- planner_model: resolveModelInternal(cwd, "maxsim-planner"),
16479
- checker_model: resolveModelInternal(cwd, "maxsim-plan-checker"),
16084
+ researcher_model: await resolveModelInternal(cwd, "maxsim-phase-researcher"),
16085
+ planner_model: await resolveModelInternal(cwd, "maxsim-planner"),
16086
+ checker_model: await resolveModelInternal(cwd, "maxsim-plan-checker"),
16480
16087
  research_enabled: config.research,
16481
16088
  plan_checker_enabled: config.plan_checker,
16482
16089
  commit_docs: config.commit_docs,
@@ -16491,13 +16098,13 @@ function cmdInitPlanPhase(cwd, phase) {
16491
16098
  has_context: phaseInfo?.has_context ?? false,
16492
16099
  has_plans: (phaseInfo?.plans?.length ?? 0) > 0,
16493
16100
  plan_count: phaseInfo?.plans?.length ?? 0,
16494
- planning_exists: pathExistsInternal(cwd, ".planning"),
16495
- roadmap_exists: pathExistsInternal(cwd, ".planning/ROADMAP.md"),
16101
+ planning_exists: await pathExistsInternal(planningPath(cwd)),
16102
+ roadmap_exists: await pathExistsInternal(planningPath(cwd, "ROADMAP.md")),
16496
16103
  state_path: ".planning/STATE.md",
16497
16104
  roadmap_path: ".planning/ROADMAP.md",
16498
16105
  requirements_path: ".planning/REQUIREMENTS.md"
16499
16106
  };
16500
- if (pathExistsInternal(cwd, ".planning/CONVENTIONS.md")) result.conventions_path = ".planning/CONVENTIONS.md";
16107
+ if (await pathExistsInternal(planningPath(cwd, "CONVENTIONS.md"))) result.conventions_path = ".planning/CONVENTIONS.md";
16501
16108
  if (phaseInfo?.directory) {
16502
16109
  const artifacts = scanPhaseArtifacts(cwd, phaseInfo.directory);
16503
16110
  if (artifacts.context_path) result.context_path = artifacts.context_path;
@@ -16507,51 +16114,52 @@ function cmdInitPlanPhase(cwd, phase) {
16507
16114
  }
16508
16115
  return cmdOk(result);
16509
16116
  }
16510
- function cmdInitNewProject(cwd) {
16511
- const config = loadConfig(cwd);
16117
+ async function cmdInitNewProject(cwd) {
16118
+ const config = await loadConfig(cwd);
16512
16119
  const homedir = node_os.default.homedir();
16513
16120
  const braveKeyFile = node_path.default.join(homedir, ".maxsim", "brave_api_key");
16514
16121
  const hasBraveSearch = !!(process.env.BRAVE_API_KEY || node_fs.default.existsSync(braveKeyFile));
16515
16122
  const hasCode = findCodeFiles(cwd).length > 0;
16516
- const hasPackageFile = pathExistsInternal(cwd, "package.json") || pathExistsInternal(cwd, "requirements.txt") || pathExistsInternal(cwd, "Cargo.toml") || pathExistsInternal(cwd, "go.mod") || pathExistsInternal(cwd, "Package.swift");
16123
+ const hasPackageFile = await pathExistsInternal(node_path.default.join(cwd, "package.json")) || await pathExistsInternal(node_path.default.join(cwd, "requirements.txt")) || await pathExistsInternal(node_path.default.join(cwd, "Cargo.toml")) || await pathExistsInternal(node_path.default.join(cwd, "go.mod")) || await pathExistsInternal(node_path.default.join(cwd, "Package.swift"));
16124
+ const hasCodebaseMap = await pathExistsInternal(planningPath(cwd, "codebase"));
16517
16125
  return cmdOk({
16518
- researcher_model: resolveModelInternal(cwd, "maxsim-project-researcher"),
16519
- synthesizer_model: resolveModelInternal(cwd, "maxsim-research-synthesizer"),
16520
- roadmapper_model: resolveModelInternal(cwd, "maxsim-roadmapper"),
16126
+ researcher_model: await resolveModelInternal(cwd, "maxsim-project-researcher"),
16127
+ synthesizer_model: await resolveModelInternal(cwd, "maxsim-research-synthesizer"),
16128
+ roadmapper_model: await resolveModelInternal(cwd, "maxsim-roadmapper"),
16521
16129
  commit_docs: config.commit_docs,
16522
- project_exists: pathExistsInternal(cwd, ".planning/PROJECT.md"),
16523
- has_codebase_map: pathExistsInternal(cwd, ".planning/codebase"),
16524
- planning_exists: pathExistsInternal(cwd, ".planning"),
16130
+ project_exists: await pathExistsInternal(planningPath(cwd, "PROJECT.md")),
16131
+ has_codebase_map: hasCodebaseMap,
16132
+ planning_exists: await pathExistsInternal(planningPath(cwd)),
16525
16133
  has_existing_code: hasCode,
16526
16134
  has_package_file: hasPackageFile,
16527
16135
  is_brownfield: hasCode || hasPackageFile,
16528
- needs_codebase_map: (hasCode || hasPackageFile) && !pathExistsInternal(cwd, ".planning/codebase"),
16529
- has_git: pathExistsInternal(cwd, ".git"),
16136
+ needs_codebase_map: (hasCode || hasPackageFile) && !hasCodebaseMap,
16137
+ has_git: await pathExistsInternal(node_path.default.join(cwd, ".git")),
16530
16138
  brave_search_available: hasBraveSearch,
16531
16139
  project_path: ".planning/PROJECT.md"
16532
16140
  });
16533
16141
  }
16534
- function cmdInitNewMilestone(cwd) {
16535
- const config = loadConfig(cwd);
16536
- const milestone = getMilestoneInfo(cwd);
16142
+ async function cmdInitNewMilestone(cwd) {
16143
+ const config = await loadConfig(cwd);
16144
+ const milestone = await getMilestoneInfo(cwd);
16537
16145
  return cmdOk({
16538
- researcher_model: resolveModelInternal(cwd, "maxsim-project-researcher"),
16539
- synthesizer_model: resolveModelInternal(cwd, "maxsim-research-synthesizer"),
16540
- roadmapper_model: resolveModelInternal(cwd, "maxsim-roadmapper"),
16146
+ researcher_model: await resolveModelInternal(cwd, "maxsim-project-researcher"),
16147
+ synthesizer_model: await resolveModelInternal(cwd, "maxsim-research-synthesizer"),
16148
+ roadmapper_model: await resolveModelInternal(cwd, "maxsim-roadmapper"),
16541
16149
  commit_docs: config.commit_docs,
16542
16150
  research_enabled: config.research,
16543
16151
  current_milestone: milestone.version,
16544
16152
  current_milestone_name: milestone.name,
16545
- project_exists: pathExistsInternal(cwd, ".planning/PROJECT.md"),
16546
- roadmap_exists: pathExistsInternal(cwd, ".planning/ROADMAP.md"),
16547
- state_exists: pathExistsInternal(cwd, ".planning/STATE.md"),
16153
+ project_exists: await pathExistsInternal(planningPath(cwd, "PROJECT.md")),
16154
+ roadmap_exists: await pathExistsInternal(planningPath(cwd, "ROADMAP.md")),
16155
+ state_exists: await pathExistsInternal(planningPath(cwd, "STATE.md")),
16548
16156
  project_path: ".planning/PROJECT.md",
16549
16157
  roadmap_path: ".planning/ROADMAP.md",
16550
16158
  state_path: ".planning/STATE.md"
16551
16159
  });
16552
16160
  }
16553
- function cmdInitQuick(cwd, description) {
16554
- const config = loadConfig(cwd);
16161
+ async function cmdInitQuick(cwd, description) {
16162
+ const config = await loadConfig(cwd);
16555
16163
  const now = /* @__PURE__ */ new Date();
16556
16164
  const slug = description ? generateSlugInternal(description)?.substring(0, 40) ?? null : null;
16557
16165
  const quickDir = planningPath(cwd, "quick");
@@ -16563,10 +16171,10 @@ function cmdInitQuick(cwd, description) {
16563
16171
  debugLog(e);
16564
16172
  }
16565
16173
  return cmdOk({
16566
- planner_model: resolveModelInternal(cwd, "maxsim-planner"),
16567
- executor_model: resolveModelInternal(cwd, "maxsim-executor"),
16568
- checker_model: resolveModelInternal(cwd, "maxsim-plan-checker"),
16569
- verifier_model: resolveModelInternal(cwd, "maxsim-verifier"),
16174
+ planner_model: await resolveModelInternal(cwd, "maxsim-planner"),
16175
+ executor_model: await resolveModelInternal(cwd, "maxsim-executor"),
16176
+ checker_model: await resolveModelInternal(cwd, "maxsim-plan-checker"),
16177
+ verifier_model: await resolveModelInternal(cwd, "maxsim-verifier"),
16570
16178
  commit_docs: config.commit_docs,
16571
16179
  next_num: nextNum,
16572
16180
  slug,
@@ -16575,12 +16183,12 @@ function cmdInitQuick(cwd, description) {
16575
16183
  timestamp: now.toISOString(),
16576
16184
  quick_dir: ".planning/quick",
16577
16185
  task_dir: slug ? `.planning/quick/${nextNum}-${slug}` : null,
16578
- roadmap_exists: pathExistsInternal(cwd, ".planning/ROADMAP.md"),
16579
- planning_exists: pathExistsInternal(cwd, ".planning")
16186
+ roadmap_exists: await pathExistsInternal(planningPath(cwd, "ROADMAP.md")),
16187
+ planning_exists: await pathExistsInternal(planningPath(cwd))
16580
16188
  });
16581
16189
  }
16582
- function cmdInitResume(cwd) {
16583
- const config = loadConfig(cwd);
16190
+ async function cmdInitResume(cwd) {
16191
+ const config = await loadConfig(cwd);
16584
16192
  let interruptedAgentId = null;
16585
16193
  try {
16586
16194
  interruptedAgentId = node_fs.default.readFileSync(planningPath(cwd, "current-agent-id.txt"), "utf-8").trim();
@@ -16588,10 +16196,10 @@ function cmdInitResume(cwd) {
16588
16196
  debugLog(e);
16589
16197
  }
16590
16198
  return cmdOk({
16591
- state_exists: pathExistsInternal(cwd, ".planning/STATE.md"),
16592
- roadmap_exists: pathExistsInternal(cwd, ".planning/ROADMAP.md"),
16593
- project_exists: pathExistsInternal(cwd, ".planning/PROJECT.md"),
16594
- planning_exists: pathExistsInternal(cwd, ".planning"),
16199
+ state_exists: await pathExistsInternal(planningPath(cwd, "STATE.md")),
16200
+ roadmap_exists: await pathExistsInternal(planningPath(cwd, "ROADMAP.md")),
16201
+ project_exists: await pathExistsInternal(planningPath(cwd, "PROJECT.md")),
16202
+ planning_exists: await pathExistsInternal(planningPath(cwd)),
16595
16203
  state_path: ".planning/STATE.md",
16596
16204
  roadmap_path: ".planning/ROADMAP.md",
16597
16205
  project_path: ".planning/PROJECT.md",
@@ -16600,13 +16208,13 @@ function cmdInitResume(cwd) {
16600
16208
  commit_docs: config.commit_docs
16601
16209
  });
16602
16210
  }
16603
- function cmdInitVerifyWork(cwd, phase) {
16211
+ async function cmdInitVerifyWork(cwd, phase) {
16604
16212
  if (!phase) return cmdErr("phase required for init verify-work");
16605
- const config = loadConfig(cwd);
16606
- const phaseInfo = findPhaseInternal(cwd, phase);
16213
+ const config = await loadConfig(cwd);
16214
+ const phaseInfo = await findPhaseInternal(cwd, phase);
16607
16215
  return cmdOk({
16608
- planner_model: resolveModelInternal(cwd, "maxsim-planner"),
16609
- checker_model: resolveModelInternal(cwd, "maxsim-plan-checker"),
16216
+ planner_model: await resolveModelInternal(cwd, "maxsim-planner"),
16217
+ checker_model: await resolveModelInternal(cwd, "maxsim-plan-checker"),
16610
16218
  commit_docs: config.commit_docs,
16611
16219
  phase_found: !!phaseInfo,
16612
16220
  phase_dir: phaseInfo?.directory ?? null,
@@ -16615,11 +16223,11 @@ function cmdInitVerifyWork(cwd, phase) {
16615
16223
  has_verification: phaseInfo?.has_verification ?? false
16616
16224
  });
16617
16225
  }
16618
- function cmdInitPhaseOp(cwd, phase) {
16619
- const config = loadConfig(cwd);
16620
- let phaseInfo = findPhaseInternal(cwd, phase ?? "");
16226
+ async function cmdInitPhaseOp(cwd, phase) {
16227
+ const config = await loadConfig(cwd);
16228
+ let phaseInfo = await findPhaseInternal(cwd, phase ?? "");
16621
16229
  if (!phaseInfo) {
16622
- const roadmapPhase = getRoadmapPhaseInternal(cwd, phase ?? "");
16230
+ const roadmapPhase = await getRoadmapPhaseInternal(cwd, phase ?? "");
16623
16231
  if (roadmapPhase?.found) {
16624
16232
  const phaseName = roadmapPhase.phase_name;
16625
16233
  phaseInfo = {
@@ -16651,13 +16259,13 @@ function cmdInitPhaseOp(cwd, phase) {
16651
16259
  has_plans: (phaseInfo?.plans?.length ?? 0) > 0,
16652
16260
  has_verification: phaseInfo?.has_verification ?? false,
16653
16261
  plan_count: phaseInfo?.plans?.length ?? 0,
16654
- roadmap_exists: pathExistsInternal(cwd, ".planning/ROADMAP.md"),
16655
- planning_exists: pathExistsInternal(cwd, ".planning"),
16262
+ roadmap_exists: await pathExistsInternal(planningPath(cwd, "ROADMAP.md")),
16263
+ planning_exists: await pathExistsInternal(planningPath(cwd)),
16656
16264
  state_path: ".planning/STATE.md",
16657
16265
  roadmap_path: ".planning/ROADMAP.md",
16658
16266
  requirements_path: ".planning/REQUIREMENTS.md"
16659
16267
  };
16660
- if (pathExistsInternal(cwd, ".planning/CONVENTIONS.md")) result.conventions_path = ".planning/CONVENTIONS.md";
16268
+ if (await pathExistsInternal(planningPath(cwd, "CONVENTIONS.md"))) result.conventions_path = ".planning/CONVENTIONS.md";
16661
16269
  if (phaseInfo?.directory) {
16662
16270
  const artifacts = scanPhaseArtifacts(cwd, phaseInfo.directory);
16663
16271
  if (artifacts.context_path) result.context_path = artifacts.context_path;
@@ -16667,8 +16275,8 @@ function cmdInitPhaseOp(cwd, phase) {
16667
16275
  }
16668
16276
  return cmdOk(result);
16669
16277
  }
16670
- function cmdInitTodos(cwd, area) {
16671
- const config = loadConfig(cwd);
16278
+ async function cmdInitTodos(cwd, area) {
16279
+ const config = await loadConfig(cwd);
16672
16280
  const now = /* @__PURE__ */ new Date();
16673
16281
  const pendingDir = planningPath(cwd, "todos", "pending");
16674
16282
  let count = 0;
@@ -16705,19 +16313,19 @@ function cmdInitTodos(cwd, area) {
16705
16313
  area_filter: area ?? null,
16706
16314
  pending_dir: ".planning/todos/pending",
16707
16315
  completed_dir: ".planning/todos/completed",
16708
- planning_exists: pathExistsInternal(cwd, ".planning"),
16709
- todos_dir_exists: pathExistsInternal(cwd, ".planning/todos"),
16710
- pending_dir_exists: pathExistsInternal(cwd, ".planning/todos/pending")
16316
+ planning_exists: await pathExistsInternal(planningPath(cwd)),
16317
+ todos_dir_exists: await pathExistsInternal(planningPath(cwd, "todos")),
16318
+ pending_dir_exists: await pathExistsInternal(planningPath(cwd, "todos", "pending"))
16711
16319
  });
16712
16320
  }
16713
- function cmdInitMilestoneOp(cwd) {
16714
- const config = loadConfig(cwd);
16715
- const milestone = getMilestoneInfo(cwd);
16321
+ async function cmdInitMilestoneOp(cwd) {
16322
+ const config = await loadConfig(cwd);
16323
+ const milestone = await getMilestoneInfo(cwd);
16716
16324
  let phaseCount = 0;
16717
16325
  let completedPhases = 0;
16718
16326
  const phasesDir = phasesPath(cwd);
16719
16327
  try {
16720
- const dirs = listSubDirs(phasesDir);
16328
+ const dirs = await listSubDirs(phasesDir);
16721
16329
  phaseCount = dirs.length;
16722
16330
  for (const dir of dirs) try {
16723
16331
  if (node_fs.default.readdirSync(node_path.default.join(phasesDir, dir)).some((f) => isSummaryFile(f))) completedPhases++;
@@ -16730,7 +16338,7 @@ function cmdInitMilestoneOp(cwd) {
16730
16338
  const archiveDir = planningPath(cwd, "archive");
16731
16339
  let archivedMilestones = [];
16732
16340
  try {
16733
- archivedMilestones = listSubDirs(archiveDir);
16341
+ archivedMilestones = await listSubDirs(archiveDir);
16734
16342
  } catch (e) {
16735
16343
  debugLog(e);
16736
16344
  }
@@ -16744,15 +16352,15 @@ function cmdInitMilestoneOp(cwd) {
16744
16352
  all_phases_complete: phaseCount > 0 && phaseCount === completedPhases,
16745
16353
  archived_milestones: archivedMilestones,
16746
16354
  archive_count: archivedMilestones.length,
16747
- project_exists: pathExistsInternal(cwd, ".planning/PROJECT.md"),
16748
- roadmap_exists: pathExistsInternal(cwd, ".planning/ROADMAP.md"),
16749
- state_exists: pathExistsInternal(cwd, ".planning/STATE.md"),
16750
- archive_exists: pathExistsInternal(cwd, ".planning/archive"),
16751
- phases_dir_exists: pathExistsInternal(cwd, ".planning/phases")
16355
+ project_exists: await pathExistsInternal(planningPath(cwd, "PROJECT.md")),
16356
+ roadmap_exists: await pathExistsInternal(planningPath(cwd, "ROADMAP.md")),
16357
+ state_exists: await pathExistsInternal(planningPath(cwd, "STATE.md")),
16358
+ archive_exists: await pathExistsInternal(planningPath(cwd, "archive")),
16359
+ phases_dir_exists: await pathExistsInternal(planningPath(cwd, "phases"))
16752
16360
  });
16753
16361
  }
16754
- function cmdInitMapCodebase(cwd) {
16755
- const config = loadConfig(cwd);
16362
+ async function cmdInitMapCodebase(cwd) {
16363
+ const config = await loadConfig(cwd);
16756
16364
  const codebaseDir = planningPath(cwd, "codebase");
16757
16365
  let existingMaps = [];
16758
16366
  try {
@@ -16761,24 +16369,24 @@ function cmdInitMapCodebase(cwd) {
16761
16369
  debugLog(e);
16762
16370
  }
16763
16371
  return cmdOk({
16764
- mapper_model: resolveModelInternal(cwd, "maxsim-codebase-mapper"),
16372
+ mapper_model: await resolveModelInternal(cwd, "maxsim-codebase-mapper"),
16765
16373
  commit_docs: config.commit_docs,
16766
16374
  search_gitignored: config.search_gitignored,
16767
16375
  parallelization: config.parallelization,
16768
16376
  codebase_dir: ".planning/codebase",
16769
16377
  existing_maps: existingMaps,
16770
16378
  has_maps: existingMaps.length > 0,
16771
- planning_exists: pathExistsInternal(cwd, ".planning"),
16772
- codebase_dir_exists: pathExistsInternal(cwd, ".planning/codebase")
16379
+ planning_exists: await pathExistsInternal(planningPath(cwd)),
16380
+ codebase_dir_exists: await pathExistsInternal(planningPath(cwd, "codebase"))
16773
16381
  });
16774
16382
  }
16775
- function cmdInitExisting(cwd) {
16776
- const config = loadConfig(cwd);
16383
+ async function cmdInitExisting(cwd) {
16384
+ const config = await loadConfig(cwd);
16777
16385
  const homedir = node_os.default.homedir();
16778
16386
  const braveKeyFile = node_path.default.join(homedir, ".maxsim", "brave_api_key");
16779
16387
  const hasBraveSearch = !!(process.env.BRAVE_API_KEY || node_fs.default.existsSync(braveKeyFile));
16780
16388
  const hasCode = findCodeFiles(cwd).length > 0;
16781
- const hasPackageFile = pathExistsInternal(cwd, "package.json") || pathExistsInternal(cwd, "requirements.txt") || pathExistsInternal(cwd, "Cargo.toml") || pathExistsInternal(cwd, "go.mod") || pathExistsInternal(cwd, "Package.swift");
16389
+ const hasPackageFile = await pathExistsInternal(node_path.default.join(cwd, "package.json")) || await pathExistsInternal(node_path.default.join(cwd, "requirements.txt")) || await pathExistsInternal(node_path.default.join(cwd, "Cargo.toml")) || await pathExistsInternal(node_path.default.join(cwd, "go.mod")) || await pathExistsInternal(node_path.default.join(cwd, "Package.swift"));
16782
16390
  let planningFiles = [];
16783
16391
  try {
16784
16392
  const planDir = planningPath(cwd);
@@ -16787,19 +16395,19 @@ function cmdInitExisting(cwd) {
16787
16395
  debugLog(e);
16788
16396
  }
16789
16397
  return cmdOk({
16790
- researcher_model: resolveModelInternal(cwd, "maxsim-project-researcher"),
16791
- synthesizer_model: resolveModelInternal(cwd, "maxsim-research-synthesizer"),
16792
- roadmapper_model: resolveModelInternal(cwd, "maxsim-roadmapper"),
16793
- mapper_model: resolveModelInternal(cwd, "maxsim-codebase-mapper"),
16398
+ researcher_model: await resolveModelInternal(cwd, "maxsim-project-researcher"),
16399
+ synthesizer_model: await resolveModelInternal(cwd, "maxsim-research-synthesizer"),
16400
+ roadmapper_model: await resolveModelInternal(cwd, "maxsim-roadmapper"),
16401
+ mapper_model: await resolveModelInternal(cwd, "maxsim-codebase-mapper"),
16794
16402
  commit_docs: config.commit_docs,
16795
- project_exists: pathExistsInternal(cwd, ".planning/PROJECT.md"),
16796
- planning_exists: pathExistsInternal(cwd, ".planning"),
16403
+ project_exists: await pathExistsInternal(planningPath(cwd, "PROJECT.md")),
16404
+ planning_exists: await pathExistsInternal(planningPath(cwd)),
16797
16405
  planning_files: planningFiles,
16798
- has_codebase_map: pathExistsInternal(cwd, ".planning/codebase"),
16406
+ has_codebase_map: await pathExistsInternal(planningPath(cwd, "codebase")),
16799
16407
  has_existing_code: hasCode,
16800
16408
  has_package_file: hasPackageFile,
16801
- has_git: pathExistsInternal(cwd, ".git"),
16802
- has_readme: pathExistsInternal(cwd, "README.md"),
16409
+ has_git: await pathExistsInternal(node_path.default.join(cwd, ".git")),
16410
+ has_readme: await pathExistsInternal(node_path.default.join(cwd, "README.md")),
16803
16411
  conflict_detected: planningFiles.length > 0,
16804
16412
  existing_file_count: planningFiles.length,
16805
16413
  brave_search_available: hasBraveSearch,
@@ -16808,15 +16416,15 @@ function cmdInitExisting(cwd) {
16808
16416
  codebase_dir: ".planning/codebase"
16809
16417
  });
16810
16418
  }
16811
- function cmdInitProgress(cwd) {
16812
- const config = loadConfig(cwd);
16813
- const milestone = getMilestoneInfo(cwd);
16419
+ async function cmdInitProgress(cwd) {
16420
+ const config = await loadConfig(cwd);
16421
+ const milestone = await getMilestoneInfo(cwd);
16814
16422
  const progressPhasesDir = phasesPath(cwd);
16815
16423
  const phases = [];
16816
16424
  let currentPhase = null;
16817
16425
  let nextPhase = null;
16818
16426
  try {
16819
- const dirs = listSubDirs(progressPhasesDir, true);
16427
+ const dirs = await listSubDirs(progressPhasesDir, true);
16820
16428
  for (const dir of dirs) {
16821
16429
  const match = dir.match(/^(\d+(?:\.\d+)?)-?(.*)/);
16822
16430
  const phaseNumber = match ? match[1] : dir;
@@ -16851,8 +16459,8 @@ function cmdInitProgress(cwd) {
16851
16459
  debugLog(e);
16852
16460
  }
16853
16461
  return cmdOk({
16854
- executor_model: resolveModelInternal(cwd, "maxsim-executor"),
16855
- planner_model: resolveModelInternal(cwd, "maxsim-planner"),
16462
+ executor_model: await resolveModelInternal(cwd, "maxsim-executor"),
16463
+ planner_model: await resolveModelInternal(cwd, "maxsim-planner"),
16856
16464
  commit_docs: config.commit_docs,
16857
16465
  milestone_version: milestone.version,
16858
16466
  milestone_name: milestone.name,
@@ -16864,9 +16472,9 @@ function cmdInitProgress(cwd) {
16864
16472
  next_phase: nextPhase,
16865
16473
  paused_at: pausedAt,
16866
16474
  has_work_in_progress: !!currentPhase,
16867
- project_exists: pathExistsInternal(cwd, ".planning/PROJECT.md"),
16868
- roadmap_exists: pathExistsInternal(cwd, ".planning/ROADMAP.md"),
16869
- state_exists: pathExistsInternal(cwd, ".planning/STATE.md"),
16475
+ project_exists: await pathExistsInternal(planningPath(cwd, "PROJECT.md")),
16476
+ roadmap_exists: await pathExistsInternal(planningPath(cwd, "ROADMAP.md")),
16477
+ state_exists: await pathExistsInternal(planningPath(cwd, "STATE.md")),
16870
16478
  state_path: ".planning/STATE.md",
16871
16479
  roadmap_path: ".planning/ROADMAP.md",
16872
16480
  project_path: ".planning/PROJECT.md",
@@ -16885,14 +16493,14 @@ function listCodebaseDocs(cwd) {
16885
16493
  return [];
16886
16494
  }
16887
16495
  }
16888
- function cmdInitExecutor(cwd, phase) {
16496
+ async function cmdInitExecutor(cwd, phase) {
16889
16497
  if (!phase) return cmdErr("phase required for init executor");
16890
- const config = loadConfig(cwd);
16891
- const phaseInfo = findPhaseInternal(cwd, phase);
16498
+ const config = await loadConfig(cwd);
16499
+ const phaseInfo = await findPhaseInternal(cwd, phase);
16892
16500
  const codebaseDocs = listCodebaseDocs(cwd);
16893
16501
  const result = {
16894
- executor_model: resolveModelInternal(cwd, "maxsim-executor"),
16895
- verifier_model: resolveModelInternal(cwd, "maxsim-verifier"),
16502
+ executor_model: await resolveModelInternal(cwd, "maxsim-executor"),
16503
+ verifier_model: await resolveModelInternal(cwd, "maxsim-verifier"),
16896
16504
  commit_docs: config.commit_docs,
16897
16505
  parallelization: config.parallelization,
16898
16506
  branching_strategy: config.branching_strategy,
@@ -16905,18 +16513,18 @@ function cmdInitExecutor(cwd, phase) {
16905
16513
  state_path: ".planning/STATE.md",
16906
16514
  codebase_docs: codebaseDocs
16907
16515
  };
16908
- if (pathExistsInternal(cwd, ".planning/CONVENTIONS.md")) result.conventions_path = ".planning/CONVENTIONS.md";
16516
+ if (await pathExistsInternal(planningPath(cwd, "CONVENTIONS.md"))) result.conventions_path = ".planning/CONVENTIONS.md";
16909
16517
  return cmdOk(result);
16910
16518
  }
16911
- function cmdInitPlanner(cwd, phase) {
16519
+ async function cmdInitPlanner(cwd, phase) {
16912
16520
  if (!phase) return cmdErr("phase required for init planner");
16913
- const config = loadConfig(cwd);
16914
- const phaseInfo = findPhaseInternal(cwd, phase);
16915
- const phase_req_ids = extractReqIds(cwd, phase);
16521
+ const config = await loadConfig(cwd);
16522
+ const phaseInfo = await findPhaseInternal(cwd, phase);
16523
+ const phase_req_ids = await extractReqIds(cwd, phase);
16916
16524
  const codebaseDocs = listCodebaseDocs(cwd);
16917
16525
  const result = {
16918
- planner_model: resolveModelInternal(cwd, "maxsim-planner"),
16919
- checker_model: resolveModelInternal(cwd, "maxsim-plan-checker"),
16526
+ planner_model: await resolveModelInternal(cwd, "maxsim-planner"),
16527
+ checker_model: await resolveModelInternal(cwd, "maxsim-plan-checker"),
16920
16528
  commit_docs: config.commit_docs,
16921
16529
  research_enabled: config.research,
16922
16530
  plan_checker_enabled: config.plan_checker,
@@ -16934,7 +16542,7 @@ function cmdInitPlanner(cwd, phase) {
16934
16542
  requirements_path: ".planning/REQUIREMENTS.md",
16935
16543
  codebase_docs: codebaseDocs
16936
16544
  };
16937
- if (pathExistsInternal(cwd, ".planning/CONVENTIONS.md")) result.conventions_path = ".planning/CONVENTIONS.md";
16545
+ if (await pathExistsInternal(planningPath(cwd, "CONVENTIONS.md"))) result.conventions_path = ".planning/CONVENTIONS.md";
16938
16546
  if (phaseInfo?.directory) {
16939
16547
  const artifacts = scanPhaseArtifacts(cwd, phaseInfo.directory);
16940
16548
  if (artifacts.context_path) result.context_path = artifacts.context_path;
@@ -16942,14 +16550,14 @@ function cmdInitPlanner(cwd, phase) {
16942
16550
  }
16943
16551
  return cmdOk(result);
16944
16552
  }
16945
- function cmdInitResearcher(cwd, phase) {
16553
+ async function cmdInitResearcher(cwd, phase) {
16946
16554
  if (!phase) return cmdErr("phase required for init researcher");
16947
- const config = loadConfig(cwd);
16948
- const phaseInfo = findPhaseInternal(cwd, phase);
16949
- const phase_req_ids = extractReqIds(cwd, phase);
16555
+ const config = await loadConfig(cwd);
16556
+ const phaseInfo = await findPhaseInternal(cwd, phase);
16557
+ const phase_req_ids = await extractReqIds(cwd, phase);
16950
16558
  const codebaseDocs = listCodebaseDocs(cwd);
16951
16559
  const result = {
16952
- researcher_model: resolveModelInternal(cwd, "maxsim-phase-researcher"),
16560
+ researcher_model: await resolveModelInternal(cwd, "maxsim-phase-researcher"),
16953
16561
  commit_docs: config.commit_docs,
16954
16562
  brave_search: config.brave_search,
16955
16563
  phase_found: !!phaseInfo,
@@ -16965,21 +16573,21 @@ function cmdInitResearcher(cwd, phase) {
16965
16573
  requirements_path: ".planning/REQUIREMENTS.md",
16966
16574
  codebase_docs: codebaseDocs
16967
16575
  };
16968
- if (pathExistsInternal(cwd, ".planning/CONVENTIONS.md")) result.conventions_path = ".planning/CONVENTIONS.md";
16576
+ if (await pathExistsInternal(planningPath(cwd, "CONVENTIONS.md"))) result.conventions_path = ".planning/CONVENTIONS.md";
16969
16577
  if (phaseInfo?.directory) {
16970
16578
  const artifacts = scanPhaseArtifacts(cwd, phaseInfo.directory);
16971
16579
  if (artifacts.context_path) result.context_path = artifacts.context_path;
16972
16580
  }
16973
16581
  return cmdOk(result);
16974
16582
  }
16975
- function cmdInitVerifier(cwd, phase) {
16583
+ async function cmdInitVerifier(cwd, phase) {
16976
16584
  if (!phase) return cmdErr("phase required for init verifier");
16977
- const config = loadConfig(cwd);
16978
- const phaseInfo = findPhaseInternal(cwd, phase);
16979
- const phase_req_ids = extractReqIds(cwd, phase);
16585
+ const config = await loadConfig(cwd);
16586
+ const phaseInfo = await findPhaseInternal(cwd, phase);
16587
+ const phase_req_ids = await extractReqIds(cwd, phase);
16980
16588
  const codebaseDocs = listCodebaseDocs(cwd);
16981
16589
  return cmdOk({
16982
- verifier_model: resolveModelInternal(cwd, "maxsim-verifier"),
16590
+ verifier_model: await resolveModelInternal(cwd, "maxsim-verifier"),
16983
16591
  commit_docs: config.commit_docs,
16984
16592
  phase_found: !!phaseInfo,
16985
16593
  phase_dir: phaseInfo?.directory ?? null,
@@ -16992,12 +16600,12 @@ function cmdInitVerifier(cwd, phase) {
16992
16600
  codebase_docs: codebaseDocs
16993
16601
  });
16994
16602
  }
16995
- function cmdInitDebugger(cwd, phase) {
16996
- const config = loadConfig(cwd);
16997
- const phaseInfo = phase ? findPhaseInternal(cwd, phase) : null;
16603
+ async function cmdInitDebugger(cwd, phase) {
16604
+ const config = await loadConfig(cwd);
16605
+ const phaseInfo = phase ? await findPhaseInternal(cwd, phase) : null;
16998
16606
  const codebaseDocs = listCodebaseDocs(cwd);
16999
16607
  const result = {
17000
- debugger_model: resolveModelInternal(cwd, "maxsim-debugger"),
16608
+ debugger_model: await resolveModelInternal(cwd, "maxsim-debugger"),
17001
16609
  commit_docs: config.commit_docs,
17002
16610
  phase_found: !!phaseInfo,
17003
16611
  phase_dir: phaseInfo?.directory ?? null,
@@ -17006,31 +16614,31 @@ function cmdInitDebugger(cwd, phase) {
17006
16614
  state_path: ".planning/STATE.md",
17007
16615
  codebase_docs: codebaseDocs
17008
16616
  };
17009
- if (pathExistsInternal(cwd, ".planning/CONVENTIONS.md")) result.conventions_path = ".planning/CONVENTIONS.md";
16617
+ if (await pathExistsInternal(planningPath(cwd, "CONVENTIONS.md"))) result.conventions_path = ".planning/CONVENTIONS.md";
17010
16618
  return cmdOk(result);
17011
16619
  }
17012
- function cmdInitCheckDrift(cwd) {
17013
- const config = loadConfig(cwd);
17014
- const driftModel = resolveModelInternal(cwd, "maxsim-drift-checker");
17015
- const hasPlanning = pathExistsInternal(cwd, ".planning");
17016
- const hasRequirements = pathExistsInternal(cwd, ".planning/REQUIREMENTS.md");
17017
- const hasRoadmap = pathExistsInternal(cwd, ".planning/ROADMAP.md");
17018
- const hasNogos = pathExistsInternal(cwd, ".planning/NO-GOS.md");
17019
- const hasConventions = pathExistsInternal(cwd, ".planning/CONVENTIONS.md");
17020
- const hasPreviousReport = pathExistsInternal(cwd, ".planning/DRIFT-REPORT.md");
16620
+ async function cmdInitCheckDrift(cwd) {
16621
+ const config = await loadConfig(cwd);
16622
+ const driftModel = await resolveModelInternal(cwd, "maxsim-drift-checker");
16623
+ const hasPlanning = await pathExistsInternal(planningPath(cwd));
16624
+ const hasRequirements = await pathExistsInternal(planningPath(cwd, "REQUIREMENTS.md"));
16625
+ const hasRoadmap = await pathExistsInternal(planningPath(cwd, "ROADMAP.md"));
16626
+ const hasNogos = await pathExistsInternal(planningPath(cwd, "NO-GOS.md"));
16627
+ const hasConventions = await pathExistsInternal(planningPath(cwd, "CONVENTIONS.md"));
16628
+ const hasPreviousReport = await pathExistsInternal(planningPath(cwd, "DRIFT-REPORT.md"));
17021
16629
  const specFiles = [];
17022
16630
  if (hasRequirements) specFiles.push(".planning/REQUIREMENTS.md");
17023
16631
  if (hasRoadmap) specFiles.push(".planning/ROADMAP.md");
17024
- if (pathExistsInternal(cwd, ".planning/STATE.md")) specFiles.push(".planning/STATE.md");
16632
+ if (await pathExistsInternal(planningPath(cwd, "STATE.md"))) specFiles.push(".planning/STATE.md");
17025
16633
  if (hasNogos) specFiles.push(".planning/NO-GOS.md");
17026
16634
  if (hasConventions) specFiles.push(".planning/CONVENTIONS.md");
17027
16635
  let phaseDirs = [];
17028
16636
  try {
17029
- phaseDirs = listSubDirs(phasesPath(cwd), true).map((d) => `.planning/phases/${d}`);
16637
+ phaseDirs = (await listSubDirs(phasesPath(cwd), true)).map((d) => `.planning/phases/${d}`);
17030
16638
  } catch {}
17031
16639
  let archivedMilestoneDirs = [];
17032
16640
  try {
17033
- archivedMilestoneDirs = getArchivedPhaseDirs(cwd).map((a) => a.basePath);
16641
+ archivedMilestoneDirs = (await getArchivedPhaseDirs(cwd)).map((a) => a.basePath);
17034
16642
  archivedMilestoneDirs = [...new Set(archivedMilestoneDirs)];
17035
16643
  } catch {}
17036
16644
  const codebaseDocs = listCodebaseDocs(cwd);
@@ -17055,13 +16663,13 @@ function cmdInitCheckDrift(cwd) {
17055
16663
  codebase_docs: codebaseDocs
17056
16664
  });
17057
16665
  }
17058
- function cmdInitRealign(cwd, direction) {
17059
- const config = loadConfig(cwd);
17060
- const hasReport = pathExistsInternal(cwd, ".planning/DRIFT-REPORT.md");
17061
- const hasPlanning = pathExistsInternal(cwd, ".planning");
16666
+ async function cmdInitRealign(cwd, direction) {
16667
+ const config = await loadConfig(cwd);
16668
+ const hasReport = await pathExistsInternal(planningPath(cwd, "DRIFT-REPORT.md"));
16669
+ const hasPlanning = await pathExistsInternal(planningPath(cwd));
17062
16670
  let phaseDirs = [];
17063
16671
  try {
17064
- phaseDirs = listSubDirs(phasesPath(cwd), true).map((d) => `.planning/phases/${d}`);
16672
+ phaseDirs = (await listSubDirs(phasesPath(cwd), true)).map((d) => `.planning/phases/${d}`);
17065
16673
  } catch {}
17066
16674
  const codebaseDocs = listCodebaseDocs(cwd);
17067
16675
  return cmdOk({
@@ -17163,12 +16771,12 @@ const handleState = async (args, cwd, raw) => {
17163
16771
  if (handler) return handleResult(await handler(), raw);
17164
16772
  return handleResult(await cmdStateLoad(cwd, raw), raw);
17165
16773
  };
17166
- const handleTemplate = (args, cwd, raw) => {
16774
+ const handleTemplate = async (args, cwd, raw) => {
17167
16775
  const sub = args[1];
17168
16776
  if (sub === "select") handleResult(cmdTemplateSelect(cwd, args[2]), raw);
17169
16777
  else if (sub === "fill") {
17170
16778
  const f = getFlags(args, "phase", "plan", "name", "type", "wave", "fields");
17171
- handleResult(cmdTemplateFill(cwd, args[2], {
16779
+ handleResult(await cmdTemplateFill(cwd, args[2], {
17172
16780
  phase: f.phase ?? "",
17173
16781
  plan: f.plan ?? void 0,
17174
16782
  name: f.name ?? void 0,
@@ -17178,14 +16786,14 @@ const handleTemplate = (args, cwd, raw) => {
17178
16786
  }), raw);
17179
16787
  } else error("Unknown template subcommand. Available: select, fill");
17180
16788
  };
17181
- const handleFrontmatter = (args, cwd, raw) => {
16789
+ const handleFrontmatter = async (args, cwd, raw) => {
17182
16790
  const sub = args[1];
17183
16791
  const file = args[2];
17184
16792
  const handler = sub ? {
17185
- "get": () => handleResult(cmdFrontmatterGet(cwd, file, getFlag(args, "--field")), raw),
16793
+ "get": async () => handleResult(await cmdFrontmatterGet(cwd, file, getFlag(args, "--field")), raw),
17186
16794
  "set": () => handleResult(cmdFrontmatterSet(cwd, file, getFlag(args, "--field"), getFlag(args, "--value") ?? void 0), raw),
17187
16795
  "merge": () => handleResult(cmdFrontmatterMerge(cwd, file, getFlag(args, "--data")), raw),
17188
- "validate": () => handleResult(cmdFrontmatterValidate(cwd, file, getFlag(args, "--schema")), raw)
16796
+ "validate": async () => handleResult(await cmdFrontmatterValidate(cwd, file, getFlag(args, "--schema")), raw)
17189
16797
  }[sub] : void 0;
17190
16798
  if (handler) return handler();
17191
16799
  error("Unknown frontmatter subcommand. Available: get, set, merge, validate");
@@ -17193,12 +16801,12 @@ const handleFrontmatter = (args, cwd, raw) => {
17193
16801
  const handleVerify = async (args, cwd, raw) => {
17194
16802
  const sub = args[1];
17195
16803
  const handler = sub ? {
17196
- "plan-structure": () => handleResult(cmdVerifyPlanStructure(cwd, args[2]), raw),
17197
- "phase-completeness": () => handleResult(cmdVerifyPhaseCompleteness(cwd, args[2]), raw),
17198
- "references": () => handleResult(cmdVerifyReferences(cwd, args[2]), raw),
16804
+ "plan-structure": async () => handleResult(await cmdVerifyPlanStructure(cwd, args[2]), raw),
16805
+ "phase-completeness": async () => handleResult(await cmdVerifyPhaseCompleteness(cwd, args[2]), raw),
16806
+ "references": async () => handleResult(await cmdVerifyReferences(cwd, args[2]), raw),
17199
16807
  "commits": async () => handleResult(await cmdVerifyCommits(cwd, args.slice(2)), raw),
17200
- "artifacts": () => handleResult(cmdVerifyArtifacts(cwd, args[2]), raw),
17201
- "key-links": () => handleResult(cmdVerifyKeyLinks(cwd, args[2]), raw)
16808
+ "artifacts": async () => handleResult(await cmdVerifyArtifacts(cwd, args[2]), raw),
16809
+ "key-links": async () => handleResult(await cmdVerifyKeyLinks(cwd, args[2]), raw)
17202
16810
  }[sub] : void 0;
17203
16811
  if (handler) return handler();
17204
16812
  error("Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links");
@@ -17257,16 +16865,16 @@ const handleMilestone = async (args, cwd, raw) => {
17257
16865
  }), raw);
17258
16866
  } else error("Unknown milestone subcommand. Available: complete");
17259
16867
  };
17260
- const handleValidate = (args, cwd, raw) => {
16868
+ const handleValidate = async (args, cwd, raw) => {
17261
16869
  const sub = args[1];
17262
16870
  const handler = sub ? {
17263
- "consistency": () => handleResult(cmdValidateConsistency(cwd), raw),
17264
- "health": () => handleResult(cmdValidateHealth(cwd, { repair: hasFlag(args, "repair") }), raw)
16871
+ "consistency": async () => handleResult(await cmdValidateConsistency(cwd), raw),
16872
+ "health": async () => handleResult(await cmdValidateHealth(cwd, { repair: hasFlag(args, "repair") }), raw)
17265
16873
  }[sub] : void 0;
17266
16874
  if (handler) return handler();
17267
16875
  error("Unknown validate subcommand. Available: consistency, health");
17268
16876
  };
17269
- const handleDrift = (args, cwd, raw) => {
16877
+ const handleDrift = async (args, cwd, raw) => {
17270
16878
  const sub = args[1];
17271
16879
  const handler = sub ? {
17272
16880
  "read-report": () => cmdDriftReadReport(cwd),
@@ -17276,10 +16884,10 @@ const handleDrift = (args, cwd, raw) => {
17276
16884
  "write-report": () => cmdDriftWriteReport(cwd, getFlag(args, "--content"), getFlag(args, "--content-file")),
17277
16885
  "previous-hash": () => cmdDriftPreviousHash(cwd)
17278
16886
  }[sub] : void 0;
17279
- if (handler) return handleResult(handler(), raw);
16887
+ if (handler) return handleResult(await handler(), raw);
17280
16888
  error("Unknown drift subcommand. Available: read-report, extract-requirements, extract-nogos, extract-conventions, write-report, previous-hash");
17281
16889
  };
17282
- const handleInit = (args, cwd, raw) => {
16890
+ const handleInit = async (args, cwd, raw) => {
17283
16891
  const workflow = args[1];
17284
16892
  const handler = workflow ? {
17285
16893
  "execute-phase": () => cmdInitExecutePhase(cwd, args[2]),
@@ -17303,12 +16911,12 @@ const handleInit = (args, cwd, raw) => {
17303
16911
  "check-drift": () => cmdInitCheckDrift(cwd),
17304
16912
  "realign": () => cmdInitRealign(cwd, args[2])
17305
16913
  }[workflow] : void 0;
17306
- if (handler) return handleResult(handler(), raw);
16914
+ if (handler) return handleResult(await handler(), raw);
17307
16915
  error(`Unknown init workflow: ${workflow}\nAvailable: execute-phase, plan-phase, new-project, new-milestone, quick, resume, verify-work, phase-op, todos, milestone-op, map-codebase, init-existing, progress, executor, planner, researcher, verifier, debugger, check-drift, realign`);
17308
16916
  };
17309
16917
  const COMMANDS = {
17310
16918
  "state": handleState,
17311
- "resolve-model": (args, cwd, raw) => handleResult(cmdResolveModel(cwd, args[1], raw), raw),
16919
+ "resolve-model": async (args, cwd, raw) => handleResult(await cmdResolveModel(cwd, args[1], raw), raw),
17312
16920
  "find-phase": async (args, cwd, raw) => handleResult(await cmdFindPhase(cwd, args[1]), raw),
17313
16921
  "commit": async (args, cwd, raw) => {
17314
16922
  const files = args.indexOf("--files") !== -1 ? args.slice(args.indexOf("--files") + 1).filter((a) => !a.startsWith("--")) : [];
@@ -17329,7 +16937,7 @@ const COMMANDS = {
17329
16937
  "config-ensure-section": (_args, cwd, raw) => handleResult(cmdConfigEnsureSection(cwd, raw), raw),
17330
16938
  "config-set": (args, cwd, raw) => handleResult(cmdConfigSet(cwd, args[1], args[2], raw), raw),
17331
16939
  "config-get": (args, cwd, raw) => handleResult(cmdConfigGet(cwd, args[1], raw), raw),
17332
- "history-digest": (_args, cwd, raw) => handleResult(cmdHistoryDigest(cwd, raw), raw),
16940
+ "history-digest": async (_args, cwd, raw) => handleResult(await cmdHistoryDigest(cwd, raw), raw),
17333
16941
  "phases": handlePhases,
17334
16942
  "roadmap": handleRoadmap,
17335
16943
  "requirements": (args, cwd, raw) => {
@@ -17340,14 +16948,14 @@ const COMMANDS = {
17340
16948
  "milestone": handleMilestone,
17341
16949
  "validate": handleValidate,
17342
16950
  "drift": handleDrift,
17343
- "progress": (args, cwd, raw) => handleResult(cmdProgressRender(cwd, args[1] || "json", raw), raw),
16951
+ "progress": async (args, cwd, raw) => handleResult(await cmdProgressRender(cwd, args[1] || "json", raw), raw),
17344
16952
  "todo": (args, cwd, raw) => {
17345
16953
  if (args[1] === "complete") handleResult(cmdTodoComplete(cwd, args[2], raw), raw);
17346
16954
  else error("Unknown todo subcommand. Available: complete");
17347
16955
  },
17348
- "scaffold": (args, cwd, raw) => {
16956
+ "scaffold": async (args, cwd, raw) => {
17349
16957
  const f = getFlags(args, "phase", "name");
17350
- handleResult(cmdScaffold(cwd, args[1], {
16958
+ handleResult(await cmdScaffold(cwd, args[1], {
17351
16959
  phase: f.phase,
17352
16960
  name: f.name ? args.slice(args.indexOf("--name") + 1).join(" ") : null
17353
16961
  }, raw), raw);
@@ -17369,39 +16977,17 @@ const COMMANDS = {
17369
16977
  freshness: f.freshness ?? void 0
17370
16978
  }, raw), raw);
17371
16979
  },
17372
- "artefakte-read": (args, cwd, raw) => handleResult(cmdArtefakteRead(cwd, args[1], getFlag(args, "--phase") ?? void 0, raw), raw),
17373
- "artefakte-write": (args, cwd, raw) => handleResult(cmdArtefakteWrite(cwd, args[1], getFlag(args, "--content") ?? void 0, getFlag(args, "--phase") ?? void 0, raw), raw),
17374
- "artefakte-append": (args, cwd, raw) => handleResult(cmdArtefakteAppend(cwd, args[1], getFlag(args, "--entry") ?? void 0, getFlag(args, "--phase") ?? void 0, raw), raw),
17375
- "artefakte-list": (args, cwd, raw) => handleResult(cmdArtefakteList(cwd, getFlag(args, "--phase") ?? void 0, raw), raw),
17376
- "context-load": (args, cwd, raw) => handleResult(cmdContextLoad(cwd, getFlag(args, "--phase") ?? void 0, getFlag(args, "--topic") ?? void 0, hasFlag(args, "include-history")), raw),
17377
- "skill-list": (_args, cwd, raw) => handleResult(cmdSkillList(cwd), raw),
16980
+ "artefakte-read": async (args, cwd, raw) => handleResult(await cmdArtefakteRead(cwd, args[1], getFlag(args, "--phase") ?? void 0, raw), raw),
16981
+ "artefakte-write": async (args, cwd, raw) => handleResult(await cmdArtefakteWrite(cwd, args[1], getFlag(args, "--content") ?? void 0, getFlag(args, "--phase") ?? void 0, raw), raw),
16982
+ "artefakte-append": async (args, cwd, raw) => handleResult(await cmdArtefakteAppend(cwd, args[1], getFlag(args, "--entry") ?? void 0, getFlag(args, "--phase") ?? void 0, raw), raw),
16983
+ "artefakte-list": async (args, cwd, raw) => handleResult(await cmdArtefakteList(cwd, getFlag(args, "--phase") ?? void 0, raw), raw),
16984
+ "context-load": async (args, cwd, raw) => handleResult(await cmdContextLoad(cwd, getFlag(args, "--phase") ?? void 0, getFlag(args, "--topic") ?? void 0, hasFlag(args, "include-history")), raw),
16985
+ "skill-list": async (_args, cwd, raw) => handleResult(await cmdSkillList(cwd), raw),
17378
16986
  "skill-install": (args, cwd, raw) => handleResult(cmdSkillInstall(cwd, args[1]), raw),
17379
16987
  "skill-update": (args, cwd, raw) => handleResult(cmdSkillUpdate(cwd, args[1]), raw),
17380
- "start": async (args, cwd, raw) => handleResult(await cmdStart(cwd, {
17381
- noBrowser: hasFlag(args, "no-browser"),
17382
- networkMode: hasFlag(args, "network")
17383
- }), raw),
17384
- "dashboard": (args) => handleDashboard(args.slice(1)),
17385
16988
  "start-server": async () => {
17386
16989
  const serverPath = node_path.join(__dirname, "mcp-server.cjs");
17387
16990
  (0, node_child_process.spawn)(process.execPath, [serverPath], { stdio: "inherit" }).on("exit", (code) => process.exit(code ?? 0));
17388
- },
17389
- "backend-start": async (args, cwd, raw) => {
17390
- const { startBackend } = await Promise.resolve().then(() => require("./lifecycle-D8mcsEjy.cjs"));
17391
- const portFlag = args.find((a) => a.startsWith("--port="))?.split("=")[1];
17392
- const background = !args.includes("--foreground");
17393
- output(await startBackend(cwd, {
17394
- port: portFlag ? parseInt(portFlag, 10) : void 0,
17395
- background
17396
- }), raw);
17397
- },
17398
- "backend-stop": async (_args, cwd, raw) => {
17399
- const { stopBackend } = await Promise.resolve().then(() => require("./lifecycle-D8mcsEjy.cjs"));
17400
- output({ stopped: await stopBackend(cwd) }, raw);
17401
- },
17402
- "backend-status": async (_args, cwd, raw) => {
17403
- const { getBackendStatus } = await Promise.resolve().then(() => require("./lifecycle-D8mcsEjy.cjs"));
17404
- output(await getBackendStatus(cwd) || { running: false }, raw);
17405
16991
  }
17406
16992
  };
17407
16993
  async function main() {
@@ -17442,84 +17028,7 @@ async function main() {
17442
17028
  throw thrown;
17443
17029
  }
17444
17030
  }
17445
- /**
17446
- * Dashboard launch command.
17447
- *
17448
- * Spawns the dashboard as a detached subprocess with MAXSIM_PROJECT_CWD set.
17449
- * If the dashboard is already running (detected via /api/health), prints the URL.
17450
- * Supports --stop to kill a running instance.
17451
- */
17452
- async function handleDashboard(args) {
17453
- const networkMode = args.includes("--network");
17454
- if (args.includes("--stop")) {
17455
- for (let port = DEFAULT_PORT; port <= PORT_RANGE_END; port++) if (await checkHealth(port)) {
17456
- console.log(`Dashboard found on port ${port} — stopping...`);
17457
- killProcessOnPort(port);
17458
- console.log("Dashboard stopped.");
17459
- return;
17460
- }
17461
- console.log("No running dashboard found.");
17462
- return;
17463
- }
17464
- const runningPort = await findRunningDashboard();
17465
- if (runningPort) {
17466
- console.log(`Dashboard already running at http://localhost:${runningPort}`);
17467
- return;
17468
- }
17469
- const serverPath = resolveDashboardServer();
17470
- if (!serverPath) {
17471
- console.error("Could not find @maxsim/dashboard server entry point.");
17472
- console.error("Ensure @maxsim/dashboard is installed and built.");
17473
- process.exit(1);
17474
- }
17475
- const serverDir = node_path.dirname(serverPath);
17476
- const dashConfig = readDashboardConfig(serverPath);
17477
- console.log("Installing node-pty for terminal support...");
17478
- if (!ensureNodePty(serverDir)) console.warn("node-pty installation failed — terminal will be unavailable.");
17479
- console.log("Dashboard starting...");
17480
- const pid = spawnDashboard({
17481
- serverPath,
17482
- projectCwd: dashConfig.projectCwd,
17483
- networkMode
17484
- });
17485
- await new Promise((resolve) => setTimeout(resolve, 3e3));
17486
- const readyPort = await findRunningDashboard();
17487
- if (readyPort) {
17488
- console.log(`Dashboard ready at http://localhost:${readyPort}`);
17489
- return;
17490
- }
17491
- console.log(`Dashboard spawned (PID ${pid}). It may take a moment to start.`);
17492
- console.log(`Check http://localhost:${DEFAULT_PORT} once ready.`);
17493
- }
17494
17031
  main();
17495
17032
 
17496
17033
  //#endregion
17497
- exports.__commonJSMin = __commonJSMin;
17498
- exports.__toESM = __toESM;
17499
- exports.appendToStateSection = appendToStateSection;
17500
- exports.cmdConfigGet = cmdConfigGet;
17501
- exports.cmdConfigSet = cmdConfigSet;
17502
- exports.cmdContextLoad = cmdContextLoad;
17503
- exports.cmdRoadmapAnalyze = cmdRoadmapAnalyze;
17504
- exports.comparePhaseNum = comparePhaseNum;
17505
- exports.escapeStringRegexp = escapeStringRegexp;
17506
- exports.extractFrontmatter = extractFrontmatter;
17507
- exports.findPhaseInternal = findPhaseInternal;
17508
- exports.generateSlugInternal = generateSlugInternal;
17509
- exports.getArchivedPhaseDirs = getArchivedPhaseDirs;
17510
- exports.getPhasePattern = getPhasePattern;
17511
- exports.listSubDirs = listSubDirs;
17512
- exports.loadConfig = loadConfig;
17513
- exports.normalizePhaseName = normalizePhaseName;
17514
- exports.parseTodoFrontmatter = parseTodoFrontmatter;
17515
- exports.phaseAddCore = phaseAddCore;
17516
- exports.phaseCompleteCore = phaseCompleteCore;
17517
- exports.phaseInsertCore = phaseInsertCore;
17518
- exports.phasesPath = phasesPath;
17519
- exports.planningPath = planningPath;
17520
- exports.safeReadFile = safeReadFile;
17521
- exports.stateExtractField = stateExtractField;
17522
- exports.statePath = statePath;
17523
- exports.stateReplaceField = stateReplaceField;
17524
- exports.todayISO = todayISO;
17525
17034
  //# sourceMappingURL=cli.cjs.map