dlw-machine-setup 0.9.5 → 0.9.6

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 +139 -35
  2. package/package.json +1 -1
package/bin/installer.js CHANGED
@@ -3295,9 +3295,9 @@ ${page}${helpTipBottom}${choiceDescription}${import_ansi_escapes4.default.cursor
3295
3295
  });
3296
3296
 
3297
3297
  // src/index.ts
3298
- var import_fs16 = require("fs");
3298
+ var import_fs17 = require("fs");
3299
3299
  var import_readline2 = require("readline");
3300
- var import_path16 = require("path");
3300
+ var import_path17 = require("path");
3301
3301
 
3302
3302
  // src/utils/fetch.ts
3303
3303
  var DEFAULT_TIMEOUT_MS = 3e4;
@@ -3951,6 +3951,7 @@ var Journal = class {
3951
3951
  // src/steps/index.ts
3952
3952
  var steps_exports = {};
3953
3953
  __export(steps_exports, {
3954
+ buildCodeIndex: () => build_code_index_default,
3954
3955
  fetchAbapHooks: () => fetch_abap_hooks_default,
3955
3956
  fetchContexts: () => fetch_contexts_default,
3956
3957
  fetchFactory: () => fetch_factory_default,
@@ -5467,9 +5468,112 @@ function isClaudeCliAvailable() {
5467
5468
  return check2.status === 0;
5468
5469
  }
5469
5470
 
5470
- // src/steps/setup/update-gitignore.ts
5471
+ // src/steps/setup/build-code-index.ts
5472
+ var import_child_process4 = require("child_process");
5471
5473
  var import_fs13 = require("fs");
5472
5474
  var import_path13 = require("path");
5475
+ var CODE_INDEX_RELATIVE_PATH = ".claude/factory/utils/code-index";
5476
+ var INDEX_OUTPUT_RELATIVE_PATH = ".claude/factory/repo-index.json";
5477
+ var INDEX_STAMP_RELATIVE_PATH = ".claude/factory/index.stamp";
5478
+ var build_code_index_default = defineStep({
5479
+ name: "build-code-index",
5480
+ label: "Building code index",
5481
+ when: (ctx) => ctx.installed.factoryInstalled === true,
5482
+ execute: async (ctx) => {
5483
+ const codeIndexDirectory = (0, import_path13.join)(ctx.config.projectPath, CODE_INDEX_RELATIVE_PATH);
5484
+ if (!(0, import_fs13.existsSync)(codeIndexDirectory)) {
5485
+ return {
5486
+ status: "skipped",
5487
+ detail: `code-index not found at ${CODE_INDEX_RELATIVE_PATH} \u2014 older Factory release?`,
5488
+ record: { depsInstalled: false, indexBuilt: false }
5489
+ };
5490
+ }
5491
+ if (!isNodeAvailable()) {
5492
+ return {
5493
+ status: "skipped",
5494
+ detail: "`node` not found on PATH \u2014 run the indexer manually once node is available",
5495
+ record: { depsInstalled: false, indexBuilt: false }
5496
+ };
5497
+ }
5498
+ const npmResult = (0, import_child_process4.spawnSync)("npm install --silent --no-audit --no-fund --omit=dev", {
5499
+ shell: true,
5500
+ stdio: "pipe",
5501
+ encoding: "utf-8",
5502
+ cwd: codeIndexDirectory
5503
+ });
5504
+ const depsInstalled = npmResult.status === 0;
5505
+ if (!depsInstalled) {
5506
+ const stderrFirstLine = (npmResult.stderr ?? "").trim().split("\n")[0] || `exit ${npmResult.status}`;
5507
+ return {
5508
+ status: "failed",
5509
+ detail: `npm install failed: ${stderrFirstLine}`,
5510
+ record: { depsInstalled: false, indexBuilt: false }
5511
+ };
5512
+ }
5513
+ const indexerScriptPath = (0, import_path13.join)(codeIndexDirectory, "index.cjs");
5514
+ const indexerResult = (0, import_child_process4.spawnSync)(`node "${indexerScriptPath}" "${ctx.config.projectPath}"`, {
5515
+ shell: true,
5516
+ stdio: "pipe",
5517
+ encoding: "utf-8",
5518
+ cwd: ctx.config.projectPath
5519
+ });
5520
+ const indexBuilt = indexerResult.status === 0;
5521
+ if (!indexBuilt) {
5522
+ const stderrFirstLine = (indexerResult.stderr ?? "").trim().split("\n")[0] || `exit ${indexerResult.status}`;
5523
+ return {
5524
+ status: "success",
5525
+ message: "deps installed; initial index build failed (run manually)",
5526
+ detail: `indexer error: ${stderrFirstLine}`,
5527
+ record: { depsInstalled: true, indexBuilt: false }
5528
+ };
5529
+ }
5530
+ const lastStdoutLines = (indexerResult.stdout ?? "").trim().split("\n").slice(-5).join(" | ");
5531
+ return {
5532
+ status: "success",
5533
+ message: lastStdoutLines || "index built",
5534
+ record: { depsInstalled: true, indexBuilt: true }
5535
+ };
5536
+ },
5537
+ inverse: {
5538
+ label: "Removing code index",
5539
+ execute: async (raw, ctx) => {
5540
+ const record = raw ?? {};
5541
+ const projectPath = ctx.config.projectPath;
5542
+ const summaryActions = [];
5543
+ if (record.indexBuilt) {
5544
+ const indexFilePath = (0, import_path13.join)(projectPath, INDEX_OUTPUT_RELATIVE_PATH);
5545
+ if ((0, import_fs13.existsSync)(indexFilePath)) {
5546
+ (0, import_fs13.unlinkSync)(indexFilePath);
5547
+ summaryActions.push(`removed ${INDEX_OUTPUT_RELATIVE_PATH}`);
5548
+ }
5549
+ const stampFilePath = (0, import_path13.join)(projectPath, INDEX_STAMP_RELATIVE_PATH);
5550
+ if ((0, import_fs13.existsSync)(stampFilePath)) {
5551
+ (0, import_fs13.unlinkSync)(stampFilePath);
5552
+ summaryActions.push(`removed ${INDEX_STAMP_RELATIVE_PATH}`);
5553
+ }
5554
+ }
5555
+ if (record.depsInstalled) {
5556
+ const nodeModulesPath = (0, import_path13.join)(projectPath, CODE_INDEX_RELATIVE_PATH, "node_modules");
5557
+ if ((0, import_fs13.existsSync)(nodeModulesPath)) {
5558
+ (0, import_fs13.rmSync)(nodeModulesPath, { recursive: true, force: true });
5559
+ summaryActions.push("removed code-index node_modules");
5560
+ }
5561
+ }
5562
+ return {
5563
+ status: "success",
5564
+ message: summaryActions.length > 0 ? summaryActions.join(", ") : "nothing to remove"
5565
+ };
5566
+ }
5567
+ }
5568
+ });
5569
+ function isNodeAvailable() {
5570
+ const probeResult = (0, import_child_process4.spawnSync)("node --version", { shell: true, stdio: "ignore" });
5571
+ return probeResult.status === 0;
5572
+ }
5573
+
5574
+ // src/steps/setup/update-gitignore.ts
5575
+ var import_fs14 = require("fs");
5576
+ var import_path14 = require("path");
5473
5577
  var MARKER_START2 = "# one-shot-installer:start";
5474
5578
  var MARKER_END2 = "# one-shot-installer:end";
5475
5579
  var CORE_GITIGNORE_ENTRIES = [
@@ -5490,8 +5594,8 @@ var update_gitignore_default = defineStep({
5490
5594
  name: "update-gitignore",
5491
5595
  label: "Updating .gitignore",
5492
5596
  execute: async (ctx) => {
5493
- const gitignorePath = (0, import_path13.join)(ctx.config.projectPath, ".gitignore");
5494
- const fileExistedBefore = (0, import_fs13.existsSync)(gitignorePath);
5597
+ const gitignorePath = (0, import_path14.join)(ctx.config.projectPath, ".gitignore");
5598
+ const fileExistedBefore = (0, import_fs14.existsSync)(gitignorePath);
5495
5599
  upsertMarkerBlock(gitignorePath, MARKER_START2, MARKER_END2, CORE_GITIGNORE_ENTRIES.join("\n"));
5496
5600
  const record = {
5497
5601
  filePath: ".gitignore",
@@ -5519,8 +5623,8 @@ var update_gitignore_default = defineStep({
5519
5623
  });
5520
5624
 
5521
5625
  // src/steps/setup/write-state.ts
5522
- var import_fs14 = require("fs");
5523
- var import_path14 = require("path");
5626
+ var import_fs15 = require("fs");
5627
+ var import_path15 = require("path");
5524
5628
  var import_os2 = require("os");
5525
5629
 
5526
5630
  // package.json
@@ -5554,7 +5658,7 @@ var write_state_default = defineStep({
5554
5658
  name: "write-state",
5555
5659
  label: "Saving installation state",
5556
5660
  execute: async (ctx) => {
5557
- const statePath = (0, import_path14.join)(ctx.config.projectPath, ".one-shot-state.json");
5661
+ const statePath = (0, import_path15.join)(ctx.config.projectPath, ".one-shot-state.json");
5558
5662
  const mcpServersAdded = ctx.installed.mcpServersAdded ?? [];
5559
5663
  const filteredMcpConfig = Object.fromEntries(
5560
5664
  Object.entries(ctx.config.mcpConfig).filter(([name]) => mcpServersAdded.includes(name))
@@ -5585,13 +5689,13 @@ var write_state_default = defineStep({
5585
5689
  * mislead the uninstall preview which reads this field. */
5586
5690
  factory: ctx.installed.factoryInstalled ? ".claude/" : null,
5587
5691
  abapHooks: ctx.installed.abapHooksInstalled ? ".claude/hooks/" : null,
5588
- globalConfig: (0, import_path14.join)((0, import_os2.homedir)(), ".one-shot-installer")
5692
+ globalConfig: (0, import_path15.join)((0, import_os2.homedir)(), ".one-shot-installer")
5589
5693
  }
5590
5694
  };
5591
5695
  if (ctx.journal) {
5592
5696
  ctx.journal.setSummary(state);
5593
5697
  } else {
5594
- (0, import_fs14.writeFileSync)(statePath, JSON.stringify(state, null, 2), "utf-8");
5698
+ (0, import_fs15.writeFileSync)(statePath, JSON.stringify(state, null, 2), "utf-8");
5595
5699
  }
5596
5700
  return { status: "success" };
5597
5701
  },
@@ -5606,9 +5710,9 @@ var write_state_default = defineStep({
5606
5710
  });
5607
5711
 
5608
5712
  // src/uninstall.ts
5609
- var import_fs15 = require("fs");
5713
+ var import_fs16 = require("fs");
5610
5714
  var import_readline = require("readline");
5611
- var import_path15 = require("path");
5715
+ var import_path16 = require("path");
5612
5716
  var dim = (text) => `\x1B[2m${text}\x1B[0m`;
5613
5717
  var yellow = (text) => `\x1B[33m${text}\x1B[0m`;
5614
5718
  var red3 = (text) => `\x1B[31m${text}\x1B[0m`;
@@ -5628,11 +5732,11 @@ async function uninstall() {
5628
5732
  try {
5629
5733
  const projectInput = await esm_default4({
5630
5734
  message: "Project directory to uninstall from:",
5631
- default: (0, import_path15.resolve)(process.cwd())
5735
+ default: (0, import_path16.resolve)(process.cwd())
5632
5736
  });
5633
- const projectPath = (0, import_path15.resolve)(projectInput);
5634
- const statePath = (0, import_path15.join)(projectPath, ".one-shot-state.json");
5635
- if (!(0, import_fs15.existsSync)(statePath)) {
5737
+ const projectPath = (0, import_path16.resolve)(projectInput);
5738
+ const statePath = (0, import_path16.join)(projectPath, ".one-shot-state.json");
5739
+ if (!(0, import_fs16.existsSync)(statePath)) {
5636
5740
  console.log("");
5637
5741
  console.log(red3(" No .one-shot-state.json found at:"));
5638
5742
  console.log(` ${statePath}`);
@@ -5657,7 +5761,7 @@ async function uninstall() {
5657
5761
  default: false
5658
5762
  });
5659
5763
  if (proceed2) {
5660
- (0, import_fs15.unlinkSync)(statePath);
5764
+ (0, import_fs16.unlinkSync)(statePath);
5661
5765
  console.log(" Removed .one-shot-state.json");
5662
5766
  }
5663
5767
  await waitForEnter();
@@ -5698,7 +5802,7 @@ async function uninstall() {
5698
5802
  console.log("");
5699
5803
  const result = await runRollback(stepList, ctx);
5700
5804
  try {
5701
- if ((0, import_fs15.existsSync)(statePath)) (0, import_fs15.unlinkSync)(statePath);
5805
+ if ((0, import_fs16.existsSync)(statePath)) (0, import_fs16.unlinkSync)(statePath);
5702
5806
  } catch {
5703
5807
  }
5704
5808
  printSummary(result);
@@ -5710,7 +5814,7 @@ async function uninstall() {
5710
5814
  }
5711
5815
  function readSummary(statePath) {
5712
5816
  try {
5713
- const raw = JSON.parse((0, import_fs15.readFileSync)(statePath, "utf-8"));
5817
+ const raw = JSON.parse((0, import_fs16.readFileSync)(statePath, "utf-8"));
5714
5818
  return raw;
5715
5819
  } catch {
5716
5820
  return {};
@@ -5791,19 +5895,19 @@ var dim2 = (text) => `\x1B[2m${text}\x1B[0m`;
5791
5895
  var yellow2 = (text) => `\x1B[33m${text}\x1B[0m`;
5792
5896
  var green2 = (text) => `\x1B[32m${text}\x1B[0m`;
5793
5897
  function detectMarkerFileMode(filePath, markerStart) {
5794
- if (!(0, import_fs16.existsSync)(filePath)) return green2("create");
5795
- const content = (0, import_fs16.readFileSync)(filePath, "utf-8");
5898
+ if (!(0, import_fs17.existsSync)(filePath)) return green2("create");
5899
+ const content = (0, import_fs17.readFileSync)(filePath, "utf-8");
5796
5900
  if (content.includes(markerStart)) return yellow2("update");
5797
5901
  return yellow2("append");
5798
5902
  }
5799
5903
  function detectMCPFileMode(filePath) {
5800
- if (!(0, import_fs16.existsSync)(filePath)) return green2("create");
5904
+ if (!(0, import_fs17.existsSync)(filePath)) return green2("create");
5801
5905
  return yellow2("merge");
5802
5906
  }
5803
5907
  function detectContextMode(projectPath, domain) {
5804
- const contextDir = (0, import_path16.join)(projectPath, "_ai-context", domain.toUpperCase());
5805
- const contextDirLower = (0, import_path16.join)(projectPath, "_ai-context", domain);
5806
- if ((0, import_fs16.existsSync)(contextDir) || (0, import_fs16.existsSync)(contextDirLower)) return yellow2("overwrite");
5908
+ const contextDir = (0, import_path17.join)(projectPath, "_ai-context", domain.toUpperCase());
5909
+ const contextDirLower = (0, import_path17.join)(projectPath, "_ai-context", domain);
5910
+ if ((0, import_fs17.existsSync)(contextDir) || (0, import_fs17.existsSync)(contextDirLower)) return yellow2("overwrite");
5807
5911
  return green2("create");
5808
5912
  }
5809
5913
  function waitForEnter2() {
@@ -5849,7 +5953,7 @@ async function main() {
5849
5953
  await waitForEnter2();
5850
5954
  return;
5851
5955
  }
5852
- const statePath = (0, import_path16.join)(config.projectPath, ".one-shot-state.json");
5956
+ const statePath = (0, import_path17.join)(config.projectPath, ".one-shot-state.json");
5853
5957
  const journal = new Journal(statePath);
5854
5958
  journal.startFresh();
5855
5959
  const ctx = {
@@ -5933,7 +6037,7 @@ async function collectInputs(options, releaseVersion, factoryAvailable = false,
5933
6037
  }
5934
6038
  const projectInput = await esm_default4({
5935
6039
  message: "Project directory:",
5936
- default: (0, import_path16.resolve)(process.cwd())
6040
+ default: (0, import_path17.resolve)(process.cwd())
5937
6041
  });
5938
6042
  const isAbapSelected = selectedTechnologies.some((t) => t.domains.includes("ABAP"));
5939
6043
  const installAbapHooks = abapHooksAvailable && agent === "claude-code" && isAbapSelected;
@@ -5941,7 +6045,7 @@ async function collectInputs(options, releaseVersion, factoryAvailable = false,
5941
6045
  technologies: selectedTechnologies,
5942
6046
  agent,
5943
6047
  azureDevOpsOrg,
5944
- projectPath: (0, import_path16.resolve)(projectInput),
6048
+ projectPath: (0, import_path17.resolve)(projectInput),
5945
6049
  baseMcpServers: options.baseMcpServers,
5946
6050
  mcpConfig,
5947
6051
  releaseVersion,
@@ -5956,9 +6060,9 @@ async function previewAndConfirm(config, options) {
5956
6060
  const instructionFile = target.instructions;
5957
6061
  const mcpConfigFile = target.mcpConfig;
5958
6062
  const serverEntries = Object.entries(config.mcpConfig);
5959
- const instructionFilePath = (0, import_path16.join)(config.projectPath, instructionFile);
5960
- const mcpConfigFilePath = (0, import_path16.join)(config.projectPath, mcpConfigFile);
5961
- const gitignorePath = (0, import_path16.join)(config.projectPath, ".gitignore");
6063
+ const instructionFilePath = (0, import_path17.join)(config.projectPath, instructionFile);
6064
+ const mcpConfigFilePath = (0, import_path17.join)(config.projectPath, mcpConfigFile);
6065
+ const gitignorePath = (0, import_path17.join)(config.projectPath, ".gitignore");
5962
6066
  const instructionMode = detectMarkerFileMode(instructionFilePath, "<!-- one-shot-installer:start -->");
5963
6067
  const mcpMode = detectMCPFileMode(mcpConfigFilePath);
5964
6068
  const gitignoreMode = detectMarkerFileMode(gitignorePath, "# one-shot-installer:start");
@@ -5985,11 +6089,11 @@ async function previewAndConfirm(config, options) {
5985
6089
  console.log(` ${mcpConfigFile.padEnd(domainColWidth + 14)}${mcpMode}`);
5986
6090
  console.log(` ${".gitignore".padEnd(domainColWidth + 14)}${gitignoreMode}`);
5987
6091
  if (config.installFactory || config.installAbapHooks) {
5988
- const claudeDir = (0, import_path16.join)(config.projectPath, ".claude");
5989
- const claudeMode = (0, import_fs16.existsSync)(claudeDir) ? yellow2("merge") : green2("create");
6092
+ const claudeDir = (0, import_path17.join)(config.projectPath, ".claude");
6093
+ const claudeMode = (0, import_fs17.existsSync)(claudeDir) ? yellow2("merge") : green2("create");
5990
6094
  console.log(` ${".claude/".padEnd(domainColWidth + 14)}${claudeMode}`);
5991
- const settingsPath = (0, import_path16.join)(config.projectPath, ".claude", "settings.json");
5992
- const settingsMode = (0, import_fs16.existsSync)(settingsPath) ? yellow2("merge") : green2("create");
6095
+ const settingsPath = (0, import_path17.join)(config.projectPath, ".claude", "settings.json");
6096
+ const settingsMode = (0, import_fs17.existsSync)(settingsPath) ? yellow2("merge") : green2("create");
5993
6097
  console.log(` ${".claude/settings.json".padEnd(domainColWidth + 14)}${settingsMode}`);
5994
6098
  }
5995
6099
  if (serverEntries.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dlw-machine-setup",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "One-shot installer for The Machine toolchain",
5
5
  "bin": {
6
6
  "dlw-machine-setup": "bin/installer.js"