dlw-machine-setup 0.5.0 → 0.5.8

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 +79 -14
  2. package/package.json +1 -1
package/bin/installer.js CHANGED
@@ -3801,8 +3801,8 @@ async function fetchFactory(options) {
3801
3801
  const factoryDir = (0, import_path3.join)(targetDir, "factory");
3802
3802
  const agentsSrc = (0, import_path3.join)(extractedPath, "agents");
3803
3803
  if ((0, import_fs3.existsSync)(agentsSrc)) {
3804
- copyDirectory2(agentsSrc, (0, import_path3.join)(claudeDir, "agents"));
3805
3804
  copyDirectory2(agentsSrc, (0, import_path3.join)(factoryDir, "agents"));
3805
+ copyAgentStubs(agentsSrc, (0, import_path3.join)(claudeDir, "agents"));
3806
3806
  result.filesInstalled.push(".claude/agents/", "factory/agents/");
3807
3807
  }
3808
3808
  const hooksSrc = (0, import_path3.join)(extractedPath, "hooks");
@@ -3845,26 +3845,37 @@ function configureSettings(claudeDir) {
3845
3845
  }
3846
3846
  }
3847
3847
  if (!settings.hooks) settings.hooks = {};
3848
+ const welcomeHook = {
3849
+ hooks: [{ type: "command", command: "node .claude/hooks/factory-welcome.cjs" }]
3850
+ };
3851
+ const immutableGuardHook = {
3852
+ matcher: "Write|Edit",
3853
+ hooks: [{ type: "command", command: "node .claude/hooks/factory-immutable-guard.cjs" }]
3854
+ };
3848
3855
  const stateAdvanceHook = {
3849
3856
  matcher: "Write|Edit",
3850
- hooks: [{ type: "command", command: "node .claude/hooks/factory-state-advance.js" }]
3857
+ hooks: [{ type: "command", command: "node .claude/hooks/factory-state-advance.cjs" }]
3851
3858
  };
3852
3859
  const contextMonitorHook = {
3853
- hooks: [{ type: "command", command: "node .claude/hooks/factory-context-monitor.js" }]
3860
+ hooks: [{ type: "command", command: "node .claude/hooks/factory-context-monitor.cjs" }]
3854
3861
  };
3855
3862
  const stateGuardHook = {
3856
- hooks: [{ type: "command", command: "node .claude/hooks/factory-state-guard.js" }]
3863
+ hooks: [{ type: "command", command: "node .claude/hooks/factory-state-guard.cjs" }]
3857
3864
  };
3858
- for (const event of ["PostToolUse", "UserPromptSubmit"]) {
3865
+ for (const event of ["SessionStart", "PreToolUse", "PostToolUse", "UserPromptSubmit"]) {
3859
3866
  if (settings.hooks[event]) {
3860
3867
  settings.hooks[event] = settings.hooks[event].filter(
3861
3868
  (h) => !h.hooks?.some(
3862
- (hh) => hh.command?.includes("factory-state-advance") || hh.command?.includes("factory-context-monitor") || hh.command?.includes("factory-state-guard")
3869
+ (hh) => hh.command?.includes("factory-welcome") || hh.command?.includes("factory-immutable-guard") || hh.command?.includes("factory-state-advance") || hh.command?.includes("factory-context-monitor") || hh.command?.includes("factory-state-guard")
3863
3870
  )
3864
3871
  );
3865
3872
  if (settings.hooks[event].length === 0) delete settings.hooks[event];
3866
3873
  }
3867
3874
  }
3875
+ if (!settings.hooks.SessionStart) settings.hooks.SessionStart = [];
3876
+ settings.hooks.SessionStart.unshift(welcomeHook);
3877
+ if (!settings.hooks.PreToolUse) settings.hooks.PreToolUse = [];
3878
+ settings.hooks.PreToolUse.unshift(immutableGuardHook);
3868
3879
  if (!settings.hooks.PostToolUse) settings.hooks.PostToolUse = [];
3869
3880
  settings.hooks.PostToolUse.unshift(stateAdvanceHook);
3870
3881
  if (!settings.hooks.UserPromptSubmit) {
@@ -3879,12 +3890,28 @@ function configureSettings(claudeDir) {
3879
3890
  );
3880
3891
  if (!hasMonitor) settings.hooks.UserPromptSubmit.push(contextMonitorHook);
3881
3892
  }
3882
- settings.statusLine = { type: "command", command: "node .claude/hooks/factory-statusline.js" };
3893
+ settings.statusLine = { type: "command", command: "node .claude/hooks/factory-statusline.cjs" };
3883
3894
  if (!(0, import_fs3.existsSync)(claudeDir)) {
3884
3895
  (0, import_fs3.mkdirSync)(claudeDir, { recursive: true });
3885
3896
  }
3886
3897
  (0, import_fs3.writeFileSync)(settingsPath, JSON.stringify(settings, null, 2) + "\n");
3887
3898
  }
