@massu/core 1.9.3 → 1.9.5

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/cli.js CHANGED
@@ -39,6 +39,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
39
39
  mod
40
40
  ));
41
41
 
42
+ // src/lib/memory-path.ts
43
+ function encodeMemoryDirName(projectRoot) {
44
+ return projectRoot.replace(/\//g, "-");
45
+ }
46
+ var init_memory_path = __esm({
47
+ "src/lib/memory-path.ts"() {
48
+ "use strict";
49
+ }
50
+ });
51
+
42
52
  // src/config.ts
43
53
  import { resolve, dirname } from "path";
44
54
  import { existsSync, readFileSync } from "fs";
@@ -193,7 +203,7 @@ function getResolvedPaths() {
193
203
  plansDir: resolve(root, "docs/plans"),
194
204
  docsDir: resolve(root, "docs"),
195
205
  claudeDir: resolve(root, claudeDirName),
196
- memoryDir: resolve(homedir(), claudeDirName, "projects", root.replace(/\//g, "-"), "memory"),
206
+ memoryDir: resolve(homedir(), claudeDirName, "projects", encodeMemoryDirName(root), "memory"),
197
207
  sessionStatePath: resolve(root, config.conventions?.sessionStatePath ?? `${claudeDirName}/session-state/CURRENT.md`),
198
208
  sessionArchivePath: resolve(root, config.conventions?.sessionArchivePath ?? `${claudeDirName}/session-state/archive`),
199
209
  mcpJsonPath: resolve(root, ".mcp.json"),
@@ -208,6 +218,7 @@ var DomainConfigSchema, PatternRuleConfigSchema, CostModelSchema, AnalyticsConfi
208
218
  var init_config = __esm({
209
219
  "src/config.ts"() {
210
220
  "use strict";
221
+ init_memory_path();
211
222
  DomainConfigSchema = z.object({
212
223
  name: z.string().default("Unknown"),
213
224
  routers: z.array(z.string()).default([]),
@@ -8045,41 +8056,41 @@ var require_queue = __commonJS({
8045
8056
  queue.drained = drained;
8046
8057
  return queue;
8047
8058
  function push(value) {
8048
- var p19 = new Promise(function(resolve40, reject) {
8059
+ var p19 = new Promise(function(resolve41, reject) {
8049
8060
  pushCb(value, function(err, result) {
8050
8061
  if (err) {
8051
8062
  reject(err);
8052
8063
  return;
8053
8064
  }
8054
- resolve40(result);
8065
+ resolve41(result);
8055
8066
  });
8056
8067
  });
8057
8068
  p19.catch(noop);
8058
8069
  return p19;
8059
8070
  }
8060
8071
  function unshift(value) {
8061
- var p19 = new Promise(function(resolve40, reject) {
8072
+ var p19 = new Promise(function(resolve41, reject) {
8062
8073
  unshiftCb(value, function(err, result) {
8063
8074
  if (err) {
8064
8075
  reject(err);
8065
8076
  return;
8066
8077
  }
8067
- resolve40(result);
8078
+ resolve41(result);
8068
8079
  });
8069
8080
  });
8070
8081
  p19.catch(noop);
8071
8082
  return p19;
8072
8083
  }
8073
8084
  function drained() {
8074
- var p19 = new Promise(function(resolve40) {
8085
+ var p19 = new Promise(function(resolve41) {
8075
8086
  process.nextTick(function() {
8076
8087
  if (queue.idle()) {
8077
- resolve40();
8088
+ resolve41();
8078
8089
  } else {
8079
8090
  var previousDrain = queue.drain;
8080
8091
  queue.drain = function() {
8081
8092
  if (typeof previousDrain === "function") previousDrain();
8082
- resolve40();
8093
+ resolve41();
8083
8094
  queue.drain = previousDrain;
8084
8095
  };
8085
8096
  }
@@ -8565,9 +8576,9 @@ var require_stream3 = __commonJS({
8565
8576
  });
8566
8577
  }
8567
8578
  _getStat(filepath) {
8568
- return new Promise((resolve40, reject) => {
8579
+ return new Promise((resolve41, reject) => {
8569
8580
  this._stat(filepath, this._fsStatSettings, (error, stats) => {
8570
- return error === null ? resolve40(stats) : reject(error);
8581
+ return error === null ? resolve41(stats) : reject(error);
8571
8582
  });
8572
8583
  });
8573
8584
  }
@@ -8591,10 +8602,10 @@ var require_async5 = __commonJS({
8591
8602
  this._readerStream = new stream_1.default(this._settings);
8592
8603
  }
8593
8604
  dynamic(root, options) {
8594
- return new Promise((resolve40, reject) => {
8605
+ return new Promise((resolve41, reject) => {
8595
8606
  this._walkAsync(root, options, (error, entries) => {
8596
8607
  if (error === null) {
8597
- resolve40(entries);
8608
+ resolve41(entries);
8598
8609
  } else {
8599
8610
  reject(error);
8600
8611
  }
@@ -8604,10 +8615,10 @@ var require_async5 = __commonJS({
8604
8615
  async static(patterns, options) {
8605
8616
  const entries = [];
8606
8617
  const stream = this._readerStream.static(patterns, options);
8607
- return new Promise((resolve40, reject) => {
8618
+ return new Promise((resolve41, reject) => {
8608
8619
  stream.once("error", reject);
8609
8620
  stream.on("data", (entry) => entries.push(entry));
8610
- stream.once("end", () => resolve40(entries));
8621
+ stream.once("end", () => resolve41(entries));
8611
8622
  });
8612
8623
  }
8613
8624
  };
@@ -12982,10 +12993,12 @@ __export(init_exports, {
12982
12993
  detectFramework: () => detectFramework,
12983
12994
  detectPython: () => detectPython,
12984
12995
  generateConfig: () => generateConfig,
12996
+ getInstallerVersion: () => getInstallerVersion,
12985
12997
  initMemoryDir: () => initMemoryDir,
12986
12998
  installHooks: () => installHooks,
12987
12999
  isTemplateName: () => isTemplateName,
12988
13000
  listTemplates: () => listTemplates,
13001
+ mergeHooksConfig: () => mergeHooksConfig,
12989
13002
  parseInitArgs: () => parseInitArgs,
12990
13003
  printInitHelp: () => printInitHelp,
12991
13004
  registerMcpServer: () => registerMcpServer,
@@ -13529,6 +13542,26 @@ function copyTemplateConfig(templateName, targetPath, projectName) {
13529
13542
  return { success: false, error: err instanceof Error ? err.message : String(err) };
13530
13543
  }
13531
13544
  }
13545
+ function getInstallerVersion() {
13546
+ const candidates = [
13547
+ resolve7(__dirname2, "../package.json"),
13548
+ resolve7(__dirname2, "../../package.json")
13549
+ ];
13550
+ for (const candidate of candidates) {
13551
+ if (existsSync11(candidate)) {
13552
+ try {
13553
+ const pkg = JSON.parse(readFileSync11(candidate, "utf-8"));
13554
+ if (typeof pkg.version === "string" && pkg.version.length > 0 && pkg.name === "@massu/core") {
13555
+ return pkg.version;
13556
+ }
13557
+ } catch {
13558
+ }
13559
+ }
13560
+ }
13561
+ throw new Error(
13562
+ "getInstallerVersion: could not resolve @massu/core package.json. This indicates a corrupt install. Re-install via `npx -y @massu/core init`."
13563
+ );
13564
+ }
13532
13565
  function registerMcpServer(projectRoot) {
13533
13566
  const mcpPath = resolve7(projectRoot, ".mcp.json");
13534
13567
  let existing = {};
@@ -13543,10 +13576,11 @@ function registerMcpServer(projectRoot) {
13543
13576
  if (servers.massu) {
13544
13577
  return false;
13545
13578
  }
13579
+ const version = getInstallerVersion();
13546
13580
  servers.massu = {
13547
13581
  type: "stdio",
13548
13582
  command: "npx",
13549
- args: ["-y", "@massu/core"]
13583
+ args: ["-y", `@massu/core@${version}`]
13550
13584
  };
13551
13585
  existing.mcpServers = servers;
13552
13586
  writeFileSync2(mcpPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
@@ -13564,15 +13598,16 @@ function resolveHooksDir() {
13564
13598
  }
13565
13599
  return "node_modules/@massu/core/dist/hooks";
13566
13600
  }
13567
- function hookCmd(hooksDir, hookFile) {
13568
- return `node ${hooksDir}/${hookFile}`;
13601
+ function hookCmd(version, hookName) {
13602
+ return `npx -y @massu/core@${version} hook-runner ${hookName}`;
13569
13603
  }
13570
- function buildHooksConfig(hooksDir) {
13604
+ function buildHooksConfig(_hooksDir) {
13605
+ const version = getInstallerVersion();
13571
13606
  return {
13572
13607
  SessionStart: [
13573
13608
  {
13574
13609
  hooks: [
13575
- { type: "command", command: hookCmd(hooksDir, "session-start.js"), timeout: 10 }
13610
+ { type: "command", command: hookCmd(version, "session-start"), timeout: 10 }
13576
13611
  ]
13577
13612
  }
13578
13613
  ],
@@ -13580,32 +13615,32 @@ function buildHooksConfig(hooksDir) {
13580
13615
  {
13581
13616
  matcher: "Bash",
13582
13617
  hooks: [
13583
- { type: "command", command: hookCmd(hooksDir, "security-gate.js"), timeout: 5 }
13618
+ { type: "command", command: hookCmd(version, "security-gate"), timeout: 5 }
13584
13619
  ]
13585
13620
  },
13586
13621
  {
13587
13622
  matcher: "Bash|Write",
13588
13623
  hooks: [
13589
- { type: "command", command: hookCmd(hooksDir, "pre-delete-check.js"), timeout: 5 }
13624
+ { type: "command", command: hookCmd(version, "pre-delete-check"), timeout: 5 }
13590
13625
  ]
13591
13626
  }
13592
13627
  ],
13593
13628
  PostToolUse: [
13594
13629
  {
13595
13630
  hooks: [
13596
- { type: "command", command: hookCmd(hooksDir, "post-tool-use.js"), timeout: 10 },
13597
- { type: "command", command: hookCmd(hooksDir, "quality-event.js"), timeout: 5 },
13598
- { type: "command", command: hookCmd(hooksDir, "cost-tracker.js"), timeout: 5 }
13631
+ { type: "command", command: hookCmd(version, "post-tool-use"), timeout: 10 },
13632
+ { type: "command", command: hookCmd(version, "quality-event"), timeout: 5 },
13633
+ { type: "command", command: hookCmd(version, "cost-tracker"), timeout: 5 }
13599
13634
  ]
13600
13635
  },
13601
13636
  {
13602
13637
  matcher: "Edit|Write",
13603
13638
  hooks: [
13604
- { type: "command", command: hookCmd(hooksDir, "post-edit-context.js"), timeout: 5 },
13639
+ { type: "command", command: hookCmd(version, "post-edit-context"), timeout: 5 },
13605
13640
  // Auto-learning pipeline — classifies failures and detects fixes on
13606
13641
  // file changes. See Phase 5-6 of the autodetect plan.
13607
- { type: "command", command: hookCmd(hooksDir, "fix-detector.js"), timeout: 5 },
13608
- { type: "command", command: hookCmd(hooksDir, "classify-failure.js"), timeout: 5 }
13642
+ { type: "command", command: hookCmd(version, "fix-detector"), timeout: 5 },
13643
+ { type: "command", command: hookCmd(version, "classify-failure"), timeout: 5 }
13609
13644
  ]
13610
13645
  },
13611
13646
  {
@@ -13613,37 +13648,86 @@ function buildHooksConfig(hooksDir) {
13613
13648
  hooks: [
13614
13649
  // Incident + rule enforcement pipelines fire on Write-only (incidents
13615
13650
  // are authored as .md files; rules are enforced after new-file drops).
13616
- { type: "command", command: hookCmd(hooksDir, "incident-pipeline.js"), timeout: 5 },
13617
- { type: "command", command: hookCmd(hooksDir, "rule-enforcement-pipeline.js"), timeout: 5 }
13651
+ { type: "command", command: hookCmd(version, "incident-pipeline"), timeout: 5 },
13652
+ { type: "command", command: hookCmd(version, "rule-enforcement-pipeline"), timeout: 5 }
13618
13653
  ]
13619
13654
  }
13620
13655
  ],
13621
13656
  Stop: [
13622
13657
  {
13623
13658
  hooks: [
13624
- { type: "command", command: hookCmd(hooksDir, "session-end.js"), timeout: 15 },
13659
+ { type: "command", command: hookCmd(version, "session-end"), timeout: 15 },
13625
13660
  // Session-end auto-learning aggregation (failure-class roll-up).
13626
- { type: "command", command: hookCmd(hooksDir, "auto-learning-pipeline.js"), timeout: 10 }
13661
+ { type: "command", command: hookCmd(version, "auto-learning-pipeline"), timeout: 10 }
13627
13662
  ]
13628
13663
  }
13629
13664
  ],
13630
13665
  PreCompact: [
13631
13666
  {
13632
13667
  hooks: [
13633
- { type: "command", command: hookCmd(hooksDir, "pre-compact.js"), timeout: 10 }
13668
+ { type: "command", command: hookCmd(version, "pre-compact"), timeout: 10 }
13634
13669
  ]
13635
13670
  }
13636
13671
  ],
13637
13672
  UserPromptSubmit: [
13638
13673
  {
13639
13674
  hooks: [
13640
- { type: "command", command: hookCmd(hooksDir, "user-prompt.js"), timeout: 5 },
13641
- { type: "command", command: hookCmd(hooksDir, "intent-suggester.js"), timeout: 5 }
13675
+ { type: "command", command: hookCmd(version, "user-prompt"), timeout: 5 },
13676
+ { type: "command", command: hookCmd(version, "intent-suggester"), timeout: 5 }
13642
13677
  ]
13643
13678
  }
13644
13679
  ]
13645
13680
  };
13646
13681
  }
13682
+ function mergeHooksConfig(existing, additions) {
13683
+ const eventNames = /* @__PURE__ */ new Set([
13684
+ ...Object.keys(existing ?? {}),
13685
+ ...Object.keys(additions ?? {})
13686
+ ]);
13687
+ const merged = {};
13688
+ for (const event of eventNames) {
13689
+ const existingGroups = existing?.[event] ?? [];
13690
+ const additionGroups = additions?.[event] ?? [];
13691
+ const byMatcher = /* @__PURE__ */ new Map();
13692
+ for (const group of existingGroups) {
13693
+ const key = group.matcher ?? "";
13694
+ const existingGroup = byMatcher.get(key);
13695
+ if (existingGroup) {
13696
+ existingGroup.hooks = mergeHookEntries(existingGroup.hooks, group.hooks);
13697
+ } else {
13698
+ byMatcher.set(key, { ...group, hooks: [...group.hooks ?? []] });
13699
+ }
13700
+ }
13701
+ for (const group of additionGroups) {
13702
+ const key = group.matcher ?? "";
13703
+ const existingGroup = byMatcher.get(key);
13704
+ if (existingGroup) {
13705
+ existingGroup.hooks = mergeHookEntries(existingGroup.hooks, group.hooks);
13706
+ } else {
13707
+ byMatcher.set(key, { ...group, hooks: [...group.hooks ?? []] });
13708
+ }
13709
+ }
13710
+ merged[event] = Array.from(byMatcher.values());
13711
+ }
13712
+ return merged;
13713
+ }
13714
+ function mergeHookEntries(existing, additions) {
13715
+ const seen = /* @__PURE__ */ new Set();
13716
+ const result = [];
13717
+ for (const entry of additions ?? []) {
13718
+ if (!entry || typeof entry.command !== "string") continue;
13719
+ if (seen.has(entry.command)) continue;
13720
+ seen.add(entry.command);
13721
+ result.push(entry);
13722
+ }
13723
+ for (const entry of existing ?? []) {
13724
+ if (!entry || typeof entry.command !== "string") continue;
13725
+ if (seen.has(entry.command)) continue;
13726
+ seen.add(entry.command);
13727
+ result.push(entry);
13728
+ }
13729
+ return result;
13730
+ }
13647
13731
  function installHooks(projectRoot) {
13648
13732
  let claudeDirName = ".claude";
13649
13733
  try {
@@ -13656,21 +13740,39 @@ function installHooks(projectRoot) {
13656
13740
  mkdirSync5(claudeDir, { recursive: true });
13657
13741
  }
13658
13742
  const settings = readSettingsLocal(claudeDir);
13659
- const hooksDir = resolveHooksDir();
13660
- const hooksConfig = buildHooksConfig(hooksDir);
13743
+ const hooksConfig = buildHooksConfig(resolveHooksDir());
13744
+ const existingHooks = settings.hooks ?? {};
13745
+ const mergedHooks = mergeHooksConfig(existingHooks, hooksConfig);
13661
13746
  let hookCount = 0;
13662
- for (const groups of Object.values(hooksConfig)) {
13747
+ for (const groups of Object.values(mergedHooks)) {
13663
13748
  for (const group of groups) {
13664
13749
  hookCount += group.hooks.length;
13665
13750
  }
13666
13751
  }
13667
- settings.hooks = hooksConfig;
13752
+ settings.hooks = mergedHooks;
13668
13753
  writeSettingsLocalAtomic(claudeDir, settings);
13669
13754
  return { installed: true, count: hookCount };
13670
13755
  }
13671
13756
  function initMemoryDir(projectRoot) {
13672
- const encodedRoot = "-" + projectRoot.replace(/\//g, "-");
13757
+ const encodedRoot = encodeMemoryDirName(projectRoot);
13673
13758
  const memoryDir = resolve7(homedir4(), `.claude/projects/${encodedRoot}/memory`);
13759
+ let migratedFromLegacy = false;
13760
+ const legacyDir = resolve7(homedir4(), `.claude/projects/-${encodedRoot}/memory`);
13761
+ if (existsSync11(legacyDir) && !existsSync11(memoryDir)) {
13762
+ try {
13763
+ mkdirSync5(resolve7(memoryDir, ".."), { recursive: true });
13764
+ renameSync3(legacyDir, memoryDir);
13765
+ try {
13766
+ const legacyParent = resolve7(legacyDir, "..");
13767
+ if (existsSync11(legacyParent) && readdirSync10(legacyParent).length === 0) {
13768
+ rmSync2(legacyParent, { recursive: false });
13769
+ }
13770
+ } catch {
13771
+ }
13772
+ migratedFromLegacy = true;
13773
+ } catch {
13774
+ }
13775
+ }
13674
13776
  let created = false;
13675
13777
  if (!existsSync11(memoryDir)) {
13676
13778
  mkdirSync5(memoryDir, { recursive: true });
@@ -13697,7 +13799,7 @@ function initMemoryDir(projectRoot) {
13697
13799
  writeFileSync2(memoryMdPath, memoryContent, "utf-8");
13698
13800
  memoryMdCreated = true;
13699
13801
  }
13700
- return { created, memoryMdCreated };
13802
+ return { created, memoryMdCreated, migratedFromLegacy };
13701
13803
  }
13702
13804
  function parseInitArgs(argv) {
13703
13805
  const opts = {};
@@ -13956,16 +14058,19 @@ function installSideEffects(projectRoot, log, skipCommands = false, emptyStack =
13956
14058
  } catch {
13957
14059
  }
13958
14060
  }
13959
- const { created: memDirCreated, memoryMdCreated } = initMemoryDir(projectRoot);
14061
+ const { created: memDirCreated, memoryMdCreated, migratedFromLegacy } = initMemoryDir(projectRoot);
13960
14062
  if (memDirCreated) {
13961
14063
  log(" Created memory directory");
13962
14064
  }
13963
14065
  if (memoryMdCreated) {
13964
14066
  log(" Created initial MEMORY.md");
13965
14067
  }
14068
+ if (migratedFromLegacy) {
14069
+ log(" Migrated memory directory from legacy double-dash path (pre-1.9.4)");
14070
+ }
13966
14071
  (async () => {
13967
14072
  try {
13968
- const encodedRoot = projectRoot.replace(/\//g, "-");
14073
+ const encodedRoot = encodeMemoryDirName(projectRoot);
13969
14074
  const memoryDir = resolve7(homedir4(), ".claude", "projects", encodedRoot, "memory");
13970
14075
  const memFiles = existsSync11(memoryDir) ? readdirSync10(memoryDir).filter((f2) => f2.endsWith(".md") && f2 !== "MEMORY.md") : [];
13971
14076
  if (memFiles.length > 0) {
@@ -14025,6 +14130,7 @@ var init_init = __esm({
14025
14130
  init_config();
14026
14131
  init_install_commands();
14027
14132
  init_settings_local();
14133
+ init_memory_path();
14028
14134
  init_detect();
14029
14135
  init_drift();
14030
14136
  __filename2 = fileURLToPath2(import.meta.url);
@@ -14756,13 +14862,113 @@ var init_install_hooks = __esm({
14756
14862
  }
14757
14863
  });
14758
14864
 
14865
+ // src/commands/hook-runner.ts
14866
+ var hook_runner_exports = {};
14867
+ __export(hook_runner_exports, {
14868
+ HOOK_NAME_TO_FILE: () => HOOK_NAME_TO_FILE,
14869
+ resolveHookFile: () => resolveHookFile,
14870
+ runHookRunner: () => runHookRunner
14871
+ });
14872
+ import { existsSync as existsSync13 } from "fs";
14873
+ import { resolve as resolve9, dirname as dirname8 } from "path";
14874
+ import { fileURLToPath as fileURLToPath4 } from "url";
14875
+ import { spawn } from "child_process";
14876
+ function resolveHookFile(hookName) {
14877
+ const file = HOOK_NAME_TO_FILE[hookName];
14878
+ if (!file) {
14879
+ throw new Error(
14880
+ `Unknown hook: "${hookName}". Recognized: ${Object.keys(HOOK_NAME_TO_FILE).join(", ")}`
14881
+ );
14882
+ }
14883
+ const candidates = [
14884
+ // Bundled compiled layout: dist/cli.js → ./hooks/<file>.js
14885
+ resolve9(__dirname4, "hooks", file),
14886
+ // TS-source dev / sibling layout: src/commands/ → ../hooks/<file>
14887
+ resolve9(__dirname4, "../hooks", file),
14888
+ // TS-source dev fallback: src/commands/ → ../../dist/hooks/<file>
14889
+ resolve9(__dirname4, "../../dist/hooks", file)
14890
+ ];
14891
+ for (const candidate of candidates) {
14892
+ if (existsSync13(candidate)) {
14893
+ return candidate;
14894
+ }
14895
+ }
14896
+ throw new Error(
14897
+ `Hook file not found for "${hookName}". Searched: ${candidates.join(", ")}. This indicates a broken @massu/core install. Re-run \`npx -y @massu/core init\`.`
14898
+ );
14899
+ }
14900
+ async function runHookRunner(args2) {
14901
+ const hookName = args2[0];
14902
+ if (!hookName) {
14903
+ process.stderr.write(
14904
+ `massu hook-runner: missing hook name.
14905
+ Usage: massu hook-runner <hook-name>
14906
+ Recognized: ${Object.keys(HOOK_NAME_TO_FILE).join(", ")}
14907
+ `
14908
+ );
14909
+ return { exitCode: 2 };
14910
+ }
14911
+ let hookFile;
14912
+ try {
14913
+ hookFile = resolveHookFile(hookName);
14914
+ } catch (err) {
14915
+ process.stderr.write(`massu hook-runner: ${err instanceof Error ? err.message : String(err)}
14916
+ `);
14917
+ return { exitCode: 2 };
14918
+ }
14919
+ return new Promise((resolvePromise) => {
14920
+ const child = spawn(process.execPath, [hookFile], {
14921
+ stdio: ["inherit", "inherit", "inherit"],
14922
+ env: process.env
14923
+ });
14924
+ child.on("exit", (code, signal) => {
14925
+ if (signal) {
14926
+ resolvePromise({ exitCode: 128 });
14927
+ return;
14928
+ }
14929
+ resolvePromise({ exitCode: code ?? 0 });
14930
+ });
14931
+ child.on("error", (err) => {
14932
+ process.stderr.write(`massu hook-runner: failed to spawn hook "${hookName}": ${err.message}
14933
+ `);
14934
+ resolvePromise({ exitCode: 2 });
14935
+ });
14936
+ });
14937
+ }
14938
+ var __filename4, __dirname4, HOOK_NAME_TO_FILE;
14939
+ var init_hook_runner = __esm({
14940
+ "src/commands/hook-runner.ts"() {
14941
+ "use strict";
14942
+ __filename4 = fileURLToPath4(import.meta.url);
14943
+ __dirname4 = dirname8(__filename4);
14944
+ HOOK_NAME_TO_FILE = {
14945
+ "session-start": "session-start.js",
14946
+ "session-end": "session-end.js",
14947
+ "security-gate": "security-gate.js",
14948
+ "pre-delete-check": "pre-delete-check.js",
14949
+ "post-tool-use": "post-tool-use.js",
14950
+ "post-edit-context": "post-edit-context.js",
14951
+ "quality-event": "quality-event.js",
14952
+ "cost-tracker": "cost-tracker.js",
14953
+ "fix-detector": "fix-detector.js",
14954
+ "classify-failure": "classify-failure.js",
14955
+ "incident-pipeline": "incident-pipeline.js",
14956
+ "rule-enforcement-pipeline": "rule-enforcement-pipeline.js",
14957
+ "auto-learning-pipeline": "auto-learning-pipeline.js",
14958
+ "pre-compact": "pre-compact.js",
14959
+ "user-prompt": "user-prompt.js",
14960
+ "intent-suggester": "intent-suggester.js"
14961
+ };
14962
+ }
14963
+ });
14964
+
14759
14965
  // src/commands/permissions.ts
14760
14966
  var permissions_exports = {};
14761
14967
  __export(permissions_exports, {
14762
14968
  handlePermissionsSubcommand: () => handlePermissionsSubcommand,
14763
14969
  printPermissionsHelp: () => printPermissionsHelp
14764
14970
  });
14765
- import { resolve as resolve9 } from "path";
14971
+ import { resolve as resolve10 } from "path";
14766
14972
  function resolveClaudeDir2() {
14767
14973
  let claudeDirName = ".claude";
14768
14974
  try {
@@ -14770,7 +14976,7 @@ function resolveClaudeDir2() {
14770
14976
  } catch {
14771
14977
  claudeDirName = ".claude";
14772
14978
  }
14773
- return resolve9(process.cwd(), claudeDirName);
14979
+ return resolve10(process.cwd(), claudeDirName);
14774
14980
  }
14775
14981
  async function handlePermissionsSubcommand(args2) {
14776
14982
  const sub = args2[0];
@@ -14884,8 +15090,8 @@ var init_permissions2 = __esm({
14884
15090
  });
14885
15091
 
14886
15092
  // src/changelog-generator.ts
14887
- import { existsSync as existsSync13, readFileSync as readFileSync13, readdirSync as readdirSync12 } from "fs";
14888
- import { resolve as resolve10 } from "path";
15093
+ import { existsSync as existsSync14, readFileSync as readFileSync13, readdirSync as readdirSync12 } from "fs";
15094
+ import { resolve as resolve11 } from "path";
14889
15095
  function parseCommitsForPlanTokens(subjects) {
14890
15096
  const tokens = /* @__PURE__ */ new Set();
14891
15097
  const maintenance = [];
@@ -14902,7 +15108,7 @@ function parseCommitsForPlanTokens(subjects) {
14902
15108
  function loadPlanSummaries(tokens, planDir) {
14903
15109
  const result = /* @__PURE__ */ new Map();
14904
15110
  if (tokens.size === 0) return result;
14905
- if (!existsSync13(planDir)) {
15111
+ if (!existsSync14(planDir)) {
14906
15112
  throw new Error(`Plan directory does not exist: ${planDir}`);
14907
15113
  }
14908
15114
  const files = readdirSync12(planDir).filter((f2) => f2.endsWith(".md"));
@@ -14910,7 +15116,7 @@ function loadPlanSummaries(tokens, planDir) {
14910
15116
  let matchedFile = null;
14911
15117
  let content = "";
14912
15118
  for (const file of files) {
14913
- const path = resolve10(planDir, file);
15119
+ const path = resolve11(planDir, file);
14914
15120
  const text18 = readFileSync13(path, "utf-8");
14915
15121
  const tokenRe = new RegExp(
14916
15122
  `^\\*\\*Plan Token\\*\\*:\\s*\`?${token.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&")}\`?(\\s|$)`,
@@ -14992,8 +15198,8 @@ __export(changelog_exports, {
14992
15198
  printChangelogHelp: () => printChangelogHelp
14993
15199
  });
14994
15200
  import { execSync } from "child_process";
14995
- import { existsSync as existsSync14, readFileSync as readFileSync14 } from "fs";
14996
- import { resolve as resolve11 } from "path";
15201
+ import { existsSync as existsSync15, readFileSync as readFileSync14 } from "fs";
15202
+ import { resolve as resolve12 } from "path";
14997
15203
  function resolveRepoRoot() {
14998
15204
  try {
14999
15205
  return execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
@@ -15017,8 +15223,8 @@ function getCommitSubjects(range) {
15017
15223
  }
15018
15224
  }
15019
15225
  function getCurrentVersion(repoRoot) {
15020
- const pkgPath = resolve11(repoRoot, "packages/core/package.json");
15021
- if (!existsSync14(pkgPath)) return "0.0.0";
15226
+ const pkgPath = resolve12(repoRoot, "packages/core/package.json");
15227
+ if (!existsSync15(pkgPath)) return "0.0.0";
15022
15228
  const pkg = JSON.parse(readFileSync14(pkgPath, "utf-8"));
15023
15229
  return pkg.version || "0.0.0";
15024
15230
  }
@@ -15026,8 +15232,8 @@ function todayDate() {
15026
15232
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
15027
15233
  }
15028
15234
  function getLatestChangelogEntryBody(repoRoot) {
15029
- const path = resolve11(repoRoot, "CHANGELOG.md");
15030
- if (!existsSync14(path)) return "";
15235
+ const path = resolve12(repoRoot, "CHANGELOG.md");
15236
+ if (!existsSync15(path)) return "";
15031
15237
  const content = readFileSync14(path, "utf-8");
15032
15238
  const m3 = content.match(/^## \[[\d.]+\][^\n]*\n([\s\S]*?)(?=\n## \[|$)/m);
15033
15239
  return m3 ? m3[1] : "";
@@ -15035,7 +15241,7 @@ function getLatestChangelogEntryBody(repoRoot) {
15035
15241
  async function handleChangelogSubcommand(args2) {
15036
15242
  const sub = args2[0];
15037
15243
  const repoRoot = resolveRepoRoot();
15038
- const planDir = resolve11(repoRoot, "docs/plans");
15244
+ const planDir = resolve12(repoRoot, "docs/plans");
15039
15245
  switch (sub) {
15040
15246
  case "generate": {
15041
15247
  const lastTag = getLastTag();
@@ -15127,8 +15333,8 @@ var show_template_exports = {};
15127
15333
  __export(show_template_exports, {
15128
15334
  runShowTemplate: () => runShowTemplate
15129
15335
  });
15130
- import { existsSync as existsSync15, readFileSync as readFileSync15 } from "fs";
15131
- import { resolve as resolve12 } from "path";
15336
+ import { existsSync as existsSync16, readFileSync as readFileSync15 } from "fs";
15337
+ import { resolve as resolve13 } from "path";
15132
15338
  function normalizeBaseName(input) {
15133
15339
  return input.endsWith(".md") ? input.slice(0, -".md".length) : input;
15134
15340
  }
@@ -15156,8 +15362,8 @@ async function runShowTemplate(args2) {
15156
15362
  return;
15157
15363
  }
15158
15364
  const suffix = choice.kind === "hit" ? choice.suffix : "";
15159
- const file = suffix === "" ? resolve12(sourceDir, `${baseName}.md`) : resolve12(sourceDir, `${baseName}${suffix}.md`);
15160
- if (!existsSync15(file)) {
15365
+ const file = suffix === "" ? resolve13(sourceDir, `${baseName}.md`) : resolve13(sourceDir, `${baseName}${suffix}.md`);
15366
+ if (!existsSync16(file)) {
15161
15367
  process.stderr.write(`massu: resolved template "${file}" no longer exists
15162
15368
  `);
15163
15369
  process.exit(1);
@@ -15217,7 +15423,7 @@ var init_passthrough = __esm({
15217
15423
 
15218
15424
  // src/lib/fileLock.ts
15219
15425
  import { mkdirSync as mkdirSync6, readFileSync as readFileSync16, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "fs";
15220
- import { dirname as dirname8 } from "path";
15426
+ import { dirname as dirname9 } from "path";
15221
15427
  import * as lockfile from "proper-lockfile";
15222
15428
  function readLockHolderPid(lockPath) {
15223
15429
  try {
@@ -15240,7 +15446,7 @@ function busyWaitSync(ms) {
15240
15446
  Atomics.wait(view, 0, 0, ms);
15241
15447
  }
15242
15448
  function withFileLockSync(lockPath, fn, opts = {}) {
15243
- mkdirSync6(dirname8(lockPath), { recursive: true });
15449
+ mkdirSync6(dirname9(lockPath), { recursive: true });
15244
15450
  const staleMs = opts.staleMs ?? 3e4;
15245
15451
  const blockMs = opts.retries === 0 ? 0 : opts.blockMs ?? 3e4;
15246
15452
  const pollIntervalMs = opts.pollIntervalMs ?? 100;
@@ -15308,9 +15514,9 @@ var init_fileLock = __esm({
15308
15514
  });
15309
15515
 
15310
15516
  // src/lib/installLock.ts
15311
- import { resolve as resolve13 } from "path";
15517
+ import { resolve as resolve14 } from "path";
15312
15518
  function withInstallLock(projectRoot, fn, opts = {}) {
15313
- const lockPath = resolve13(projectRoot, ".massu", "installAll.lock");
15519
+ const lockPath = resolve14(projectRoot, ".massu", "installAll.lock");
15314
15520
  return withFileLockSync(
15315
15521
  lockPath,
15316
15522
  fn,
@@ -15346,8 +15552,8 @@ __export(config_refresh_exports, {
15346
15552
  mergeRefresh: () => mergeRefresh,
15347
15553
  runConfigRefresh: () => runConfigRefresh
15348
15554
  });
15349
- import { existsSync as existsSync16, readFileSync as readFileSync17, rmSync as rmSync4 } from "fs";
15350
- import { resolve as resolve14 } from "path";
15555
+ import { existsSync as existsSync17, readFileSync as readFileSync17, rmSync as rmSync4 } from "fs";
15556
+ import { resolve as resolve15 } from "path";
15351
15557
  import { parse as parseYaml5 } from "yaml";
15352
15558
  function flatten(obj, prefix3 = "") {
15353
15559
  const out = {};
@@ -15475,10 +15681,10 @@ function renderDiff(diff) {
15475
15681
  }
15476
15682
  async function runConfigRefresh(opts = {}) {
15477
15683
  const cwd = opts.cwd ?? process.cwd();
15478
- const configPath = resolve14(cwd, "massu.config.yaml");
15684
+ const configPath = resolve15(cwd, "massu.config.yaml");
15479
15685
  const log = opts.silent ? () => {
15480
15686
  } : (s) => process.stdout.write(s);
15481
- if (!existsSync16(configPath)) {
15687
+ if (!existsSync17(configPath)) {
15482
15688
  const message = "massu.config.yaml not found. Run: npx massu init";
15483
15689
  if (!opts.silent) process.stderr.write(message + "\n");
15484
15690
  return { exitCode: 1, applied: false, dryRun: !!opts.dryRun, diff: [], message };
@@ -15558,8 +15764,8 @@ async function runConfigRefresh(opts = {}) {
15558
15764
  `);
15559
15765
  const stackResolved = installResult.totalInstalled > 0 || installResult.totalUpdated > 0;
15560
15766
  if (stackResolved) {
15561
- const placeholderPath = resolve14(installResult.claudeDir, "commands", "_massu-needs-stack.md");
15562
- if (existsSync16(placeholderPath)) {
15767
+ const placeholderPath = resolve15(installResult.claudeDir, "commands", "_massu-needs-stack.md");
15768
+ if (existsSync17(placeholderPath)) {
15563
15769
  try {
15564
15770
  rmSync4(placeholderPath, { force: true });
15565
15771
  log("Removed _massu-needs-stack.md (stack now declared).\n");
@@ -15668,12 +15874,12 @@ var init_gitToplevel = __esm({
15668
15874
  });
15669
15875
 
15670
15876
  // src/watch/lockfile-detector.ts
15671
- import { existsSync as existsSync17, statSync as statSync8 } from "fs";
15672
- import { resolve as resolve15 } from "path";
15877
+ import { existsSync as existsSync18, statSync as statSync8 } from "fs";
15878
+ import { resolve as resolve16 } from "path";
15673
15879
  function lockfileMidWrite(projectRoot, now = Date.now(), windowMs = LOCKFILE_WINDOW_MS) {
15674
15880
  for (const lf of KNOWN_LOCKFILES) {
15675
- const p19 = resolve15(projectRoot, lf);
15676
- if (!existsSync17(p19)) continue;
15881
+ const p19 = resolve16(projectRoot, lf);
15882
+ if (!existsSync18(p19)) continue;
15677
15883
  try {
15678
15884
  const stat = statSync8(p19);
15679
15885
  const delta = now - stat.mtimeMs;
@@ -15686,7 +15892,7 @@ function lockfileMidWrite(projectRoot, now = Date.now(), windowMs = LOCKFILE_WIN
15686
15892
  function gitMidOperation(projectRoot) {
15687
15893
  const sentinels = ["MERGE_HEAD", "REBASE_HEAD", "CHERRY_PICK_HEAD", "rebase-apply", "rebase-merge"];
15688
15894
  for (const s of sentinels) {
15689
- if (existsSync17(resolve15(projectRoot, ".git", s))) return true;
15895
+ if (existsSync18(resolve16(projectRoot, ".git", s))) return true;
15690
15896
  }
15691
15897
  return false;
15692
15898
  }
@@ -15883,17 +16089,17 @@ var init_paths = __esm({
15883
16089
  });
15884
16090
 
15885
16091
  // src/watch/state.ts
15886
- import { closeSync as closeSync3, existsSync as existsSync18, fsyncSync as fsyncSync3, mkdirSync as mkdirSync7, openSync as openSync3, readFileSync as readFileSync18, renameSync as renameSync4, rmSync as rmSync5, writeFileSync as writeFileSync4, writeSync as writeSync3 } from "fs";
15887
- import { dirname as dirname9, resolve as resolve16 } from "path";
16092
+ import { closeSync as closeSync3, existsSync as existsSync19, fsyncSync as fsyncSync3, mkdirSync as mkdirSync7, openSync as openSync3, readFileSync as readFileSync18, renameSync as renameSync4, rmSync as rmSync5, writeFileSync as writeFileSync4, writeSync as writeSync3 } from "fs";
16093
+ import { dirname as dirname10, resolve as resolve17 } from "path";
15888
16094
  function watchStatePath(projectRoot) {
15889
- return resolve16(projectRoot, ".massu", "watch-state.json");
16095
+ return resolve17(projectRoot, ".massu", "watch-state.json");
15890
16096
  }
15891
16097
  function backupStatePath(projectRoot) {
15892
- return resolve16(projectRoot, ".massu", "watch-state.v0.bak.json");
16098
+ return resolve17(projectRoot, ".massu", "watch-state.v0.bak.json");
15893
16099
  }
15894
16100
  function readState(projectRoot) {
15895
16101
  const path = watchStatePath(projectRoot);
15896
- if (!existsSync18(path)) return { ...DEFAULT_STATE };
16102
+ if (!existsSync19(path)) return { ...DEFAULT_STATE };
15897
16103
  const content = readFileSync18(path, "utf-8");
15898
16104
  let raw;
15899
16105
  try {
@@ -15936,14 +16142,14 @@ function readState(projectRoot) {
15936
16142
  }
15937
16143
  function archiveCorrupt(projectRoot, content) {
15938
16144
  const bak = backupStatePath(projectRoot);
15939
- mkdirSync7(dirname9(bak), { recursive: true });
16145
+ mkdirSync7(dirname10(bak), { recursive: true });
15940
16146
  writeFileSync4(bak, content, "utf-8");
15941
16147
  }
15942
16148
  function writeStateAtomic(projectRoot, state) {
15943
16149
  const path = watchStatePath(projectRoot);
15944
16150
  writeStateAtomicCounter = writeStateAtomicCounter + 1 >>> 0;
15945
16151
  const tmp = `${path}.${process.pid}.${writeStateAtomicCounter}.tmp`;
15946
- mkdirSync7(dirname9(path), { recursive: true });
16152
+ mkdirSync7(dirname10(path), { recursive: true });
15947
16153
  let renamed = false;
15948
16154
  try {
15949
16155
  const fd = openSync3(tmp, "w");
@@ -15957,7 +16163,7 @@ function writeStateAtomic(projectRoot, state) {
15957
16163
  renameSync4(tmp, path);
15958
16164
  renamed = true;
15959
16165
  } finally {
15960
- if (!renamed && existsSync18(tmp)) {
16166
+ if (!renamed && existsSync19(tmp)) {
15961
16167
  try {
15962
16168
  rmSync5(tmp, { force: true });
15963
16169
  } catch {
@@ -16237,8 +16443,8 @@ __export(watch_exports, {
16237
16443
  runWatch: () => runWatch
16238
16444
  });
16239
16445
  import { spawnSync as spawnSync3 } from "child_process";
16240
- import { basename as basename5, dirname as dirname10, resolve as resolve17 } from "path";
16241
- import { appendFileSync, existsSync as existsSync19, mkdirSync as mkdirSync8, readFileSync as readFileSync19 } from "fs";
16446
+ import { basename as basename5, dirname as dirname11, resolve as resolve18 } from "path";
16447
+ import { appendFileSync, existsSync as existsSync20, mkdirSync as mkdirSync8, readFileSync as readFileSync19 } from "fs";
16242
16448
  function parseFlags(args2) {
16243
16449
  const out = {
16244
16450
  foreground: false,
@@ -16263,8 +16469,8 @@ function parseFlags(args2) {
16263
16469
  }
16264
16470
  function findClaudeBg() {
16265
16471
  const home = process.env.HOME ?? "";
16266
- const fixed = home ? resolve17(home, ".claude", "bin", "claude-bg") : null;
16267
- if (fixed && existsSync19(fixed)) return fixed;
16472
+ const fixed = home ? resolve18(home, ".claude", "bin", "claude-bg") : null;
16473
+ if (fixed && existsSync20(fixed)) return fixed;
16268
16474
  const which = spawnSync3("which", ["claude-bg"], { encoding: "utf-8" });
16269
16475
  if (which.status === 0 && which.stdout) {
16270
16476
  const p19 = which.stdout.trim();
@@ -16325,7 +16531,7 @@ async function runWatch(args2) {
16325
16531
  }
16326
16532
  function runStatus(root) {
16327
16533
  const path = watchStatePath(root);
16328
- if (!existsSync19(path)) {
16534
+ if (!existsSync20(path)) {
16329
16535
  process.stdout.write("massu watch: not running (no state file)\n");
16330
16536
  return { exitCode: 0 };
16331
16537
  }
@@ -16407,7 +16613,7 @@ async function runForeground(root) {
16407
16613
  }
16408
16614
  throw err;
16409
16615
  }
16410
- return new Promise((resolve40) => {
16616
+ return new Promise((resolve41) => {
16411
16617
  const shutdown = async () => {
16412
16618
  if (stopped) return;
16413
16619
  stopped = true;
@@ -16417,7 +16623,7 @@ async function runForeground(root) {
16417
16623
  process.chdir(priorCwd);
16418
16624
  } catch {
16419
16625
  }
16420
- resolve40({ exitCode: 0 });
16626
+ resolve41({ exitCode: 0 });
16421
16627
  };
16422
16628
  process.on("SIGINT", () => {
16423
16629
  void shutdown();
@@ -16478,19 +16684,19 @@ async function runOnQuiescent(projectRoot) {
16478
16684
  );
16479
16685
  }
16480
16686
  function refreshLogPath(projectRoot) {
16481
- return resolve17(projectRoot, ".massu", "refresh-log.jsonl");
16687
+ return resolve18(projectRoot, ".massu", "refresh-log.jsonl");
16482
16688
  }
16483
16689
  function appendRefreshLog(projectRoot, event) {
16484
16690
  const path = refreshLogPath(projectRoot);
16485
16691
  try {
16486
- mkdirSync8(dirname10(path), { recursive: true });
16692
+ mkdirSync8(dirname11(path), { recursive: true });
16487
16693
  appendFileSync(path, JSON.stringify(event) + "\n", "utf-8");
16488
16694
  } catch {
16489
16695
  }
16490
16696
  }
16491
16697
  function readRefreshLog(projectRoot, limit = 10, opts = {}) {
16492
16698
  const path = refreshLogPath(projectRoot);
16493
- if (!existsSync19(path)) return [];
16699
+ if (!existsSync20(path)) return [];
16494
16700
  const warn = opts.warn ?? ((s) => {
16495
16701
  process.stderr.write(s);
16496
16702
  });
@@ -16567,7 +16773,7 @@ var init_refresh_log = __esm({
16567
16773
  import {
16568
16774
  chmodSync as chmodSync3,
16569
16775
  closeSync as closeSync4,
16570
- existsSync as existsSync20,
16776
+ existsSync as existsSync21,
16571
16777
  fsyncSync as fsyncSync4,
16572
16778
  mkdirSync as mkdirSync9,
16573
16779
  openSync as openSync4,
@@ -16576,12 +16782,12 @@ import {
16576
16782
  statSync as statSync9,
16577
16783
  writeSync as writeSync4
16578
16784
  } from "node:fs";
16579
- import { dirname as dirname11 } from "node:path";
16785
+ import { dirname as dirname12 } from "node:path";
16580
16786
  function atomicWrite(path, content, opts = {}) {
16581
16787
  const tmpPath = `${path}.tmp`;
16582
- const parentDir = dirname11(path);
16788
+ const parentDir = dirname12(path);
16583
16789
  try {
16584
- if (!existsSync20(parentDir)) {
16790
+ if (!existsSync21(parentDir)) {
16585
16791
  const mkdirOpts = { recursive: true };
16586
16792
  if (opts.ensureParentDirMode !== void 0) {
16587
16793
  mkdirOpts.mode = opts.ensureParentDirMode;
@@ -16603,7 +16809,7 @@ function atomicWrite(path, content, opts = {}) {
16603
16809
  renameSync5(tmpPath, path);
16604
16810
  return { written: true };
16605
16811
  } catch (err) {
16606
- if (existsSync20(tmpPath)) {
16812
+ if (existsSync21(tmpPath)) {
16607
16813
  try {
16608
16814
  rmSync6(tmpPath, { force: true });
16609
16815
  } catch {
@@ -16946,19 +17152,19 @@ var init_fetcher = __esm({
16946
17152
  });
16947
17153
 
16948
17154
  // src/security/manifest-cache.ts
16949
- import { existsSync as existsSync21, readFileSync as readFileSync20, statSync as statSync10 } from "node:fs";
17155
+ import { existsSync as existsSync22, readFileSync as readFileSync20, statSync as statSync10 } from "node:fs";
16950
17156
  import { homedir as homedir5 } from "node:os";
16951
- import { resolve as resolve18 } from "node:path";
17157
+ import { resolve as resolve19 } from "node:path";
16952
17158
  import { z as z4 } from "zod";
16953
17159
  function defaultCachePaths() {
16954
- const dir = resolve18(homedir5(), ".massu");
17160
+ const dir = resolve19(homedir5(), ".massu");
16955
17161
  return {
16956
- cachePath: resolve18(dir, "adapter-manifest.json"),
16957
- lockPath: resolve18(dir, ".adapter-manifest.lock")
17162
+ cachePath: resolve19(dir, "adapter-manifest.json"),
17163
+ lockPath: resolve19(dir, ".adapter-manifest.lock")
16958
17164
  };
16959
17165
  }
16960
17166
  function loadCachedManifest(paths = defaultCachePaths()) {
16961
- if (!existsSync21(paths.cachePath)) {
17167
+ if (!existsSync22(paths.cachePath)) {
16962
17168
  return { kind: "absent" };
16963
17169
  }
16964
17170
  let raw;
@@ -17152,15 +17358,15 @@ var init_adapter_origin = __esm({
17152
17358
  });
17153
17359
 
17154
17360
  // src/security/local-fingerprint.ts
17155
- import { existsSync as existsSync22, readFileSync as readFileSync21, lstatSync as lstatSync5 } from "node:fs";
17361
+ import { existsSync as existsSync23, readFileSync as readFileSync21, lstatSync as lstatSync5 } from "node:fs";
17156
17362
  import { homedir as homedir6 } from "node:os";
17157
- import { resolve as resolve19, isAbsolute } from "node:path";
17363
+ import { resolve as resolve20, isAbsolute } from "node:path";
17158
17364
  import { createHash as createHash7 } from "node:crypto";
17159
17365
  import { z as z5 } from "zod";
17160
17366
  function computeLocalFingerprint(localPaths, projectRoot) {
17161
17367
  const tuples = [];
17162
17368
  for (const p19 of localPaths) {
17163
- const abs = isAbsolute(p19) ? p19 : resolve19(projectRoot, p19);
17369
+ const abs = isAbsolute(p19) ? p19 : resolve20(projectRoot, p19);
17164
17370
  let contentTag;
17165
17371
  try {
17166
17372
  const lst = lstatSync5(abs);
@@ -17181,7 +17387,7 @@ function computeLocalFingerprint(localPaths, projectRoot) {
17181
17387
  return createHash7("sha256").update(canonical).digest("hex");
17182
17388
  }
17183
17389
  function readFingerprintSentinel(path = FINGERPRINT_PATH) {
17184
- if (!existsSync22(path)) return null;
17390
+ if (!existsSync23(path)) return null;
17185
17391
  let raw;
17186
17392
  try {
17187
17393
  raw = JSON.parse(readFileSync21(path, "utf-8"));
@@ -17232,7 +17438,7 @@ var init_local_fingerprint = __esm({
17232
17438
  "use strict";
17233
17439
  init_atomic_write();
17234
17440
  init_manifest_schema();
17235
- FINGERPRINT_PATH = resolve19(homedir6(), ".massu", "adapters-local-fingerprint.json");
17441
+ FINGERPRINT_PATH = resolve20(homedir6(), ".massu", "adapters-local-fingerprint.json");
17236
17442
  FingerprintSentinelSchema = z5.object({
17237
17443
  fingerprint: z5.string().regex(/^[0-9a-f]{64}$/),
17238
17444
  source: z5.enum(["cli", "cli-resync"]),
@@ -17248,15 +17454,15 @@ var init_local_fingerprint = __esm({
17248
17454
  });
17249
17455
 
17250
17456
  // src/security/install-tracking.ts
17251
- import { readFileSync as readFileSync22, readdirSync as readdirSync13, lstatSync as lstatSync6, existsSync as existsSync23 } from "node:fs";
17457
+ import { readFileSync as readFileSync22, readdirSync as readdirSync13, lstatSync as lstatSync6, existsSync as existsSync24 } from "node:fs";
17252
17458
  import { join as join11, relative as relative5, sep } from "node:path";
17253
17459
  import { homedir as homedir7 } from "node:os";
17254
- import { resolve as resolve20 } from "node:path";
17460
+ import { resolve as resolve21 } from "node:path";
17255
17461
  import { createHash as createHash8 } from "node:crypto";
17256
17462
  import { z as z6 } from "zod";
17257
17463
  function containsHiddenDirs(packageDir) {
17258
17464
  for (const hidden of EXCLUDED_DIR_NAMES) {
17259
- if (existsSync23(`${packageDir}/${hidden}`)) {
17465
+ if (existsSync24(`${packageDir}/${hidden}`)) {
17260
17466
  return hidden;
17261
17467
  }
17262
17468
  }
@@ -17311,7 +17517,7 @@ function sha256OfDir(dir, opts = {}) {
17311
17517
  return top.digest("hex");
17312
17518
  }
17313
17519
  function readInstalledManifest(path = INSTALLED_MANIFEST_PATH) {
17314
- if (!existsSync23(path)) return {};
17520
+ if (!existsSync24(path)) return {};
17315
17521
  let raw;
17316
17522
  try {
17317
17523
  raw = JSON.parse(readFileSync22(path, "utf-8"));
@@ -17378,7 +17584,7 @@ var init_install_tracking = __esm({
17378
17584
  "src/security/install-tracking.ts"() {
17379
17585
  "use strict";
17380
17586
  init_atomic_write();
17381
- INSTALLED_MANIFEST_PATH = resolve20(homedir7(), ".massu", "adapter-manifest-installed.json");
17587
+ INSTALLED_MANIFEST_PATH = resolve21(homedir7(), ".massu", "adapter-manifest-installed.json");
17382
17588
  DEFAULT_MAX_FILE_BYTES = 64 * 1024 * 1024;
17383
17589
  EXCLUDED_DIR_NAMES = /* @__PURE__ */ new Set([".git", "node_modules", ".cache", ".tmp"]);
17384
17590
  InstallEntrySchema = z6.object({
@@ -17401,12 +17607,12 @@ var init_install_tracking = __esm({
17401
17607
  });
17402
17608
 
17403
17609
  // src/detect/adapters/discover.ts
17404
- import { existsSync as existsSync24, readdirSync as readdirSync14, readFileSync as readFileSync23, lstatSync as lstatSync7 } from "node:fs";
17405
- import { resolve as resolve21, isAbsolute as isAbsolute2 } from "node:path";
17610
+ import { existsSync as existsSync25, readdirSync as readdirSync14, readFileSync as readFileSync23, lstatSync as lstatSync7 } from "node:fs";
17611
+ import { resolve as resolve22, isAbsolute as isAbsolute2 } from "node:path";
17406
17612
  import { z as z7 } from "zod";
17407
17613
  function walkNodeModules(projectRoot, warnings) {
17408
- const nodeModulesDir = resolve21(projectRoot, "node_modules");
17409
- if (!existsSync24(nodeModulesDir)) {
17614
+ const nodeModulesDir = resolve22(projectRoot, "node_modules");
17615
+ if (!existsSync25(nodeModulesDir)) {
17410
17616
  return [];
17411
17617
  }
17412
17618
  const candidates = [];
@@ -17419,7 +17625,7 @@ function walkNodeModules(projectRoot, warnings) {
17419
17625
  }
17420
17626
  for (const entry of topLevelEntries) {
17421
17627
  if (entry.startsWith(".")) continue;
17422
- const entryPath = resolve21(nodeModulesDir, entry);
17628
+ const entryPath = resolve22(nodeModulesDir, entry);
17423
17629
  let entryStat;
17424
17630
  try {
17425
17631
  entryStat = lstatSync7(entryPath);
@@ -17441,7 +17647,7 @@ function walkNodeModules(projectRoot, warnings) {
17441
17647
  continue;
17442
17648
  }
17443
17649
  for (const sub of scopedEntries) {
17444
- const subPath = resolve21(entryPath, sub);
17650
+ const subPath = resolve22(entryPath, sub);
17445
17651
  let subStat;
17446
17652
  try {
17447
17653
  subStat = lstatSync7(subPath);
@@ -17460,8 +17666,8 @@ function walkNodeModules(projectRoot, warnings) {
17460
17666
  return candidates;
17461
17667
  }
17462
17668
  function tryReadAdapterPackage(packageDir, warnings) {
17463
- const pkgJsonPath = resolve21(packageDir, "package.json");
17464
- if (!existsSync24(pkgJsonPath)) return null;
17669
+ const pkgJsonPath = resolve22(packageDir, "package.json");
17670
+ if (!existsSync25(pkgJsonPath)) return null;
17465
17671
  let raw;
17466
17672
  try {
17467
17673
  raw = JSON.parse(readFileSync23(pkgJsonPath, "utf-8"));
@@ -17598,8 +17804,8 @@ function discoverAdapters(opts) {
17598
17804
  const localSet = new Set(opts.configLocalPaths);
17599
17805
  for (const localPath of opts.configLocalPaths) {
17600
17806
  if (seenIds.has(localPath)) continue;
17601
- const absPath = isAbsolute2(localPath) ? localPath : resolve21(opts.projectRoot, localPath);
17602
- if (!existsSync24(absPath)) {
17807
+ const absPath = isAbsolute2(localPath) ? localPath : resolve22(opts.projectRoot, localPath);
17808
+ if (!existsSync25(absPath)) {
17603
17809
  warnings.push(
17604
17810
  `local adapter file not found: ${localPath} (resolved to ${absPath}). Remove via: massu adapters remove-local ${localPath}`
17605
17811
  );
@@ -17680,8 +17886,8 @@ __export(adapters_exports, {
17680
17886
  runAdaptersResyncLocalFingerprint: () => runAdaptersResyncLocalFingerprint,
17681
17887
  runAdaptersSearch: () => runAdaptersSearch
17682
17888
  });
17683
- import { existsSync as existsSync25, readFileSync as readFileSync24 } from "node:fs";
17684
- import { resolve as resolve22 } from "node:path";
17889
+ import { existsSync as existsSync26, readFileSync as readFileSync24 } from "node:fs";
17890
+ import { resolve as resolve23 } from "node:path";
17685
17891
  import { parseDocument } from "yaml";
17686
17892
  async function handleAdaptersSubcommand(args2) {
17687
17893
  const sub = args2[0];
@@ -17948,8 +18154,8 @@ function mutateLocalArray(mutator, command) {
17948
18154
  );
17949
18155
  return { exitCode: 2 };
17950
18156
  }
17951
- const yamlPath = resolve22(projectRoot, "massu.config.yaml");
17952
- if (!existsSync25(yamlPath)) {
18157
+ const yamlPath = resolve23(projectRoot, "massu.config.yaml");
18158
+ if (!existsSync26(yamlPath)) {
17953
18159
  process.stderr.write(
17954
18160
  `${command}: massu.config.yaml not found at ${yamlPath}. Run \`massu init\` first.
17955
18161
  `
@@ -17979,7 +18185,7 @@ function mutateLocalArray(mutator, command) {
17979
18185
  if (next === null) {
17980
18186
  return { exitCode: 0 };
17981
18187
  }
17982
- const lockPath = resolve22(projectRoot, ".massu", "adapters-local-mutate.lock");
18188
+ const lockPath = resolve23(projectRoot, ".massu", "adapters-local-mutate.lock");
17983
18189
  return withFileLockSync(lockPath, () => {
17984
18190
  doc.setIn(["adapters", "local"], next);
17985
18191
  const newYaml = doc.toString();
@@ -18048,16 +18254,16 @@ async function runAdaptersInstall(args2) {
18048
18254
  `);
18049
18255
  return { exitCode: 1 };
18050
18256
  }
18051
- const packageDir = resolve22(projectRoot, "node_modules", ...packageName.split("/"));
18052
- if (!existsSync25(packageDir)) {
18257
+ const packageDir = resolve23(projectRoot, "node_modules", ...packageName.split("/"));
18258
+ if (!existsSync26(packageDir)) {
18053
18259
  process.stderr.write(
18054
18260
  `install: ${packageName} is not installed in node_modules. Run \`npm install ${packageName}\` first.
18055
18261
  `
18056
18262
  );
18057
18263
  return { exitCode: 1 };
18058
18264
  }
18059
- const pkgJsonPath = resolve22(packageDir, "package.json");
18060
- if (!existsSync25(pkgJsonPath)) {
18265
+ const pkgJsonPath = resolve23(packageDir, "package.json");
18266
+ if (!existsSync26(pkgJsonPath)) {
18061
18267
  process.stderr.write(`install: ${packageName} has no package.json at ${pkgJsonPath}
18062
18268
  `);
18063
18269
  return { exitCode: 1 };
@@ -18183,8 +18389,8 @@ async function runAdaptersResign(_args) {
18183
18389
  removeInstalledManifestEntry(name);
18184
18390
  continue;
18185
18391
  }
18186
- const packageDir = resolve22(projectRoot, "node_modules", ...name.split("/"));
18187
- if (!existsSync25(packageDir)) {
18392
+ const packageDir = resolve23(projectRoot, "node_modules", ...name.split("/"));
18393
+ if (!existsSync26(packageDir)) {
18188
18394
  removed++;
18189
18395
  warnings.push(`${name}@${entry.version}: not present in node_modules \u2014 REMOVED from sidecar`);
18190
18396
  removeInstalledManifestEntry(name);
@@ -18271,11 +18477,11 @@ var init_adapters2 = __esm({
18271
18477
 
18272
18478
  // src/db.ts
18273
18479
  import Database2 from "better-sqlite3";
18274
- import { dirname as dirname12, join as join12 } from "path";
18275
- import { existsSync as existsSync26, mkdirSync as mkdirSync10, readdirSync as readdirSync15, statSync as statSync11 } from "fs";
18480
+ import { dirname as dirname13, join as join12 } from "path";
18481
+ import { existsSync as existsSync27, mkdirSync as mkdirSync10, readdirSync as readdirSync15, statSync as statSync11 } from "fs";
18276
18482
  function getCodeGraphDb() {
18277
18483
  const dbPath = getResolvedPaths().codegraphDbPath;
18278
- if (!existsSync26(dbPath)) {
18484
+ if (!existsSync27(dbPath)) {
18279
18485
  throw new CodegraphDbNotInitializedError(dbPath);
18280
18486
  }
18281
18487
  const db = new Database2(dbPath, { readonly: true });
@@ -18284,8 +18490,8 @@ function getCodeGraphDb() {
18284
18490
  }
18285
18491
  function getDataDb() {
18286
18492
  const dbPath = getResolvedPaths().dataDbPath;
18287
- const dir = dirname12(dbPath);
18288
- if (!existsSync26(dir)) {
18493
+ const dir = dirname13(dbPath);
18494
+ if (!existsSync27(dir)) {
18289
18495
  mkdirSync10(dir, { recursive: true });
18290
18496
  }
18291
18497
  const db = new Database2(dbPath);
@@ -18592,10 +18798,10 @@ var init_db = __esm({
18592
18798
  });
18593
18799
 
18594
18800
  // src/security-utils.ts
18595
- import { resolve as resolve23, normalize } from "path";
18801
+ import { resolve as resolve24, normalize } from "path";
18596
18802
  function ensureWithinRoot(filePath, projectRoot) {
18597
- const resolvedRoot = resolve23(projectRoot);
18598
- const resolvedPath = resolve23(resolvedRoot, filePath);
18803
+ const resolvedRoot = resolve24(projectRoot);
18804
+ const resolvedPath = resolve24(resolvedRoot, filePath);
18599
18805
  const normalizedPath = normalize(resolvedPath);
18600
18806
  const normalizedRoot = normalize(resolvedRoot);
18601
18807
  if (!normalizedPath.startsWith(normalizedRoot + "/") && normalizedPath !== normalizedRoot) {
@@ -18668,8 +18874,8 @@ var init_rules = __esm({
18668
18874
  });
18669
18875
 
18670
18876
  // src/import-resolver.ts
18671
- import { readFileSync as readFileSync25, existsSync as existsSync27, statSync as statSync12 } from "fs";
18672
- import { resolve as resolve24, dirname as dirname13, join as join13 } from "path";
18877
+ import { readFileSync as readFileSync25, existsSync as existsSync28, statSync as statSync12 } from "fs";
18878
+ import { resolve as resolve25, dirname as dirname14, join as join13 } from "path";
18673
18879
  function parseImports(source) {
18674
18880
  const imports = [];
18675
18881
  const lines = source.split("\n");
@@ -18725,23 +18931,23 @@ function resolveImportPath(specifier, fromFile) {
18725
18931
  let basePath;
18726
18932
  if (specifier.startsWith("@/")) {
18727
18933
  const paths = getResolvedPaths();
18728
- basePath = resolve24(paths.pathAlias["@"] ?? paths.srcDir, specifier.slice(2));
18934
+ basePath = resolve25(paths.pathAlias["@"] ?? paths.srcDir, specifier.slice(2));
18729
18935
  } else {
18730
- basePath = resolve24(dirname13(fromFile), specifier);
18936
+ basePath = resolve25(dirname14(fromFile), specifier);
18731
18937
  }
18732
- if (existsSync27(basePath) && !isDirectory(basePath)) {
18938
+ if (existsSync28(basePath) && !isDirectory(basePath)) {
18733
18939
  return toRelative(basePath);
18734
18940
  }
18735
18941
  const resolvedPaths = getResolvedPaths();
18736
18942
  for (const ext of resolvedPaths.extensions) {
18737
18943
  const withExt = basePath + ext;
18738
- if (existsSync27(withExt)) {
18944
+ if (existsSync28(withExt)) {
18739
18945
  return toRelative(withExt);
18740
18946
  }
18741
18947
  }
18742
18948
  for (const indexFile of resolvedPaths.indexFiles) {
18743
18949
  const indexPath = join13(basePath, indexFile);
18744
- if (existsSync27(indexPath)) {
18950
+ if (existsSync28(indexPath)) {
18745
18951
  return toRelative(indexPath);
18746
18952
  }
18747
18953
  }
@@ -18777,8 +18983,8 @@ function buildImportIndex(dataDb, codegraphDb) {
18777
18983
  const batchSize = 500;
18778
18984
  let batch = [];
18779
18985
  for (const file of files) {
18780
- const absPath = ensureWithinRoot(resolve24(projectRoot, file.path), projectRoot);
18781
- if (!existsSync27(absPath)) continue;
18986
+ const absPath = ensureWithinRoot(resolve25(projectRoot, file.path), projectRoot);
18987
+ if (!existsSync28(absPath)) continue;
18782
18988
  let source;
18783
18989
  try {
18784
18990
  source = readFileSync25(absPath, "utf-8");
@@ -18817,12 +19023,12 @@ var init_import_resolver = __esm({
18817
19023
  });
18818
19024
 
18819
19025
  // src/trpc-index.ts
18820
- import { readFileSync as readFileSync26, existsSync as existsSync28, readdirSync as readdirSync16 } from "fs";
18821
- import { resolve as resolve25, join as join14 } from "path";
19026
+ import { readFileSync as readFileSync26, existsSync as existsSync29, readdirSync as readdirSync16 } from "fs";
19027
+ import { resolve as resolve26, join as join14 } from "path";
18822
19028
  function parseRootRouter() {
18823
19029
  const paths = getResolvedPaths();
18824
19030
  const rootPath = paths.rootRouterPath;
18825
- if (!existsSync28(rootPath)) {
19031
+ if (!existsSync29(rootPath)) {
18826
19032
  throw new Error(`Root router not found at ${rootPath}`);
18827
19033
  }
18828
19034
  const source = readFileSync26(rootPath, "utf-8");
@@ -18833,16 +19039,16 @@ function parseRootRouter() {
18833
19039
  while ((match = importRegex.exec(source)) !== null) {
18834
19040
  const variable = match[1];
18835
19041
  let filePath = match[2];
18836
- const fullPath = resolve25(paths.routersDir, filePath);
19042
+ const fullPath = resolve26(paths.routersDir, filePath);
18837
19043
  for (const ext of [".ts", ".tsx", ""]) {
18838
19044
  const candidate = fullPath + ext;
18839
19045
  const routersRelPath = getConfig().paths.routers ?? "src/server/api/routers";
18840
- if (existsSync28(candidate)) {
19046
+ if (existsSync29(candidate)) {
18841
19047
  filePath = routersRelPath + "/" + filePath + ext;
18842
19048
  break;
18843
19049
  }
18844
19050
  const indexCandidate = join14(fullPath, "index.ts");
18845
- if (existsSync28(indexCandidate)) {
19051
+ if (existsSync29(indexCandidate)) {
18846
19052
  filePath = routersRelPath + "/" + filePath + "/index.ts";
18847
19053
  break;
18848
19054
  }
@@ -18861,8 +19067,8 @@ function parseRootRouter() {
18861
19067
  return mappings;
18862
19068
  }
18863
19069
  function extractProcedures(routerFilePath) {
18864
- const absPath = resolve25(getProjectRoot(), routerFilePath);
18865
- if (!existsSync28(absPath)) return [];
19070
+ const absPath = resolve26(getProjectRoot(), routerFilePath);
19071
+ if (!existsSync29(absPath)) return [];
18866
19072
  const source = readFileSync26(absPath, "utf-8");
18867
19073
  const procedures = [];
18868
19074
  const seen = /* @__PURE__ */ new Set();
@@ -18886,13 +19092,13 @@ function findUICallSites(routerKey, procedureName) {
18886
19092
  const root = getProjectRoot();
18887
19093
  const src = config.paths.source;
18888
19094
  const searchDirs = [
18889
- resolve25(root, config.paths.pages ?? src + "/app"),
18890
- resolve25(root, config.paths.components ?? src + "/components"),
18891
- resolve25(root, config.paths.hooks ?? src + "/hooks")
19095
+ resolve26(root, config.paths.pages ?? src + "/app"),
19096
+ resolve26(root, config.paths.components ?? src + "/components"),
19097
+ resolve26(root, config.paths.hooks ?? src + "/hooks")
18892
19098
  ];
18893
19099
  const searchPattern = `api.${routerKey}.${procedureName}`;
18894
19100
  for (const dir of searchDirs) {
18895
- if (!existsSync28(dir)) continue;
19101
+ if (!existsSync29(dir)) continue;
18896
19102
  searchDirectory(dir, searchPattern, callSites);
18897
19103
  }
18898
19104
  return callSites;
@@ -18969,8 +19175,8 @@ var init_trpc_index = __esm({
18969
19175
  });
18970
19176
 
18971
19177
  // src/page-deps.ts
18972
- import { readFileSync as readFileSync27, existsSync as existsSync29 } from "fs";
18973
- import { resolve as resolve26 } from "path";
19178
+ import { readFileSync as readFileSync27, existsSync as existsSync30 } from "fs";
19179
+ import { resolve as resolve27 } from "path";
18974
19180
  function deriveRoute(pageFile) {
18975
19181
  let route = pageFile.replace(/^src\/app/, "").replace(/\/page\.tsx?$/, "").replace(/\/page\.jsx?$/, "");
18976
19182
  return route || "/";
@@ -19008,8 +19214,8 @@ function findRouterCalls(files) {
19008
19214
  const routers = /* @__PURE__ */ new Set();
19009
19215
  const projectRoot = getProjectRoot();
19010
19216
  for (const file of files) {
19011
- const absPath = ensureWithinRoot(resolve26(projectRoot, file), projectRoot);
19012
- if (!existsSync29(absPath)) continue;
19217
+ const absPath = ensureWithinRoot(resolve27(projectRoot, file), projectRoot);
19218
+ if (!existsSync30(absPath)) continue;
19013
19219
  try {
19014
19220
  const source = readFileSync27(absPath, "utf-8");
19015
19221
  const apiCallRegex = /api\.(\w+)\.\w+/g;
@@ -19029,8 +19235,8 @@ function findTablesFromRouters(routerNames, dataDb) {
19029
19235
  "SELECT DISTINCT router_file FROM massu_trpc_procedures WHERE router_name = ?"
19030
19236
  ).all(routerName);
19031
19237
  for (const proc of procs) {
19032
- const absPath = ensureWithinRoot(resolve26(getProjectRoot(), proc.router_file), getProjectRoot());
19033
- if (!existsSync29(absPath)) continue;
19238
+ const absPath = ensureWithinRoot(resolve27(getProjectRoot(), proc.router_file), getProjectRoot());
19239
+ if (!existsSync30(absPath)) continue;
19034
19240
  try {
19035
19241
  const source = readFileSync27(absPath, "utf-8");
19036
19242
  const dbPattern = getConfig().dbAccessPattern ?? "ctx.db.{table}";
@@ -19301,11 +19507,11 @@ var init_domains = __esm({
19301
19507
  });
19302
19508
 
19303
19509
  // src/schema-mapper.ts
19304
- import { readFileSync as readFileSync28, existsSync as existsSync30, readdirSync as readdirSync17 } from "fs";
19510
+ import { readFileSync as readFileSync28, existsSync as existsSync31, readdirSync as readdirSync17 } from "fs";
19305
19511
  import { join as join15 } from "path";
19306
19512
  function parsePrismaSchema() {
19307
19513
  const schemaPath = getResolvedPaths().prismaSchemaPath;
19308
- if (!existsSync30(schemaPath)) {
19514
+ if (!existsSync31(schemaPath)) {
19309
19515
  throw new Error(`Prisma schema not found at ${schemaPath}`);
19310
19516
  }
19311
19517
  const source = readFileSync28(schemaPath, "utf-8");
@@ -19366,7 +19572,7 @@ function toSnakeCase(str) {
19366
19572
  function findColumnUsageInRouters(tableName) {
19367
19573
  const usage = /* @__PURE__ */ new Map();
19368
19574
  const routersDir = getResolvedPaths().routersDir;
19369
- if (!existsSync30(routersDir)) return usage;
19575
+ if (!existsSync31(routersDir)) return usage;
19370
19576
  scanDirectory(routersDir, tableName, usage);
19371
19577
  return usage;
19372
19578
  }
@@ -19428,7 +19634,7 @@ function detectMismatches(models) {
19428
19634
  }
19429
19635
  function findFilesUsingColumn(dir, column, tableName) {
19430
19636
  const result = [];
19431
- if (!existsSync30(dir)) return result;
19637
+ if (!existsSync31(dir)) return result;
19432
19638
  const entries = readdirSync17(dir, { withFileTypes: true });
19433
19639
  for (const entry of entries) {
19434
19640
  const fullPath = join15(dir, entry.name);
@@ -19581,14 +19787,14 @@ var init_import_parser = __esm({
19581
19787
  });
19582
19788
 
19583
19789
  // src/python/import-resolver.ts
19584
- import { readFileSync as readFileSync29, existsSync as existsSync31, readdirSync as readdirSync18 } from "fs";
19585
- import { resolve as resolve28, join as join16, relative as relative6, dirname as dirname14 } from "path";
19790
+ import { readFileSync as readFileSync29, existsSync as existsSync32, readdirSync as readdirSync18 } from "fs";
19791
+ import { resolve as resolve29, join as join16, relative as relative6, dirname as dirname15 } from "path";
19586
19792
  function resolvePythonModulePath(module, fromFile, pythonRoot, level) {
19587
19793
  const projectRoot = getProjectRoot();
19588
19794
  if (level > 0) {
19589
- let baseDir = dirname14(resolve28(projectRoot, fromFile));
19795
+ let baseDir = dirname15(resolve29(projectRoot, fromFile));
19590
19796
  for (let i = 1; i < level; i++) {
19591
- baseDir = dirname14(baseDir);
19797
+ baseDir = dirname15(baseDir);
19592
19798
  }
19593
19799
  const modulePart = module.replace(/^\.+/, "");
19594
19800
  if (modulePart) {
@@ -19598,17 +19804,17 @@ function resolvePythonModulePath(module, fromFile, pythonRoot, level) {
19598
19804
  return tryResolvePythonPath(baseDir, projectRoot);
19599
19805
  }
19600
19806
  const parts = module.split(".");
19601
- const candidate = join16(resolve28(projectRoot, pythonRoot), ...parts);
19807
+ const candidate = join16(resolve29(projectRoot, pythonRoot), ...parts);
19602
19808
  return tryResolvePythonPath(candidate, projectRoot);
19603
19809
  }
19604
19810
  function tryResolvePythonPath(basePath, projectRoot) {
19605
- if (existsSync31(basePath + ".py")) {
19811
+ if (existsSync32(basePath + ".py")) {
19606
19812
  return relative6(projectRoot, basePath + ".py");
19607
19813
  }
19608
- if (existsSync31(join16(basePath, "__init__.py"))) {
19814
+ if (existsSync32(join16(basePath, "__init__.py"))) {
19609
19815
  return relative6(projectRoot, join16(basePath, "__init__.py"));
19610
19816
  }
19611
- if (basePath.endsWith(".py") && existsSync31(basePath)) {
19817
+ if (basePath.endsWith(".py") && existsSync32(basePath)) {
19612
19818
  return relative6(projectRoot, basePath);
19613
19819
  }
19614
19820
  return null;
@@ -19631,7 +19837,7 @@ function walkPythonFiles(dir, excludeDirs) {
19631
19837
  }
19632
19838
  function buildPythonImportIndex(dataDb, pythonRoot, excludeDirs = ["__pycache__", ".venv", "venv", ".mypy_cache", ".pytest_cache"]) {
19633
19839
  const projectRoot = getProjectRoot();
19634
- const absRoot = resolve28(projectRoot, pythonRoot);
19840
+ const absRoot = resolve29(projectRoot, pythonRoot);
19635
19841
  dataDb.exec("DELETE FROM massu_py_imports");
19636
19842
  const insertStmt = dataDb.prepare(
19637
19843
  "INSERT INTO massu_py_imports (source_file, target_file, import_type, imported_names, line) VALUES (?, ?, ?, ?, ?)"
@@ -20956,8 +21162,8 @@ var init_memory_tools = __esm({
20956
21162
  });
20957
21163
 
20958
21164
  // src/docs-tools.ts
20959
- import { readFileSync as readFileSync34, existsSync as existsSync32 } from "fs";
20960
- import { resolve as resolve29, basename as basename6 } from "path";
21165
+ import { readFileSync as readFileSync34, existsSync as existsSync33 } from "fs";
21166
+ import { resolve as resolve30, basename as basename6 } from "path";
20961
21167
  function p3(baseName) {
20962
21168
  return `${getConfig().toolPrefix}_${baseName}`;
20963
21169
  }
@@ -21012,7 +21218,7 @@ function handleDocsToolCall(name, args2) {
21012
21218
  }
21013
21219
  function loadDocsMap() {
21014
21220
  const mapPath = getResolvedPaths().docsMapPath;
21015
- if (!existsSync32(mapPath)) {
21221
+ if (!existsSync33(mapPath)) {
21016
21222
  throw new Error(`docs-map.json not found at ${mapPath}`);
21017
21223
  }
21018
21224
  return JSON.parse(readFileSync34(mapPath, "utf-8"));
@@ -21085,10 +21291,10 @@ function extractFrontmatter(content) {
21085
21291
  }
21086
21292
  function extractProcedureNames(routerPath) {
21087
21293
  const root = getProjectRoot();
21088
- const absPath = ensureWithinRoot(resolve29(getResolvedPaths().srcDir, "..", routerPath), root);
21089
- if (!existsSync32(absPath)) {
21090
- const altPath = ensureWithinRoot(resolve29(getResolvedPaths().srcDir, "../server/api/routers", basename6(routerPath)), root);
21091
- if (!existsSync32(altPath)) return [];
21294
+ const absPath = ensureWithinRoot(resolve30(getResolvedPaths().srcDir, "..", routerPath), root);
21295
+ if (!existsSync33(absPath)) {
21296
+ const altPath = ensureWithinRoot(resolve30(getResolvedPaths().srcDir, "../server/api/routers", basename6(routerPath)), root);
21297
+ if (!existsSync33(altPath)) return [];
21092
21298
  return extractProcedureNamesFromContent(readFileSync34(altPath, "utf-8"));
21093
21299
  }
21094
21300
  return extractProcedureNamesFromContent(readFileSync34(absPath, "utf-8"));
@@ -21131,8 +21337,8 @@ function handleDocsAudit(args2) {
21131
21337
  for (const [mappingId, triggeringFiles] of affectedMappings) {
21132
21338
  const mapping = docsMap.mappings.find((m3) => m3.id === mappingId);
21133
21339
  if (!mapping) continue;
21134
- const helpPagePath = ensureWithinRoot(resolve29(getResolvedPaths().helpSitePath, mapping.helpPage), getProjectRoot());
21135
- if (!existsSync32(helpPagePath)) {
21340
+ const helpPagePath = ensureWithinRoot(resolve30(getResolvedPaths().helpSitePath, mapping.helpPage), getProjectRoot());
21341
+ if (!existsSync33(helpPagePath)) {
21136
21342
  results.push({
21137
21343
  helpPage: mapping.helpPage,
21138
21344
  mappingId,
@@ -21184,8 +21390,8 @@ function handleDocsAudit(args2) {
21184
21390
  });
21185
21391
  for (const [guideName, parentId] of Object.entries(docsMap.userGuideInheritance.examples)) {
21186
21392
  if (parentId === mappingId) {
21187
- const guidePath = ensureWithinRoot(resolve29(getResolvedPaths().helpSitePath, `pages/user-guides/${guideName}/index.mdx`), getProjectRoot());
21188
- if (existsSync32(guidePath)) {
21393
+ const guidePath = ensureWithinRoot(resolve30(getResolvedPaths().helpSitePath, `pages/user-guides/${guideName}/index.mdx`), getProjectRoot());
21394
+ if (existsSync33(guidePath)) {
21189
21395
  const guideContent = readFileSync34(guidePath, "utf-8");
21190
21396
  const guideFrontmatter = extractFrontmatter(guideContent);
21191
21397
  if (!guideFrontmatter?.lastVerified || status === "STALE") {
@@ -21219,8 +21425,8 @@ function handleDocsCoverage(args2) {
21219
21425
  const gaps = [];
21220
21426
  const mappings = filterDomain ? docsMap.mappings.filter((m3) => m3.id === filterDomain) : docsMap.mappings;
21221
21427
  for (const mapping of mappings) {
21222
- const helpPagePath = ensureWithinRoot(resolve29(getResolvedPaths().helpSitePath, mapping.helpPage), getProjectRoot());
21223
- const exists = existsSync32(helpPagePath);
21428
+ const helpPagePath = ensureWithinRoot(resolve30(getResolvedPaths().helpSitePath, mapping.helpPage), getProjectRoot());
21429
+ const exists = existsSync33(helpPagePath);
21224
21430
  let hasContent = false;
21225
21431
  let lineCount = 0;
21226
21432
  let lastVerified = null;
@@ -21567,8 +21773,8 @@ var init_observability_tools = __esm({
21567
21773
  });
21568
21774
 
21569
21775
  // src/sentinel-db.ts
21570
- import { existsSync as existsSync33 } from "fs";
21571
- import { resolve as resolve30 } from "path";
21776
+ import { existsSync as existsSync34 } from "fs";
21777
+ import { resolve as resolve31 } from "path";
21572
21778
  function parsePortalScope(raw) {
21573
21779
  if (!raw) return [];
21574
21780
  try {
@@ -21804,23 +22010,23 @@ function validateFeatures(db, domainFilter) {
21804
22010
  const missingProcedures = [];
21805
22011
  const missingPages = [];
21806
22012
  for (const comp of components) {
21807
- const absPath = resolve30(PROJECT_ROOT, comp.component_file);
21808
- if (!existsSync33(absPath)) {
22013
+ const absPath = resolve31(PROJECT_ROOT, comp.component_file);
22014
+ if (!existsSync34(absPath)) {
21809
22015
  missingComponents.push(comp.component_file);
21810
22016
  }
21811
22017
  }
21812
22018
  for (const proc of procedures) {
21813
- const routerPath = resolve30(PROJECT_ROOT, `src/server/api/routers/${proc.router_name}.ts`);
21814
- if (!existsSync33(routerPath)) {
22019
+ const routerPath = resolve31(PROJECT_ROOT, `src/server/api/routers/${proc.router_name}.ts`);
22020
+ if (!existsSync34(routerPath)) {
21815
22021
  missingProcedures.push({ router: proc.router_name, procedure: proc.procedure_name });
21816
22022
  }
21817
22023
  }
21818
22024
  for (const page of pages) {
21819
22025
  const routeToPath = page.page_route.replace(/^\/(portal-[^/]+\/)?/, "src/app/").replace(/\/$/, "") + "/page.tsx";
21820
- const absPath = resolve30(PROJECT_ROOT, routeToPath);
21821
- if (page.page_route.startsWith("/") && !existsSync33(absPath)) {
21822
- const altPath = resolve30(PROJECT_ROOT, `src/app${page.page_route}/page.tsx`);
21823
- if (!existsSync33(altPath)) {
22026
+ const absPath = resolve31(PROJECT_ROOT, routeToPath);
22027
+ if (page.page_route.startsWith("/") && !existsSync34(absPath)) {
22028
+ const altPath = resolve31(PROJECT_ROOT, `src/app${page.page_route}/page.tsx`);
22029
+ if (!existsSync34(altPath)) {
21824
22030
  missingPages.push(page.page_route);
21825
22031
  }
21826
22032
  }
@@ -22344,8 +22550,8 @@ var init_sentinel_tools = __esm({
22344
22550
  });
22345
22551
 
22346
22552
  // src/sentinel-scanner.ts
22347
- import { readFileSync as readFileSync35, existsSync as existsSync34, readdirSync as readdirSync23, statSync as statSync13 } from "fs";
22348
- import { resolve as resolve31, join as join21, basename as basename7, dirname as dirname15, relative as relative11 } from "path";
22553
+ import { readFileSync as readFileSync35, existsSync as existsSync35, readdirSync as readdirSync23, statSync as statSync13 } from "fs";
22554
+ import { resolve as resolve32, join as join21, basename as basename7, dirname as dirname16, relative as relative11 } from "path";
22349
22555
  function inferDomain(filePath) {
22350
22556
  const domains = getConfig().domains;
22351
22557
  const path = filePath.toLowerCase();
@@ -22474,8 +22680,8 @@ function scanComponentExports(dataDb) {
22474
22680
  const projectRoot = getProjectRoot();
22475
22681
  const componentsBase = config.paths.components ?? config.paths.source + "/components";
22476
22682
  const componentDirs = [];
22477
- const basePath = resolve31(projectRoot, componentsBase);
22478
- if (existsSync34(basePath)) {
22683
+ const basePath = resolve32(projectRoot, componentsBase);
22684
+ if (existsSync35(basePath)) {
22479
22685
  try {
22480
22686
  const entries = readdirSync23(basePath, { withFileTypes: true });
22481
22687
  for (const entry of entries) {
@@ -22487,8 +22693,8 @@ function scanComponentExports(dataDb) {
22487
22693
  }
22488
22694
  }
22489
22695
  for (const dir of componentDirs) {
22490
- const absDir = resolve31(projectRoot, dir);
22491
- if (!existsSync34(absDir)) continue;
22696
+ const absDir = resolve32(projectRoot, dir);
22697
+ if (!existsSync35(absDir)) continue;
22492
22698
  const files = walkDir2(absDir).filter((f2) => f2.endsWith(".tsx") || f2.endsWith(".ts"));
22493
22699
  for (const file of files) {
22494
22700
  const relPath = relative11(projectRoot, file);
@@ -22518,7 +22724,7 @@ function scanComponentExports(dataDb) {
22518
22724
  if (hasHandlers && exportMatch) {
22519
22725
  const componentName = exportMatch[1];
22520
22726
  const domain = inferDomain(relPath);
22521
- const subdomain = basename7(dirname15(relPath));
22727
+ const subdomain = basename7(dirname16(relPath));
22522
22728
  const featureKey = `component.${subdomain}.${componentName.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "")}`;
22523
22729
  if (!annotations.some((a2) => a2.featureKey === featureKey)) {
22524
22730
  features.push({
@@ -23531,7 +23737,7 @@ var init_audit_trail = __esm({
23531
23737
  });
23532
23738
 
23533
23739
  // src/validation-engine.ts
23534
- import { existsSync as existsSync35, readFileSync as readFileSync36 } from "fs";
23740
+ import { existsSync as existsSync36, readFileSync as readFileSync36 } from "fs";
23535
23741
  function p10(baseName) {
23536
23742
  return `${getConfig().toolPrefix}_${baseName}`;
23537
23743
  }
@@ -23562,7 +23768,7 @@ function validateFile(filePath, projectRoot) {
23562
23768
  });
23563
23769
  return checks;
23564
23770
  }
23565
- if (!existsSync35(absPath)) {
23771
+ if (!existsSync36(absPath)) {
23566
23772
  checks.push({
23567
23773
  name: "file_exists",
23568
23774
  severity: "error",
@@ -24016,7 +24222,7 @@ var init_adr_generator = __esm({
24016
24222
  });
24017
24223
 
24018
24224
  // src/security-scorer.ts
24019
- import { existsSync as existsSync36, readFileSync as readFileSync37 } from "fs";
24225
+ import { existsSync as existsSync37, readFileSync as readFileSync37 } from "fs";
24020
24226
  function p12(baseName) {
24021
24227
  return `${getConfig().toolPrefix}_${baseName}`;
24022
24228
  }
@@ -24040,7 +24246,7 @@ function scoreFileSecurity(filePath, projectRoot) {
24040
24246
  }]
24041
24247
  };
24042
24248
  }
24043
- if (!existsSync36(absPath)) {
24249
+ if (!existsSync37(absPath)) {
24044
24250
  return { riskScore: 0, findings: [] };
24045
24251
  }
24046
24252
  let source;
@@ -24334,8 +24540,8 @@ var init_security_scorer = __esm({
24334
24540
  });
24335
24541
 
24336
24542
  // src/dependency-scorer.ts
24337
- import { existsSync as existsSync37, readFileSync as readFileSync38 } from "fs";
24338
- import { resolve as resolve32 } from "path";
24543
+ import { existsSync as existsSync38, readFileSync as readFileSync38 } from "fs";
24544
+ import { resolve as resolve33 } from "path";
24339
24545
  function p13(baseName) {
24340
24546
  return `${getConfig().toolPrefix}_${baseName}`;
24341
24547
  }
@@ -24367,8 +24573,8 @@ function calculateDepRisk(factors) {
24367
24573
  return Math.min(100, risk);
24368
24574
  }
24369
24575
  function getInstalledPackages(projectRoot) {
24370
- const pkgPath = resolve32(projectRoot, "package.json");
24371
- if (!existsSync37(pkgPath)) return /* @__PURE__ */ new Map();
24576
+ const pkgPath = resolve33(projectRoot, "package.json");
24577
+ if (!existsSync38(pkgPath)) return /* @__PURE__ */ new Map();
24372
24578
  try {
24373
24579
  const pkg = JSON.parse(readFileSync38(pkgPath, "utf-8"));
24374
24580
  const packages = /* @__PURE__ */ new Map();
@@ -24973,8 +25179,8 @@ var init_regression_detector = __esm({
24973
25179
 
24974
25180
  // src/knowledge-indexer.ts
24975
25181
  import { createHash as createHash9 } from "crypto";
24976
- import { readFileSync as readFileSync39, readdirSync as readdirSync24, statSync as statSync14, existsSync as existsSync38 } from "fs";
24977
- import { resolve as resolve33, relative as relative12, basename as basename8, extname as extname2 } from "path";
25182
+ import { readFileSync as readFileSync39, readdirSync as readdirSync24, statSync as statSync14, existsSync as existsSync39 } from "fs";
25183
+ import { resolve as resolve34, relative as relative12, basename as basename8, extname as extname2 } from "path";
24978
25184
  function getKnowledgePaths() {
24979
25185
  const resolved = getResolvedPaths();
24980
25186
  const config = getConfig();
@@ -25002,7 +25208,7 @@ function discoverMarkdownFiles(baseDir) {
25002
25208
  try {
25003
25209
  const entries = readdirSync24(dir, { withFileTypes: true });
25004
25210
  for (const entry of entries) {
25005
- const fullPath = resolve33(dir, entry.name);
25211
+ const fullPath = resolve34(dir, entry.name);
25006
25212
  if (entry.isDirectory()) {
25007
25213
  if (entry.name === "archive" && dir.includes("session-state")) continue;
25008
25214
  if (entry.name === "archive" && dir.includes("status")) continue;
@@ -25280,11 +25486,11 @@ function indexAllKnowledge(db) {
25280
25486
  files.push(...memFiles);
25281
25487
  } catch {
25282
25488
  }
25283
- if (existsSync38(paths.plansDir)) {
25489
+ if (existsSync39(paths.plansDir)) {
25284
25490
  const planFiles = discoverMarkdownFiles(paths.plansDir);
25285
25491
  files.push(...planFiles);
25286
25492
  }
25287
- if (existsSync38(paths.docsDir)) {
25493
+ if (existsSync39(paths.docsDir)) {
25288
25494
  const excludePatterns = getConfig().conventions?.excludePatterns ?? ["/ARCHIVE/", "/SESSION-HISTORY/"];
25289
25495
  const docsFiles = discoverMarkdownFiles(paths.docsDir).filter((f2) => !f2.includes("/plans/") && !excludePatterns.some((p19) => f2.includes(p19)));
25290
25496
  files.push(...docsFiles);
@@ -25327,7 +25533,7 @@ function indexAllKnowledge(db) {
25327
25533
  } catch {
25328
25534
  }
25329
25535
  for (const filePath of files) {
25330
- if (!existsSync38(filePath)) continue;
25536
+ if (!existsSync39(filePath)) continue;
25331
25537
  const content = readFileSync39(filePath, "utf-8");
25332
25538
  const hash = hashContent2(content);
25333
25539
  const relPath = filePath.startsWith(paths.claudeDir) ? relative12(paths.claudeDir, filePath) : filePath.startsWith(paths.plansDir) ? "plans/" + relative12(paths.plansDir, filePath) : filePath.startsWith(paths.docsDir) ? "docs/" + relative12(paths.docsDir, filePath) : filePath.startsWith(paths.memoryDir) ? `memory/${relative12(paths.memoryDir, filePath)}` : basename8(filePath);
@@ -25448,10 +25654,10 @@ function isKnowledgeStale(db) {
25448
25654
  files.push(...discoverMarkdownFiles(paths.memoryDir));
25449
25655
  } catch {
25450
25656
  }
25451
- if (existsSync38(paths.plansDir)) {
25657
+ if (existsSync39(paths.plansDir)) {
25452
25658
  files.push(...discoverMarkdownFiles(paths.plansDir));
25453
25659
  }
25454
- if (existsSync38(paths.docsDir)) {
25660
+ if (existsSync39(paths.docsDir)) {
25455
25661
  const excludePatterns = getConfig().conventions?.excludePatterns ?? ["/ARCHIVE/", "/SESSION-HISTORY/"];
25456
25662
  const docsFiles = discoverMarkdownFiles(paths.docsDir).filter((f2) => !f2.includes("/plans/") && !excludePatterns.some((p19) => f2.includes(p19)));
25457
25663
  files.push(...docsFiles);
@@ -25481,7 +25687,7 @@ var init_knowledge_indexer = __esm({
25481
25687
 
25482
25688
  // src/knowledge-tools.ts
25483
25689
  import { readFileSync as readFileSync40, writeFileSync as writeFileSync5, appendFileSync as appendFileSync2, readdirSync as readdirSync25 } from "fs";
25484
- import { resolve as resolve34, basename as basename9 } from "path";
25690
+ import { resolve as resolve35, basename as basename9 } from "path";
25485
25691
  function p16(baseName) {
25486
25692
  return `${getConfig().toolPrefix}_${baseName}`;
25487
25693
  }
@@ -26218,7 +26424,7 @@ function handleCorrect(db, args2) {
26218
26424
  if (!wrong || !correction || !rule) {
26219
26425
  return text15("Error: wrong, correction, and rule are all required.");
26220
26426
  }
26221
- const correctionsPath = resolve34(getResolvedPaths().memoryDir, "corrections.md");
26427
+ const correctionsPath = resolve35(getResolvedPaths().memoryDir, "corrections.md");
26222
26428
  const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
26223
26429
  const title = rule.slice(0, 60);
26224
26430
  const entry = `
@@ -26569,12 +26775,12 @@ var init_knowledge_tools = __esm({
26569
26775
 
26570
26776
  // src/knowledge-db.ts
26571
26777
  import Database3 from "better-sqlite3";
26572
- import { dirname as dirname16 } from "path";
26573
- import { existsSync as existsSync40, mkdirSync as mkdirSync11 } from "fs";
26778
+ import { dirname as dirname17 } from "path";
26779
+ import { existsSync as existsSync41, mkdirSync as mkdirSync11 } from "fs";
26574
26780
  function getKnowledgeDb() {
26575
26781
  const dbPath = getResolvedPaths().knowledgeDbPath;
26576
- const dir = dirname16(dbPath);
26577
- if (!existsSync40(dir)) {
26782
+ const dir = dirname17(dbPath);
26783
+ if (!existsSync41(dir)) {
26578
26784
  mkdirSync11(dir, { recursive: true });
26579
26785
  }
26580
26786
  const db = new Database3(dbPath);
@@ -27308,8 +27514,8 @@ var init_python_tools = __esm({
27308
27514
  });
27309
27515
 
27310
27516
  // src/tools.ts
27311
- import { readFileSync as readFileSync41, existsSync as existsSync41 } from "fs";
27312
- import { resolve as resolve35, basename as basename10 } from "path";
27517
+ import { readFileSync as readFileSync41, existsSync as existsSync42 } from "fs";
27518
+ import { resolve as resolve36, basename as basename10 } from "path";
27313
27519
  function prefix2() {
27314
27520
  return getConfig().toolPrefix;
27315
27521
  }
@@ -27344,7 +27550,7 @@ function ensureIndexes(dataDb, codegraphDb, force = false) {
27344
27550
  if (config.python?.root) {
27345
27551
  const pythonRoot = config.python.root;
27346
27552
  const excludeDirs = config.python.exclude_dirs || ["__pycache__", ".venv", "venv", ".mypy_cache", ".pytest_cache"];
27347
- if (force || isPythonDataStale(dataDb, resolve35(getProjectRoot(), pythonRoot))) {
27553
+ if (force || isPythonDataStale(dataDb, resolve36(getProjectRoot(), pythonRoot))) {
27348
27554
  const pyImports = buildPythonImportIndex(dataDb, pythonRoot, excludeDirs);
27349
27555
  results.push(`Python imports: ${pyImports}`);
27350
27556
  const pyRoutes = buildPythonRouteIndex(dataDb, pythonRoot, excludeDirs);
@@ -27779,8 +27985,8 @@ function handleContext(file, dataDb, codegraphDb) {
27779
27985
  try {
27780
27986
  const resolvedPaths = getResolvedPaths();
27781
27987
  const root = getProjectRoot();
27782
- const absFilePath = ensureWithinRoot(resolve35(resolvedPaths.srcDir, "..", file), root);
27783
- if (existsSync41(absFilePath)) {
27988
+ const absFilePath = ensureWithinRoot(resolve36(resolvedPaths.srcDir, "..", file), root);
27989
+ if (existsSync42(absFilePath)) {
27784
27990
  const fileContent = readFileSync41(absFilePath, "utf-8").slice(0, 3e3);
27785
27991
  const keywords = [];
27786
27992
  if (fileContent.includes("ctx.db")) keywords.push("database", "schema");
@@ -28205,8 +28411,8 @@ function handleSchema(args2) {
28205
28411
  lines.push("Checking all column references against Prisma schema...");
28206
28412
  lines.push("");
28207
28413
  const projectRoot = getProjectRoot();
28208
- const absPath = ensureWithinRoot(resolve35(projectRoot, file), projectRoot);
28209
- if (!existsSync41(absPath)) {
28414
+ const absPath = ensureWithinRoot(resolve36(projectRoot, file), projectRoot);
28415
+ if (!existsSync42(absPath)) {
28210
28416
  return text17(`File not found: ${file}`);
28211
28417
  }
28212
28418
  const source = readFileSync41(absPath, "utf-8");
@@ -28579,8 +28785,8 @@ var init_server_dispatch = __esm({
28579
28785
  // src/server.ts
28580
28786
  var server_exports = {};
28581
28787
  import { readFileSync as readFileSync42 } from "fs";
28582
- import { resolve as resolve36, dirname as dirname17 } from "path";
28583
- import { fileURLToPath as fileURLToPath4 } from "url";
28788
+ import { resolve as resolve37, dirname as dirname18 } from "path";
28789
+ import { fileURLToPath as fileURLToPath5 } from "url";
28584
28790
  function pruneMemoryOnStartup() {
28585
28791
  try {
28586
28792
  const memDb = getMemoryDb();
@@ -28604,17 +28810,17 @@ function pruneMemoryOnStartup() {
28604
28810
  );
28605
28811
  }
28606
28812
  }
28607
- var __dirname4, PKG_VERSION, dispatcher, buffer;
28813
+ var __dirname5, PKG_VERSION, dispatcher, buffer;
28608
28814
  var init_server = __esm({
28609
28815
  "src/server.ts"() {
28610
28816
  "use strict";
28611
28817
  init_memory_db();
28612
28818
  init_license();
28613
28819
  init_server_dispatch();
28614
- __dirname4 = dirname17(fileURLToPath4(import.meta.url));
28820
+ __dirname5 = dirname18(fileURLToPath5(import.meta.url));
28615
28821
  PKG_VERSION = (() => {
28616
28822
  try {
28617
- const pkg = JSON.parse(readFileSync42(resolve36(__dirname4, "..", "package.json"), "utf-8"));
28823
+ const pkg = JSON.parse(readFileSync42(resolve37(__dirname5, "..", "package.json"), "utf-8"));
28618
28824
  return pkg.version ?? "0.0.0";
28619
28825
  } catch {
28620
28826
  return "0.0.0";
@@ -28900,19 +29106,19 @@ var config_upgrade_exports = {};
28900
29106
  __export(config_upgrade_exports, {
28901
29107
  runConfigUpgrade: () => runConfigUpgrade
28902
29108
  });
28903
- import { existsSync as existsSync42, readFileSync as readFileSync43, writeFileSync as writeFileSync6, copyFileSync, unlinkSync as unlinkSync2 } from "fs";
28904
- import { resolve as resolve37 } from "path";
29109
+ import { existsSync as existsSync43, readFileSync as readFileSync43, writeFileSync as writeFileSync6, copyFileSync, unlinkSync as unlinkSync2 } from "fs";
29110
+ import { resolve as resolve38 } from "path";
28905
29111
  import { parse as parseYaml6 } from "yaml";
28906
29112
  async function runConfigUpgrade(opts = {}) {
28907
29113
  const cwd = opts.cwd ?? process.cwd();
28908
- const configPath = resolve37(cwd, "massu.config.yaml");
29114
+ const configPath = resolve38(cwd, "massu.config.yaml");
28909
29115
  const bakPath = `${configPath}.bak`;
28910
29116
  const log = opts.silent ? () => {
28911
29117
  } : (s) => process.stdout.write(s);
28912
29118
  const err = opts.silent ? () => {
28913
29119
  } : (s) => process.stderr.write(s);
28914
29120
  if (opts.rollback) {
28915
- if (!existsSync42(bakPath)) {
29121
+ if (!existsSync43(bakPath)) {
28916
29122
  const message = `No backup found at ${bakPath}`;
28917
29123
  err(message + "\n");
28918
29124
  return { exitCode: 1, action: "none", message };
@@ -28928,7 +29134,7 @@ async function runConfigUpgrade(opts = {}) {
28928
29134
  return { exitCode: 2, action: "none", message };
28929
29135
  }
28930
29136
  }
28931
- if (!existsSync42(configPath)) {
29137
+ if (!existsSync43(configPath)) {
28932
29138
  const message = "massu.config.yaml not found. Run: npx massu init";
28933
29139
  err(message + "\n");
28934
29140
  return { exitCode: 1, action: "none", message };
@@ -28992,8 +29198,8 @@ var config_check_drift_exports = {};
28992
29198
  __export(config_check_drift_exports, {
28993
29199
  runConfigCheckDrift: () => runConfigCheckDrift
28994
29200
  });
28995
- import { existsSync as existsSync43, readFileSync as readFileSync44 } from "fs";
28996
- import { resolve as resolve38 } from "path";
29201
+ import { existsSync as existsSync44, readFileSync as readFileSync44 } from "fs";
29202
+ import { resolve as resolve39 } from "path";
28997
29203
  import { parse as parseYaml7 } from "yaml";
28998
29204
  function renderChanges(changes) {
28999
29205
  if (changes.length === 0) return "(none)\n";
@@ -29001,12 +29207,12 @@ function renderChanges(changes) {
29001
29207
  }
29002
29208
  async function runConfigCheckDrift(opts = {}) {
29003
29209
  const cwd = opts.cwd ?? process.cwd();
29004
- const configPath = resolve38(cwd, "massu.config.yaml");
29210
+ const configPath = resolve39(cwd, "massu.config.yaml");
29005
29211
  const log = opts.silent ? () => {
29006
29212
  } : (s) => process.stdout.write(s);
29007
29213
  const err = opts.silent ? () => {
29008
29214
  } : (s) => process.stderr.write(s);
29009
- if (!existsSync43(configPath)) {
29215
+ if (!existsSync44(configPath)) {
29010
29216
  const message = "massu.config.yaml not found. Run: npx massu init";
29011
29217
  err(message + "\n");
29012
29218
  return {
@@ -29088,10 +29294,10 @@ var init_config_check_drift = __esm({
29088
29294
 
29089
29295
  // src/cli.ts
29090
29296
  import { readFileSync as readFileSync45 } from "fs";
29091
- import { resolve as resolve39, dirname as dirname18 } from "path";
29092
- import { fileURLToPath as fileURLToPath5 } from "url";
29093
- var __filename4 = fileURLToPath5(import.meta.url);
29094
- var __dirname5 = dirname18(__filename4);
29297
+ import { resolve as resolve40, dirname as dirname19 } from "path";
29298
+ import { fileURLToPath as fileURLToPath6 } from "url";
29299
+ var __filename5 = fileURLToPath6(import.meta.url);
29300
+ var __dirname6 = dirname19(__filename5);
29095
29301
  var args = process.argv.slice(2);
29096
29302
  var subcommand = args[0];
29097
29303
  async function main() {
@@ -29111,6 +29317,12 @@ async function main() {
29111
29317
  await runInstallHooks2();
29112
29318
  break;
29113
29319
  }
29320
+ case "hook-runner": {
29321
+ const { runHookRunner: runHookRunner2 } = await Promise.resolve().then(() => (init_hook_runner(), hook_runner_exports));
29322
+ const result = await runHookRunner2(args.slice(1));
29323
+ process.exit(result.exitCode);
29324
+ return;
29325
+ }
29114
29326
  case "install-commands": {
29115
29327
  const { runInstallCommands: runInstallCommands2 } = await Promise.resolve().then(() => (init_install_commands(), install_commands_exports));
29116
29328
  await runInstallCommands2();
@@ -29287,7 +29499,7 @@ Examples:
29287
29499
  }
29288
29500
  function printVersion() {
29289
29501
  try {
29290
- const pkg = JSON.parse(readFileSync45(resolve39(__dirname5, "../package.json"), "utf-8"));
29502
+ const pkg = JSON.parse(readFileSync45(resolve40(__dirname6, "../package.json"), "utf-8"));
29291
29503
  console.log(`massu v${pkg.version}`);
29292
29504
  } catch {
29293
29505
  console.log("massu v0.1.0");