maxsimcli 4.15.4 → 4.16.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/assets/CHANGELOG.md +7 -0
- package/dist/assets/templates/agents/AGENTS.md +1 -1
- package/dist/assets/templates/agents/executor.md +1 -1
- package/dist/assets/templates/agents/planner.md +4 -4
- package/dist/assets/templates/workflows/execute-phase.md +6 -22
- package/dist/assets/templates/workflows/execute-plan.md +8 -31
- package/dist/assets/templates/workflows/execute.md +7 -9
- package/dist/assets/templates/workflows/go.md +2 -2
- package/dist/assets/templates/workflows/progress.md +10 -11
- package/dist/assets/templates/workflows/sdd.md +29 -28
- package/dist/cli.cjs +6901 -6442
- package/dist/cli.cjs.map +1 -1
- package/dist/core-D5zUr9cb.cjs.map +1 -1
- package/dist/mcp-server.cjs +184 -53
- package/dist/mcp-server.cjs.map +1 -1
- package/dist/skills-CjFWZIGM.cjs.map +1 -1
- package/package.json +1 -1
package/dist/mcp-server.cjs
CHANGED
|
@@ -7,6 +7,19 @@ var __getOwnPropNames$1 = Object.getOwnPropertyNames;
|
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
9
9
|
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
10
|
+
var __exportAll = (all, no_symbols) => {
|
|
11
|
+
let target = {};
|
|
12
|
+
for (var name in all) {
|
|
13
|
+
__defProp$1(target, name, {
|
|
14
|
+
get: all[name],
|
|
15
|
+
enumerable: true
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
if (!no_symbols) {
|
|
19
|
+
__defProp$1(target, Symbol.toStringTag, { value: "Module" });
|
|
20
|
+
}
|
|
21
|
+
return target;
|
|
22
|
+
};
|
|
10
23
|
var __copyProps$1 = (to, from, except, desc) => {
|
|
11
24
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
25
|
for (var keys = __getOwnPropNames$1(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
@@ -26765,8 +26778,9 @@ function configPath(cwd) {
|
|
|
26765
26778
|
function phasesPath(cwd) {
|
|
26766
26779
|
return planningPath(cwd, "phases");
|
|
26767
26780
|
}
|
|
26768
|
-
/** Phase-file predicates. */
|
|
26781
|
+
/** Phase-file predicates. @deprecated Use GitHub Issues for plan/summary tracking. Local fallback only. */
|
|
26769
26782
|
const isPlanFile = (f) => f.endsWith("-PLAN.md") || f === "PLAN.md";
|
|
26783
|
+
/** @deprecated Use GitHub Issues for plan/summary tracking. Local fallback only. */
|
|
26770
26784
|
const isSummaryFile = (f) => f.endsWith("-SUMMARY.md") || f === "SUMMARY.md";
|
|
26771
26785
|
/** Strip suffix to get plan/summary ID. */
|
|
26772
26786
|
const planId = (f) => f.replace("-PLAN.md", "").replace("PLAN.md", "");
|
|
@@ -27005,10 +27019,19 @@ async function searchPhaseInDir(baseDir, relBase, normalized) {
|
|
|
27005
27019
|
}
|
|
27006
27020
|
async function findPhaseInternal(cwd, phase) {
|
|
27007
27021
|
if (!phase) return null;
|
|
27008
|
-
const pd = phasesPath(cwd);
|
|
27009
27022
|
const normalized = normalizePhaseName(phase);
|
|
27010
|
-
|
|
27011
|
-
|
|
27023
|
+
try {
|
|
27024
|
+
const { findPhaseFromGitHub } = await Promise.resolve().then(() => sync_exports);
|
|
27025
|
+
const ghResult = await findPhaseFromGitHub(cwd, normalized);
|
|
27026
|
+
if (ghResult) return ghResult;
|
|
27027
|
+
} catch {
|
|
27028
|
+
debugLog("find-phase-github-fallback", "GitHub lookup failed, falling back to local");
|
|
27029
|
+
}
|
|
27030
|
+
const current = await searchPhaseInDir(phasesPath(cwd), node_path.default.join(".planning", "phases"), normalized);
|
|
27031
|
+
if (current) {
|
|
27032
|
+
current.source = "local";
|
|
27033
|
+
return current;
|
|
27034
|
+
}
|
|
27012
27035
|
const archiveDir = planningPath(cwd, "archive");
|
|
27013
27036
|
if (await pathExistsInternal(archiveDir)) try {
|
|
27014
27037
|
const versionDirs = (await node_fs.promises.readdir(archiveDir, { withFileTypes: true })).filter((e) => e.isDirectory()).map((e) => e.name).sort().reverse();
|
|
@@ -27016,6 +27039,7 @@ async function findPhaseInternal(cwd, phase) {
|
|
|
27016
27039
|
const result = await searchPhaseInDir(node_path.default.join(archiveDir, versionName), node_path.default.join(".planning", "archive", versionName), normalized);
|
|
27017
27040
|
if (result) {
|
|
27018
27041
|
result.archived = versionName;
|
|
27042
|
+
result.source = "local";
|
|
27019
27043
|
return result;
|
|
27020
27044
|
}
|
|
27021
27045
|
}
|
|
@@ -33727,10 +33751,7 @@ function cmdErr(error) {
|
|
|
33727
33751
|
*
|
|
33728
33752
|
* Ported from maxsim/bin/lib/phase.cjs
|
|
33729
33753
|
*/
|
|
33730
|
-
async function scaffoldPhaseStubs(
|
|
33731
|
-
const today = todayISO();
|
|
33732
|
-
await Promise.all([node_fs.promises.writeFile(node_path.default.join(dirPath, `${phaseId}-CONTEXT.md`), `# Phase ${phaseId} Context: ${name}\n\n**Created:** ${today}\n**Phase goal:** [To be defined during /maxsim:discuss-phase]\n\n---\n\n_Context will be populated by /maxsim:discuss-phase_\n`), node_fs.promises.writeFile(node_path.default.join(dirPath, `${phaseId}-RESEARCH.md`), `# Phase ${phaseId}: ${name} - Research\n\n**Researched:** Not yet\n**Domain:** TBD\n**Confidence:** TBD\n\n---\n\n_Research will be populated by /maxsim:research-phase_\n`)]);
|
|
33733
|
-
}
|
|
33754
|
+
async function scaffoldPhaseStubs(_dirPath, _phaseId, _name) {}
|
|
33734
33755
|
async function phaseAddCore(cwd, description, options) {
|
|
33735
33756
|
const rmPath = roadmapPath(cwd);
|
|
33736
33757
|
let content;
|
|
@@ -33753,7 +33774,7 @@ async function phaseAddCore(cwd, description, options) {
|
|
|
33753
33774
|
const dirPath = planningPath(cwd, "phases", dirName);
|
|
33754
33775
|
await node_fs.promises.mkdir(dirPath, { recursive: true });
|
|
33755
33776
|
await node_fs.promises.writeFile(node_path.default.join(dirPath, ".gitkeep"), "");
|
|
33756
|
-
if (options?.includeStubs) await scaffoldPhaseStubs(dirPath, paddedNum, description);
|
|
33777
|
+
if (options?.includeStubs) await /* @__PURE__ */ scaffoldPhaseStubs(dirPath, paddedNum, description);
|
|
33757
33778
|
const phaseEntry = `\n### Phase ${newPhaseNum}: ${description}\n\n**Goal:** [To be planned]\n**Requirements**: TBD\n**Depends on:** Phase ${maxPhase}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /maxsim:plan ${newPhaseNum} to break down)\n`;
|
|
33758
33779
|
let updatedContent;
|
|
33759
33780
|
const lastSeparator = content.lastIndexOf("\n---");
|
|
@@ -33797,7 +33818,7 @@ async function phaseInsertCore(cwd, afterPhase, description, options) {
|
|
|
33797
33818
|
const dirPath = planningPath(cwd, "phases", dirName);
|
|
33798
33819
|
await node_fs.promises.mkdir(dirPath, { recursive: true });
|
|
33799
33820
|
await node_fs.promises.writeFile(node_path.default.join(dirPath, ".gitkeep"), "");
|
|
33800
|
-
if (options?.includeStubs) await scaffoldPhaseStubs(dirPath, decimalPhase, description);
|
|
33821
|
+
if (options?.includeStubs) await /* @__PURE__ */ scaffoldPhaseStubs(dirPath, decimalPhase, description);
|
|
33801
33822
|
const phaseEntry = `\n### Phase ${decimalPhase}: ${description} (INSERTED)\n\n**Goal:** [Urgent work - to be planned]\n**Requirements**: TBD\n**Depends on:** Phase ${afterPhase}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /maxsim:plan ${decimalPhase} to break down)\n`;
|
|
33802
33823
|
const headerPattern = new RegExp(`(#{2,4}\\s*Phase\\s+0*${afterPhaseEscaped}:[^\\n]*\\n)`, "i");
|
|
33803
33824
|
const headerMatch = content.match(headerPattern);
|
|
@@ -38806,48 +38827,6 @@ function escapeStringRegexp(string) {
|
|
|
38806
38827
|
return string.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
|
|
38807
38828
|
}
|
|
38808
38829
|
|
|
38809
|
-
//#endregion
|
|
38810
|
-
//#region src/core/state.ts
|
|
38811
|
-
/**
|
|
38812
|
-
* State — STATE.md operations and progression engine
|
|
38813
|
-
*
|
|
38814
|
-
* Ported from maxsim/bin/lib/state.cjs
|
|
38815
|
-
*/
|
|
38816
|
-
function stateExtractField(content, fieldName) {
|
|
38817
|
-
const escaped = escapeStringRegexp(fieldName);
|
|
38818
|
-
const boldPattern = new RegExp(`\\*\\*\\s*${escaped}\\s*:\\s*\\*\\*\\s*(.+)`, "i");
|
|
38819
|
-
const boldMatch = content.match(boldPattern);
|
|
38820
|
-
if (boldMatch) return boldMatch[1].trim();
|
|
38821
|
-
const plainPattern = new RegExp(`^\\s*${escaped}\\s*:\\s*(.+)`, "im");
|
|
38822
|
-
const plainMatch = content.match(plainPattern);
|
|
38823
|
-
return plainMatch ? plainMatch[1].trim() : null;
|
|
38824
|
-
}
|
|
38825
|
-
function stateReplaceField(content, fieldName, newValue) {
|
|
38826
|
-
const escaped = escapeStringRegexp(fieldName);
|
|
38827
|
-
const boldPattern = new RegExp(`(\\*\\*\\s*${escaped}\\s*:\\s*\\*\\*\\s*)(.*)`, "i");
|
|
38828
|
-
let replaced = content.replace(boldPattern, (_match, prefix) => `${prefix}${newValue}`);
|
|
38829
|
-
if (replaced !== content) return replaced;
|
|
38830
|
-
const plainPattern = new RegExp(`(^[ \\t]*${escaped}\\s*:\\s*)(.*)`, "im");
|
|
38831
|
-
replaced = content.replace(plainPattern, (_match, prefix) => `${prefix}${newValue}`);
|
|
38832
|
-
return replaced !== content ? replaced : null;
|
|
38833
|
-
}
|
|
38834
|
-
/**
|
|
38835
|
-
* Append an entry to a section in STATE.md content, removing placeholder text.
|
|
38836
|
-
* Returns updated content or null if section not found.
|
|
38837
|
-
*/
|
|
38838
|
-
function appendToStateSection(content, sectionPattern, entry, placeholderPatterns) {
|
|
38839
|
-
const match = content.match(sectionPattern);
|
|
38840
|
-
if (!match) return null;
|
|
38841
|
-
let sectionBody = match[2];
|
|
38842
|
-
for (const pat of placeholderPatterns || [
|
|
38843
|
-
/None yet\.?\s*\n?/gi,
|
|
38844
|
-
/No decisions yet\.?\s*\n?/gi,
|
|
38845
|
-
/None\.?\s*\n?/gi
|
|
38846
|
-
]) sectionBody = sectionBody.replace(pat, "");
|
|
38847
|
-
sectionBody = sectionBody.trimEnd() + "\n" + entry + "\n";
|
|
38848
|
-
return content.replace(sectionPattern, (_m, header) => `${header}${sectionBody}`);
|
|
38849
|
-
}
|
|
38850
|
-
|
|
38851
38830
|
//#endregion
|
|
38852
38831
|
//#region src/github/sync.ts
|
|
38853
38832
|
/**
|
|
@@ -38866,6 +38845,12 @@ function appendToStateSection(content, sectionPattern, entry, placeholderPattern
|
|
|
38866
38845
|
* CRITICAL: All operations use client.ts (Octokit adapter) exclusively.
|
|
38867
38846
|
* CRITICAL: Never call process.exit() — return GhResult instead.
|
|
38868
38847
|
*/
|
|
38848
|
+
var sync_exports = /* @__PURE__ */ __exportAll({
|
|
38849
|
+
checkPhaseProgress: () => checkPhaseProgress,
|
|
38850
|
+
detectInterruptedPhase: () => detectInterruptedPhase,
|
|
38851
|
+
findPhaseFromGitHub: () => findPhaseFromGitHub,
|
|
38852
|
+
getAllPhasesProgress: () => getAllPhasesProgress
|
|
38853
|
+
});
|
|
38869
38854
|
/**
|
|
38870
38855
|
* Get the progress of a phase by counting open/closed sub-issues.
|
|
38871
38856
|
*
|
|
@@ -38983,6 +38968,130 @@ async function getAllPhasesProgress() {
|
|
|
38983
38968
|
return results;
|
|
38984
38969
|
});
|
|
38985
38970
|
}
|
|
38971
|
+
/**
|
|
38972
|
+
* Populate a PhaseSearchResult from GitHub Issues data.
|
|
38973
|
+
*
|
|
38974
|
+
* Looks up the phase in the local mapping cache, then queries GitHub for
|
|
38975
|
+
* sub-issue counts and comments to derive plans/summaries/research status.
|
|
38976
|
+
*
|
|
38977
|
+
* Returns null if:
|
|
38978
|
+
* - No mapping file exists
|
|
38979
|
+
* - Phase not found in mapping
|
|
38980
|
+
* - GitHub API call fails
|
|
38981
|
+
*
|
|
38982
|
+
* @param cwd - Project root directory
|
|
38983
|
+
* @param phaseNum - Normalized phase number (e.g., "01", "02A")
|
|
38984
|
+
*/
|
|
38985
|
+
async function findPhaseFromGitHub(cwd, phaseNum) {
|
|
38986
|
+
let mapping;
|
|
38987
|
+
try {
|
|
38988
|
+
mapping = loadMapping(cwd);
|
|
38989
|
+
} catch {
|
|
38990
|
+
return null;
|
|
38991
|
+
}
|
|
38992
|
+
if (!mapping) return null;
|
|
38993
|
+
const phaseMapping = mapping.phases[phaseNum];
|
|
38994
|
+
if (!phaseMapping) return null;
|
|
38995
|
+
const issueNumber = phaseMapping.tracking_issue.number;
|
|
38996
|
+
if (!issueNumber) return null;
|
|
38997
|
+
const progressResult = await checkPhaseProgress(issueNumber);
|
|
38998
|
+
if (!progressResult.ok) return null;
|
|
38999
|
+
const { tasks, completed, total } = progressResult.data;
|
|
39000
|
+
let phaseName = null;
|
|
39001
|
+
let phaseSlug = null;
|
|
39002
|
+
try {
|
|
39003
|
+
const octokit = getOctokit();
|
|
39004
|
+
const { owner, repo } = await getRepoInfo();
|
|
39005
|
+
const titleMatch = (await octokit.rest.issues.get({
|
|
39006
|
+
owner,
|
|
39007
|
+
repo,
|
|
39008
|
+
issue_number: issueNumber
|
|
39009
|
+
})).data.title.match(/\[Phase\s+\S+\]\s*(.*)/);
|
|
39010
|
+
if (titleMatch) {
|
|
39011
|
+
phaseName = titleMatch[1].trim();
|
|
39012
|
+
phaseSlug = phaseName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
39013
|
+
}
|
|
39014
|
+
} catch {}
|
|
39015
|
+
const planNames = tasks.map((t) => `task-${t.number}`);
|
|
39016
|
+
const summaryNames = tasks.filter((t) => t.state === "closed").map((t) => `task-${t.number}`);
|
|
39017
|
+
const completedSet = new Set(summaryNames);
|
|
39018
|
+
const incompletePlans = planNames.filter((p) => !completedSet.has(p));
|
|
39019
|
+
let hasResearch = false;
|
|
39020
|
+
let hasContext = false;
|
|
39021
|
+
let hasVerification = false;
|
|
39022
|
+
try {
|
|
39023
|
+
const octokit = getOctokit();
|
|
39024
|
+
const { owner, repo } = await getRepoInfo();
|
|
39025
|
+
const comments = await octokit.rest.issues.listComments({
|
|
39026
|
+
owner,
|
|
39027
|
+
repo,
|
|
39028
|
+
issue_number: issueNumber,
|
|
39029
|
+
per_page: 100
|
|
39030
|
+
});
|
|
39031
|
+
for (const comment of comments.data) {
|
|
39032
|
+
const body = comment.body ?? "";
|
|
39033
|
+
if (body.includes("<!-- maxsim:type=research -->") || body.includes("## Research") || body.startsWith("## Phase") && body.includes("Research")) hasResearch = true;
|
|
39034
|
+
if (body.includes("<!-- maxsim:type=context -->") || body.includes("## Context")) hasContext = true;
|
|
39035
|
+
if (body.includes("<!-- maxsim:type=verification -->") || body.includes("## Verification")) hasVerification = true;
|
|
39036
|
+
}
|
|
39037
|
+
} catch {}
|
|
39038
|
+
return {
|
|
39039
|
+
found: true,
|
|
39040
|
+
directory: `.planning/phases/${phaseNum}-${phaseSlug || "unknown"}`,
|
|
39041
|
+
phase_number: phaseNum,
|
|
39042
|
+
phase_name: phaseName,
|
|
39043
|
+
phase_slug: phaseSlug,
|
|
39044
|
+
plans: planNames,
|
|
39045
|
+
summaries: summaryNames,
|
|
39046
|
+
incomplete_plans: incompletePlans,
|
|
39047
|
+
has_research: hasResearch,
|
|
39048
|
+
has_context: hasContext,
|
|
39049
|
+
has_verification: hasVerification,
|
|
39050
|
+
source: "github"
|
|
39051
|
+
};
|
|
39052
|
+
}
|
|
39053
|
+
|
|
39054
|
+
//#endregion
|
|
39055
|
+
//#region src/core/state.ts
|
|
39056
|
+
/**
|
|
39057
|
+
* State — STATE.md operations and progression engine
|
|
39058
|
+
*
|
|
39059
|
+
* Ported from maxsim/bin/lib/state.cjs
|
|
39060
|
+
*/
|
|
39061
|
+
function stateExtractField(content, fieldName) {
|
|
39062
|
+
const escaped = escapeStringRegexp(fieldName);
|
|
39063
|
+
const boldPattern = new RegExp(`\\*\\*\\s*${escaped}\\s*:\\s*\\*\\*\\s*(.+)`, "i");
|
|
39064
|
+
const boldMatch = content.match(boldPattern);
|
|
39065
|
+
if (boldMatch) return boldMatch[1].trim();
|
|
39066
|
+
const plainPattern = new RegExp(`^\\s*${escaped}\\s*:\\s*(.+)`, "im");
|
|
39067
|
+
const plainMatch = content.match(plainPattern);
|
|
39068
|
+
return plainMatch ? plainMatch[1].trim() : null;
|
|
39069
|
+
}
|
|
39070
|
+
function stateReplaceField(content, fieldName, newValue) {
|
|
39071
|
+
const escaped = escapeStringRegexp(fieldName);
|
|
39072
|
+
const boldPattern = new RegExp(`(\\*\\*\\s*${escaped}\\s*:\\s*\\*\\*\\s*)(.*)`, "i");
|
|
39073
|
+
let replaced = content.replace(boldPattern, (_match, prefix) => `${prefix}${newValue}`);
|
|
39074
|
+
if (replaced !== content) return replaced;
|
|
39075
|
+
const plainPattern = new RegExp(`(^[ \\t]*${escaped}\\s*:\\s*)(.*)`, "im");
|
|
39076
|
+
replaced = content.replace(plainPattern, (_match, prefix) => `${prefix}${newValue}`);
|
|
39077
|
+
return replaced !== content ? replaced : null;
|
|
39078
|
+
}
|
|
39079
|
+
/**
|
|
39080
|
+
* Append an entry to a section in STATE.md content, removing placeholder text.
|
|
39081
|
+
* Returns updated content or null if section not found.
|
|
39082
|
+
*/
|
|
39083
|
+
function appendToStateSection(content, sectionPattern, entry, placeholderPatterns) {
|
|
39084
|
+
const match = content.match(sectionPattern);
|
|
39085
|
+
if (!match) return null;
|
|
39086
|
+
let sectionBody = match[2];
|
|
39087
|
+
for (const pat of placeholderPatterns || [
|
|
39088
|
+
/None yet\.?\s*\n?/gi,
|
|
39089
|
+
/No decisions yet\.?\s*\n?/gi,
|
|
39090
|
+
/None\.?\s*\n?/gi
|
|
39091
|
+
]) sectionBody = sectionBody.replace(pat, "");
|
|
39092
|
+
sectionBody = sectionBody.trimEnd() + "\n" + entry + "\n";
|
|
39093
|
+
return content.replace(sectionPattern, (_m, header) => `${header}${sectionBody}`);
|
|
39094
|
+
}
|
|
38986
39095
|
|
|
38987
39096
|
//#endregion
|
|
38988
39097
|
//#region src/mcp/state-tools.ts
|
|
@@ -39279,6 +39388,20 @@ async function cmdRoadmapAnalyze(cwd) {
|
|
|
39279
39388
|
checkboxPattern: new RegExp(`-\\s*\\[(x| )\\]\\s*.*Phase\\s+${phaseNum.replace(".", "\\.")}`, "i")
|
|
39280
39389
|
});
|
|
39281
39390
|
}
|
|
39391
|
+
let ghPhaseProgress = null;
|
|
39392
|
+
try {
|
|
39393
|
+
const mapping = loadMapping(cwd);
|
|
39394
|
+
if (mapping && Object.keys(mapping.phases).length > 0) {
|
|
39395
|
+
const ghResult = await getAllPhasesProgress();
|
|
39396
|
+
if (ghResult.ok) {
|
|
39397
|
+
ghPhaseProgress = /* @__PURE__ */ new Map();
|
|
39398
|
+
for (const entry of ghResult.data) ghPhaseProgress.set(entry.phaseNumber, {
|
|
39399
|
+
total: entry.progress.total,
|
|
39400
|
+
completed: entry.progress.completed
|
|
39401
|
+
});
|
|
39402
|
+
}
|
|
39403
|
+
}
|
|
39404
|
+
} catch {}
|
|
39282
39405
|
let allDirs = [];
|
|
39283
39406
|
try {
|
|
39284
39407
|
allDirs = await listSubDirs(phasesDir);
|
|
@@ -39289,7 +39412,15 @@ async function cmdRoadmapAnalyze(cwd) {
|
|
|
39289
39412
|
let summaryCount = 0;
|
|
39290
39413
|
let hasContext = false;
|
|
39291
39414
|
let hasResearch = false;
|
|
39292
|
-
|
|
39415
|
+
const ghData = ghPhaseProgress?.get(p.phaseNum);
|
|
39416
|
+
if (ghData) {
|
|
39417
|
+
planCount = ghData.total;
|
|
39418
|
+
summaryCount = ghData.completed;
|
|
39419
|
+
if (summaryCount >= planCount && planCount > 0) diskStatus = "complete";
|
|
39420
|
+
else if (summaryCount > 0) diskStatus = "partial";
|
|
39421
|
+
else if (planCount > 0) diskStatus = "planned";
|
|
39422
|
+
else diskStatus = "empty";
|
|
39423
|
+
} else try {
|
|
39293
39424
|
const dirMatch = allDirs.find((d) => d.startsWith(p.normalized + "-") || d === p.normalized);
|
|
39294
39425
|
if (dirMatch) {
|
|
39295
39426
|
const phaseFiles = await node_fs.promises.readdir(node_path.default.join(phasesDir, dirMatch));
|