dlw-machine-setup 0.4.1 → 0.4.2
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/bin/installer.js +55 -8
- package/package.json +1 -1
package/bin/installer.js
CHANGED
|
@@ -3811,10 +3811,37 @@ function downgradeHeadings(content) {
|
|
|
3811
3811
|
return line.replace(/^(#{1,5}) /, "$1# ");
|
|
3812
3812
|
}).join("\n");
|
|
3813
3813
|
}
|
|
3814
|
+
function collectMdFiles(dir) {
|
|
3815
|
+
if (!(0, import_fs4.existsSync)(dir)) return [];
|
|
3816
|
+
const entries = (0, import_fs4.readdirSync)(dir, { recursive: true });
|
|
3817
|
+
return entries.filter((entry) => {
|
|
3818
|
+
const fullPath = (0, import_path4.join)(dir, entry);
|
|
3819
|
+
return entry.endsWith(".md") && (0, import_fs4.statSync)(fullPath).isFile() && !entry.toLowerCase().endsWith(SNIPPET_FILENAME);
|
|
3820
|
+
}).map((entry) => entry.replace(/\\/g, "/")).sort();
|
|
3821
|
+
}
|
|
3822
|
+
function extractFirstHeading(filePath) {
|
|
3823
|
+
try {
|
|
3824
|
+
const content = (0, import_fs4.readFileSync)(filePath, "utf-8");
|
|
3825
|
+
const withoutFrontmatter = content.replace(/^---[\s\S]*?---\s*/, "");
|
|
3826
|
+
const match = withoutFrontmatter.match(/^#\s+(.+)/m);
|
|
3827
|
+
if (match) {
|
|
3828
|
+
return match[1].replace(/^[\p{Emoji_Presentation}\p{Extended_Pictographic}\s]+/u, "").trim();
|
|
3829
|
+
}
|
|
3830
|
+
} catch {
|
|
3831
|
+
}
|
|
3832
|
+
const basename = filePath.split(/[/\\]/).pop() ?? "";
|
|
3833
|
+
return basename.replace(/\.md$/i, "").replace(/[-_]+/g, " ");
|
|
3834
|
+
}
|
|
3814
3835
|
function buildWorkflowSection(domains) {
|
|
3815
3836
|
const sections = [];
|
|
3837
|
+
const generalSnippet = (0, import_path4.join)(CONTEXTS_DIR, "GENERAL", SNIPPET_FILENAME);
|
|
3838
|
+
if ((0, import_fs4.existsSync)(generalSnippet)) {
|
|
3839
|
+
const raw = (0, import_fs4.readFileSync)(generalSnippet, "utf-8").trim();
|
|
3840
|
+
if (raw) sections.push(downgradeHeadings(raw));
|
|
3841
|
+
}
|
|
3816
3842
|
for (const domain of domains) {
|
|
3817
3843
|
const domainUpper = domain.toUpperCase();
|
|
3844
|
+
if (domainUpper === "GENERAL") continue;
|
|
3818
3845
|
const snippetPath = (0, import_path4.join)(CONTEXTS_DIR, domainUpper, SNIPPET_FILENAME);
|
|
3819
3846
|
if (!(0, import_fs4.existsSync)(snippetPath)) continue;
|
|
3820
3847
|
const raw = (0, import_fs4.readFileSync)(snippetPath, "utf-8").trim();
|
|
@@ -3862,27 +3889,47 @@ function buildContextRefsSection(domains) {
|
|
|
3862
3889
|
`Domain-specific guidelines and reference material are available in the \`_ai-context/\` folder:`,
|
|
3863
3890
|
``
|
|
3864
3891
|
];
|
|
3892
|
+
let hasAnyFiles = false;
|
|
3865
3893
|
for (const domain of domains) {
|
|
3866
3894
|
const domainUpper = domain.toUpperCase();
|
|
3867
3895
|
const domainPath = (0, import_path4.join)(CONTEXTS_DIR, domainUpper);
|
|
3868
3896
|
if (!(0, import_fs4.existsSync)(domainPath)) continue;
|
|
3869
|
-
|
|
3897
|
+
const domainFiles = [];
|
|
3870
3898
|
const instructionsMd = (0, import_path4.join)(domainPath, "core", "instructions.md");
|
|
3871
3899
|
if ((0, import_fs4.existsSync)(instructionsMd)) {
|
|
3872
|
-
|
|
3900
|
+
const desc = extractFirstHeading(instructionsMd);
|
|
3901
|
+
domainFiles.push(`- \`_ai-context/${domainUpper}/core/instructions.md\` \u2014 ${desc} (start here)`);
|
|
3873
3902
|
}
|
|
3874
|
-
const
|
|
3875
|
-
if ((0, import_fs4.existsSync)(
|
|
3876
|
-
|
|
3903
|
+
const coreDir = (0, import_path4.join)(domainPath, "core");
|
|
3904
|
+
if ((0, import_fs4.existsSync)(coreDir)) {
|
|
3905
|
+
const coreFiles = collectMdFiles(coreDir).filter((f) => f !== "instructions.md" && !f.startsWith("instructions/"));
|
|
3906
|
+
for (const file of coreFiles) {
|
|
3907
|
+
const desc = extractFirstHeading((0, import_path4.join)(coreDir, file));
|
|
3908
|
+
domainFiles.push(`- \`_ai-context/${domainUpper}/core/${file}\` \u2014 ${desc}`);
|
|
3909
|
+
}
|
|
3877
3910
|
}
|
|
3878
3911
|
const refDir = (0, import_path4.join)(domainPath, "reference");
|
|
3879
3912
|
if ((0, import_fs4.existsSync)(refDir)) {
|
|
3880
|
-
|
|
3913
|
+
const refFiles = collectMdFiles(refDir);
|
|
3914
|
+
if (refFiles.length > 0) {
|
|
3915
|
+
domainFiles.push(``);
|
|
3916
|
+
domainFiles.push(`**Reference & cheat sheets:**`);
|
|
3917
|
+
for (const file of refFiles) {
|
|
3918
|
+
const desc = extractFirstHeading((0, import_path4.join)(refDir, file));
|
|
3919
|
+
domainFiles.push(`- \`_ai-context/${domainUpper}/reference/${file}\` \u2014 ${desc}`);
|
|
3920
|
+
}
|
|
3921
|
+
}
|
|
3881
3922
|
}
|
|
3923
|
+
if (domainFiles.length === 0) continue;
|
|
3924
|
+
hasAnyFiles = true;
|
|
3925
|
+
lines2.push(`### ${domainUpper}`);
|
|
3926
|
+
lines2.push(...domainFiles);
|
|
3927
|
+
lines2.push(``);
|
|
3928
|
+
}
|
|
3929
|
+
if (hasAnyFiles) {
|
|
3930
|
+
lines2.push(`**ALWAYS** read \`core/instructions.md\` for a domain before implementing features. Consult reference files when the topic is directly relevant.`);
|
|
3882
3931
|
lines2.push(``);
|
|
3883
3932
|
}
|
|
3884
|
-
lines2.push(`**ALWAYS** consult these files before implementing features or making architectural decisions.`);
|
|
3885
|
-
lines2.push(``);
|
|
3886
3933
|
return lines2.join("\n");
|
|
3887
3934
|
}
|
|
3888
3935
|
function buildCombinedInstructions(domains, mcpConfig) {
|