3899
+ function copyAgentStubs(source, target) {
3900
+ if (!(0, import_fs3.existsSync)(target)) {
3901
+ (0, import_fs3.mkdirSync)(target, { recursive: true });
3902
+ }
3903
+ const entries = (0, import_fs3.readdirSync)(source, { withFileTypes: true });
3904
+ for (const entry of entries) {
3905
+ if (entry.isDirectory()) continue;
3906
+ if (!entry.name.endsWith(".md")) continue;
3907
+ const content = (0, import_fs3.readFileSync)((0, import_path3.join)(source, entry.name), "utf8");
3908
+ const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?\r?\n)---/);
3909
+ if (frontmatterMatch) {
3910
+ (0, import_fs3.writeFileSync)((0, import_path3.join)(target, entry.name), frontmatterMatch[0] + "\n");
3911
+ } else {
3912
+ }
3913
+ }
3914
+ }
3888
3915
  function copyDirectory2(source, target) {
3889
3916
  if (!(0, import_fs3.existsSync)(target)) {
3890
3917
  (0, import_fs3.mkdirSync)(target, { recursive: true });
@@ -4288,7 +4315,7 @@ async function loadWizardOptions(token, repo) {
4288
4315
  }
4289
4316
 
4290
4317
  // src/index.ts
4291
- var INSTALLER_VERSION = "0.5.0";
4318
+ var INSTALLER_VERSION = "0.5.7";
4292
4319
  function getInstructionFilePath(agent) {
4293
4320
  switch (agent) {
4294
4321
  case "claude-code":
@@ -4317,6 +4344,25 @@ function formatMCPCommand(server) {
4317
4344
  if (server.command) return `${server.command} ${(server.args ?? []).join(" ")}`.trimEnd();
4318
4345
  return "";
4319
4346
  }
4347
+ var dim = (text) => `\x1B[2m${text}\x1B[0m`;
4348
+ var yellow = (text) => `\x1B[33m${text}\x1B[0m`;
4349
+ var green = (text) => `\x1B[32m${text}\x1B[0m`;
4350
+ function detectMarkerFileMode(filePath, markerStart) {
4351
+ if (!(0, import_fs7.existsSync)(filePath)) return green("create");
4352
+ const content = (0, import_fs7.readFileSync)(filePath, "utf-8");
4353
+ if (content.includes(markerStart)) return yellow("update");
4354
+ return yellow("append");
4355
+ }
4356
+ function detectMCPFileMode(filePath) {
4357
+ if (!(0, import_fs7.existsSync)(filePath)) return green("create");
4358
+ return yellow("merge");
4359
+ }
4360
+ function detectContextMode(projectPath, domain) {
4361
+ const contextDir = (0, import_path7.join)(projectPath, "_ai-context", domain.toUpperCase());
4362
+ const contextDirLower = (0, import_path7.join)(projectPath, "_ai-context", domain);
4363
+ if ((0, import_fs7.existsSync)(contextDir) || (0, import_fs7.existsSync)(contextDirLower)) return yellow("overwrite");
4364
+ return green("create");
4365
+ }
4320
4366
  function waitForEnter() {
4321
4367
  const rl = (0, import_readline.createInterface)({ input: process.stdin, output: process.stdout });
4322
4368
  return new Promise((resolve4) => {
@@ -4411,6 +4457,17 @@ async function previewAndConfirm(config, options) {
4411
4457
  const instructionFile = getInstructionFilePath(config.agent);
4412
4458
  const mcpConfigFile = getMCPConfigPath(config.agent);
4413
4459
  const serverEntries = Object.entries(config.mcpConfig);
4460
+ const instructionFilePath = (0, import_path7.join)(config.projectPath, instructionFile);
4461
+ const mcpConfigFilePath = (0, import_path7.join)(config.projectPath, mcpConfigFile);
4462
+ const gitignorePath = (0, import_path7.join)(config.projectPath, ".gitignore");
4463
+ const instructionMode = detectMarkerFileMode(instructionFilePath, "<!-- one-shot-installer:start -->");
4464
+ const mcpMode = detectMCPFileMode(mcpConfigFilePath);
4465
+ const gitignoreMode = detectMarkerFileMode(gitignorePath, "# one-shot-installer:start");
4466
+ const uniqueDomains = [...new Set(config.personas.flatMap((p) => p.domains))];
4467
+ const domainModes = uniqueDomains.map((d) => ({
4468
+ domain: d,
4469
+ mode: detectContextMode(config.projectPath, d)
4470
+ }));
4414
4471
  console.log("\n" + "\u2500".repeat(48));
4415
4472
  console.log(" Ready to install");
4416
4473
  console.log("\u2500".repeat(48) + "\n");
@@ -4419,14 +4476,22 @@ async function previewAndConfirm(config, options) {
4419
4476
  console.log(` Factory ${config.installFactory ? "yes" : "no"}`);
4420
4477
  console.log(` Directory ${config.projectPath}`);
4421
4478
  console.log("");
4422
- console.log(` Instruction file`);
4423
- console.log(` ${instructionFile}`);
4424
- console.log("");
4425
- console.log(` MCP config`);
4426
- console.log(` ${mcpConfigFile}`);
4479
+ console.log(` ${dim("File actions:")}`);
4480
+ const domainColWidth = Math.max(...domainModes.map((d) => d.domain.length), 6) + 2;
4481
+ for (const { domain, mode } of domainModes) {
4482
+ console.log(` _ai-context/${domain.padEnd(domainColWidth)}${mode}`);
4483
+ }
4484
+ console.log(` ${instructionFile.padEnd(domainColWidth + 14)}${instructionMode}`);
4485
+ console.log(` ${mcpConfigFile.padEnd(domainColWidth + 14)}${mcpMode}`);
4486
+ console.log(` ${".gitignore".padEnd(domainColWidth + 14)}${gitignoreMode}`);
4487
+ if (config.installFactory) {
4488
+ const factoryExists = (0, import_fs7.existsSync)((0, import_path7.join)(config.projectPath, "factory"));
4489
+ const factoryMode = factoryExists ? yellow("overwrite") : green("create");
4490
+ console.log(` ${"factory/".padEnd(domainColWidth + 14)}${factoryMode}`);
4491
+ }
4427
4492
  if (serverEntries.length > 0) {
4428
4493
  console.log("");
4429
- console.log(" MCP servers");
4494
+ console.log(` ${dim("MCP servers:")}`);
4430
4495
  const maxLen = Math.max(...serverEntries.map(([name]) => name.length));
4431
4496
  for (const [name, server] of serverEntries) {
4432
4497
  const cmd = formatMCPCommand(server);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dlw-machine-setup",
3
- "version": "0.5.0",
3
+ "version": "0.5.8",
4
4
  "description": "One-shot installer for The Machine toolchain",
5
5
  "bin": {
6
6
  "dlw-machine-setup": "bin/installer.js"