dlw-machine-setup 0.4.1 → 0.4.3

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.
Files changed (2) hide show
  1. package/bin/installer.js +50 -44
  2. package/package.json +1 -1
package/bin/installer.js CHANGED
@@ -3783,7 +3783,6 @@ var import_path4 = require("path");
3783
3783
  var CONTEXTS_DIR = (0, import_path4.join)(process.cwd(), "_ai-context");
3784
3784
  var MARKER_START = "<!-- one-shot-installer:start -->";
3785
3785
  var MARKER_END = "<!-- one-shot-installer:end -->";
3786
- var SNIPPET_FILENAME = "context-instructions.md";
3787
3786
  function upsertBlock(filePath, block) {
3788
3787
  const marked = `${MARKER_START}
3789
3788
  ${block}
@@ -3803,35 +3802,26 @@ ${MARKER_END}`;
3803
3802
  (0, import_fs4.writeFileSync)(filePath, existing + separator + marked, "utf-8");
3804
3803
  }
3805
3804
  }
3806
- function downgradeHeadings(content) {
3807
- let inCodeBlock = false;
3808
- return content.split("\n").map((line) => {
3809
- if (/^ {0,3}```/.test(line)) inCodeBlock = !inCodeBlock;
3810
- if (inCodeBlock) return line;
3811
- return line.replace(/^(#{1,5}) /, "$1# ");
3812
- }).join("\n");
3813
- }
3814
- function buildWorkflowSection(domains) {
3815
- const sections = [];
3816
- for (const domain of domains) {
3817
- const domainUpper = domain.toUpperCase();
3818
- const snippetPath = (0, import_path4.join)(CONTEXTS_DIR, domainUpper, SNIPPET_FILENAME);
3819
- if (!(0, import_fs4.existsSync)(snippetPath)) continue;
3820
- const raw = (0, import_fs4.readFileSync)(snippetPath, "utf-8").trim();
3821
- if (!raw) continue;
3822
- sections.push(downgradeHeadings(raw));
3823
- }
3824
- return sections.length > 0 ? sections.join("\n\n") + "\n" : "";
3805
+ function collectMdFiles(dir) {
3806
+ if (!(0, import_fs4.existsSync)(dir)) return [];
3807
+ const entries = (0, import_fs4.readdirSync)(dir, { recursive: true });
3808
+ return entries.filter((entry) => {
3809
+ const fullPath = (0, import_path4.join)(dir, entry);
3810
+ return entry.endsWith(".md") && (0, import_fs4.statSync)(fullPath).isFile();
3811
+ }).map((entry) => entry.replace(/\\/g, "/")).sort();
3825
3812
  }
3826
- function cleanupWorkflowSnippets(domains) {
3827
- for (const domain of domains) {
3828
- const domainUpper = domain.toUpperCase();
3829
- const snippetPath = (0, import_path4.join)(CONTEXTS_DIR, domainUpper, SNIPPET_FILENAME);
3830
- try {
3831
- (0, import_fs4.unlinkSync)(snippetPath);
3832
- } catch {
3813
+ function extractFirstHeading(filePath) {
3814
+ try {
3815
+ const content = (0, import_fs4.readFileSync)(filePath, "utf-8");
3816
+ const withoutFrontmatter = content.replace(/^---[\s\S]*?---\s*/, "");
3817
+ const match = withoutFrontmatter.match(/^#\s+(.+)/m);
3818
+ if (match) {
3819
+ return match[1].replace(/^[\p{Emoji_Presentation}\p{Extended_Pictographic}\s]+/u, "").trim();
3833
3820
  }
3821
+ } catch {
3834
3822
  }
3823
+ const basename = filePath.split(/[/\\]/).pop() ?? "";
3824
+ return basename.replace(/\.md$/i, "").replace(/[-_]+/g, " ");
3835
3825
  }
3836
3826
  function buildMCPSection(mcpConfig) {
3837
3827
  const entries = Object.entries(mcpConfig);
@@ -3862,27 +3852,52 @@ function buildContextRefsSection(domains) {
3862
3852
  `Domain-specific guidelines and reference material are available in the \`_ai-context/\` folder:`,
3863
3853
  ``
3864
3854
  ];
3855
+ let hasAnyFiles = false;
3865
3856
  for (const domain of domains) {
3866
3857
  const domainUpper = domain.toUpperCase();
3867
3858
  const domainPath = (0, import_path4.join)(CONTEXTS_DIR, domainUpper);
3868
3859
  if (!(0, import_fs4.existsSync)(domainPath)) continue;
3869
- lines2.push(`### ${domainUpper}`);
3860
+ const domainFiles = [];
3861
+ const ctxInstructions = (0, import_path4.join)(domainPath, "context-instructions.md");
3862
+ if ((0, import_fs4.existsSync)(ctxInstructions)) {
3863
+ const desc = extractFirstHeading(ctxInstructions);
3864
+ domainFiles.push(`- \`_ai-context/${domainUpper}/context-instructions.md\` \u2014 ${desc}`);
3865
+ }
3870
3866
  const instructionsMd = (0, import_path4.join)(domainPath, "core", "instructions.md");
3871
3867
  if ((0, import_fs4.existsSync)(instructionsMd)) {
3872
- lines2.push(`- \`_ai-context/${domainUpper}/core/instructions.md\` \u2014 core development guidelines`);
3868
+ const desc = extractFirstHeading(instructionsMd);
3869
+ domainFiles.push(`- \`_ai-context/${domainUpper}/core/instructions.md\` \u2014 ${desc} (start here)`);
3873
3870
  }
3874
- const instructionsDir = (0, import_path4.join)(domainPath, "core", "instructions");
3875
- if ((0, import_fs4.existsSync)(instructionsDir)) {
3876
- lines2.push(`- \`_ai-context/${domainUpper}/core/instructions/\` \u2014 detailed topic-specific guidelines`);
3871
+ const coreDir = (0, import_path4.join)(domainPath, "core");
3872
+ if ((0, import_fs4.existsSync)(coreDir)) {
3873
+ const coreFiles = collectMdFiles(coreDir).filter((f) => f !== "instructions.md" && !f.startsWith("instructions/"));
3874
+ for (const file of coreFiles) {
3875
+ const desc = extractFirstHeading((0, import_path4.join)(coreDir, file));
3876
+ domainFiles.push(`- \`_ai-context/${domainUpper}/core/${file}\` \u2014 ${desc}`);
3877
+ }
3877
3878
  }
3878
3879
  const refDir = (0, import_path4.join)(domainPath, "reference");
3879
3880
  if ((0, import_fs4.existsSync)(refDir)) {
3880
- lines2.push(`- \`_ai-context/${domainUpper}/reference/\` \u2014 cheat sheets and reference material`);
3881
+ const refFiles = collectMdFiles(refDir);
3882
+ if (refFiles.length > 0) {
3883
+ domainFiles.push(``);
3884
+ domainFiles.push(`**Reference & cheat sheets:**`);
3885
+ for (const file of refFiles) {
3886
+ const desc = extractFirstHeading((0, import_path4.join)(refDir, file));
3887
+ domainFiles.push(`- \`_ai-context/${domainUpper}/reference/${file}\` \u2014 ${desc}`);
3888
+ }
3889
+ }
3881
3890
  }
3891
+ if (domainFiles.length === 0) continue;
3892
+ hasAnyFiles = true;
3893
+ lines2.push(`### ${domainUpper}`);
3894
+ lines2.push(...domainFiles);
3895
+ lines2.push(``);
3896
+ }
3897
+ if (hasAnyFiles) {
3898
+ lines2.push(`**ALWAYS** read \`core/instructions.md\` for a domain before implementing features. Consult reference files when the topic is directly relevant.`);
3882
3899
  lines2.push(``);
3883
3900
  }
3884
- lines2.push(`**ALWAYS** consult these files before implementing features or making architectural decisions.`);
3885
- lines2.push(``);
3886
3901
  return lines2.join("\n");
3887
3902
  }
3888
3903
  function buildCombinedInstructions(domains, mcpConfig) {
@@ -3896,12 +3911,6 @@ function buildCombinedInstructions(domains, mcpConfig) {
3896
3911
  if (mcpConfig && Object.keys(mcpConfig).length > 0) {
3897
3912
  lines2.push(buildMCPSection(mcpConfig));
3898
3913
  }
3899
- const workflowContent = buildWorkflowSection(domains);
3900
- if (workflowContent) {
3901
- lines2.push(`## Domain-Specific Development Workflows
3902
- `);
3903
- lines2.push(workflowContent);
3904
- }
3905
3914
  return lines2.join("\n");
3906
3915
  }
3907
3916
  async function setupInstructions(config) {
@@ -3910,7 +3919,6 @@ async function setupInstructions(config) {
3910
3919
  case "claude-code": {
3911
3920
  const content = buildCombinedInstructions(domains, mcpConfig);
3912
3921
  upsertBlock((0, import_path4.join)(process.cwd(), "CLAUDE.md"), content);
3913
- cleanupWorkflowSnippets(domains);
3914
3922
  break;
3915
3923
  }
3916
3924
  case "github-copilot": {
@@ -3926,7 +3934,6 @@ applyTo: "**"
3926
3934
  }
3927
3935
  const body = buildCombinedInstructions(domains, mcpConfig);
3928
3936
  upsertBlock(filePath, body);
3929
- cleanupWorkflowSnippets(domains);
3930
3937
  break;
3931
3938
  }
3932
3939
  case "cursor": {
@@ -3934,7 +3941,6 @@ applyTo: "**"
3934
3941
  if (!(0, import_fs4.existsSync)(cursorDir)) (0, import_fs4.mkdirSync)(cursorDir, { recursive: true });
3935
3942
  const body = buildCombinedInstructions(domains, mcpConfig);
3936
3943
  upsertBlock((0, import_path4.join)(cursorDir, `instructions.mdc`), body);
3937
- cleanupWorkflowSnippets(domains);
3938
3944
  break;
3939
3945
  }
3940
3946
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dlw-machine-setup",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "One-shot installer for The Machine toolchain",
5
5
  "bin": {
6
6
  "dlw-machine-setup": "bin/installer.js"