md4ai 0.18.4 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.bundled.js +140 -61
  2. package/package.json +1 -1
@@ -112,7 +112,7 @@ var CURRENT_VERSION;
112
112
  var init_check_update = __esm({
113
113
  "dist/check-update.js"() {
114
114
  "use strict";
115
- CURRENT_VERSION = true ? "0.18.4" : "0.0.0-dev";
115
+ CURRENT_VERSION = true ? "0.19.0" : "0.0.0-dev";
116
116
  }
117
117
  });
118
118
 
@@ -1830,9 +1830,9 @@ var init_marketplace_scanner = __esm({
1830
1830
 
1831
1831
  // dist/doppler/auth.js
1832
1832
  async function resolveDopplerToken() {
1833
- const { join: join17 } = await import("node:path");
1834
- const { homedir: homedir10 } = await import("node:os");
1835
- const credPath = join17(homedir10(), ".md4ai", "credentials.json");
1833
+ const { join: join18 } = await import("node:path");
1834
+ const { homedir: homedir11 } = await import("node:os");
1835
+ const credPath = join18(homedir11(), ".md4ai", "credentials.json");
1836
1836
  const creds = await loadCredentials();
1837
1837
  if (creds?.dopplerToken) {
1838
1838
  return { token: creds.dopplerToken, sourcePath: credPath };
@@ -2072,6 +2072,46 @@ var init_doppler_scanner = __esm({
2072
2072
  }
2073
2073
  });
2074
2074
 
2075
+ // dist/scanner/global-config-scanner.js
2076
+ import { readFile as readFile10, stat as stat2 } from "node:fs/promises";
2077
+ import { join as join12 } from "node:path";
2078
+ import { homedir as homedir7 } from "node:os";
2079
+ async function scanGlobalConfigFiles() {
2080
+ const claudeDir = join12(homedir7(), ".claude");
2081
+ const results = [];
2082
+ for (const filename of GLOBAL_CONFIG_PATHS) {
2083
+ const fullPath = join12(claudeDir, filename);
2084
+ try {
2085
+ const [content, stats] = await Promise.all([
2086
+ readFile10(fullPath, "utf-8"),
2087
+ stat2(fullPath)
2088
+ ]);
2089
+ results.push({
2090
+ filePath: filename,
2091
+ content,
2092
+ sizeBytes: stats.size,
2093
+ lastModified: stats.mtime.toISOString()
2094
+ });
2095
+ } catch {
2096
+ }
2097
+ }
2098
+ return results;
2099
+ }
2100
+ var GLOBAL_CONFIG_PATHS;
2101
+ var init_global_config_scanner = __esm({
2102
+ "dist/scanner/global-config-scanner.js"() {
2103
+ "use strict";
2104
+ GLOBAL_CONFIG_PATHS = [
2105
+ "CLAUDE.md",
2106
+ "settings.json",
2107
+ "settings.local.json",
2108
+ "mcp.json",
2109
+ "remote-settings.json",
2110
+ "policy-limits.json"
2111
+ ];
2112
+ }
2113
+ });
2114
+
2075
2115
  // dist/scanner/index.js
2076
2116
  var scanner_exports = {};
2077
2117
  __export(scanner_exports, {
@@ -2079,9 +2119,9 @@ __export(scanner_exports, {
2079
2119
  scanProject: () => scanProject
2080
2120
  });
2081
2121
  import { readdir as readdir5 } from "node:fs/promises";
2082
- import { join as join12, relative as relative3, resolve as resolve4 } from "node:path";
2122
+ import { join as join13, relative as relative3, resolve as resolve4 } from "node:path";
2083
2123
  import { existsSync as existsSync7 } from "node:fs";
2084
- import { homedir as homedir7 } from "node:os";
2124
+ import { homedir as homedir8 } from "node:os";
2085
2125
  import { createHash } from "node:crypto";
2086
2126
  async function scanProject(projectRoot, folderId) {
2087
2127
  const allFiles = await discoverFiles(projectRoot);
@@ -2104,6 +2144,7 @@ async function scanProject(projectRoot, folderId) {
2104
2144
  const toolings = await detectToolings(projectRoot);
2105
2145
  const envManifest = await scanEnvManifest(projectRoot);
2106
2146
  const marketplacePlugins = await scanMarketplacePlugins();
2147
+ const globalConfigFiles = await scanGlobalConfigFiles();
2107
2148
  const doppler2 = await scanDoppler(projectRoot, folderId);
2108
2149
  if (doppler2 && envManifest) {
2109
2150
  const dopplerDrift = computeDopplerDrift(doppler2, envManifest);
@@ -2130,7 +2171,7 @@ async function scanProject(projectRoot, folderId) {
2130
2171
  depth: depthMap.get(br.from) ?? 999
2131
2172
  }));
2132
2173
  brokenRefs.sort((a, b) => a.depth - b.depth || a.from.localeCompare(b.from));
2133
- const scanData = JSON.stringify({ graph, orphans, brokenRefs, skills, staleFiles, toolings, envManifest, marketplacePlugins, doppler: doppler2 });
2174
+ const scanData = JSON.stringify({ graph, orphans, brokenRefs, skills, staleFiles, toolings, envManifest, marketplacePlugins, doppler: doppler2, globalConfigFiles });
2134
2175
  const dataHash = createHash("sha256").update(scanData).digest("hex");
2135
2176
  const pluginVersions = await checkPluginLatestVersions(marketplacePlugins);
2136
2177
  return {
@@ -2144,29 +2185,30 @@ async function scanProject(projectRoot, folderId) {
2144
2185
  doppler: doppler2,
2145
2186
  marketplacePlugins,
2146
2187
  pluginVersions,
2188
+ globalConfigFiles,
2147
2189
  scannedAt: (/* @__PURE__ */ new Date()).toISOString(),
2148
2190
  dataHash
2149
2191
  };
2150
2192
  }
2151
2193
  async function discoverFiles(projectRoot) {
2152
2194
  const files = [];
2153
- const claudeDir = join12(projectRoot, ".claude");
2195
+ const claudeDir = join13(projectRoot, ".claude");
2154
2196
  if (existsSync7(claudeDir)) {
2155
2197
  await walkDir(claudeDir, projectRoot, files);
2156
2198
  }
2157
- if (existsSync7(join12(projectRoot, "CLAUDE.md"))) {
2199
+ if (existsSync7(join13(projectRoot, "CLAUDE.md"))) {
2158
2200
  files.push("CLAUDE.md");
2159
2201
  }
2160
- if (existsSync7(join12(projectRoot, "skills.md"))) {
2202
+ if (existsSync7(join13(projectRoot, "skills.md"))) {
2161
2203
  files.push("skills.md");
2162
2204
  }
2163
- const plansDir = join12(projectRoot, "docs", "plans");
2205
+ const plansDir = join13(projectRoot, "docs", "plans");
2164
2206
  if (existsSync7(plansDir)) {
2165
2207
  await walkDir(plansDir, projectRoot, files);
2166
2208
  }
2167
2209
  const absRoot = resolve4(projectRoot);
2168
2210
  const projectHash = absRoot.replace(/\//g, "-");
2169
- const memoryDir = join12(homedir7(), ".claude", "projects", projectHash, "memory");
2211
+ const memoryDir = join13(homedir8(), ".claude", "projects", projectHash, "memory");
2170
2212
  if (existsSync7(memoryDir)) {
2171
2213
  const memEntries = await readdir5(memoryDir, { withFileTypes: true });
2172
2214
  for (const entry of memEntries) {
@@ -2180,7 +2222,7 @@ async function discoverFiles(projectRoot) {
2180
2222
  async function walkDir(dir, projectRoot, files) {
2181
2223
  const entries = await readdir5(dir, { withFileTypes: true });
2182
2224
  for (const entry of entries) {
2183
- const fullPath = join12(dir, entry.name);
2225
+ const fullPath = join13(dir, entry.name);
2184
2226
  if (entry.isDirectory()) {
2185
2227
  if (["node_modules", ".git", ".turbo", "cache", "session-env"].includes(entry.name))
2186
2228
  continue;
@@ -2199,7 +2241,7 @@ function identifyRoots(allFiles, projectRoot) {
2199
2241
  }
2200
2242
  }
2201
2243
  for (const globalFile of GLOBAL_ROOT_FILES) {
2202
- const expanded = globalFile.replace("~", homedir7());
2244
+ const expanded = globalFile.replace("~", homedir8());
2203
2245
  if (existsSync7(expanded)) {
2204
2246
  roots.push(globalFile);
2205
2247
  }
@@ -2207,7 +2249,7 @@ function identifyRoots(allFiles, projectRoot) {
2207
2249
  return roots;
2208
2250
  }
2209
2251
  async function readClaudeConfigFiles(projectRoot, graphFilePaths) {
2210
- const { readFile: readFile14, stat: stat2 } = await import("node:fs/promises");
2252
+ const { readFile: readFile15, stat: stat3 } = await import("node:fs/promises");
2211
2253
  const { existsSync: existsSync15 } = await import("node:fs");
2212
2254
  const filePaths = graphFilePaths ?? await discoverFiles(projectRoot);
2213
2255
  const files = [];
@@ -2222,8 +2264,8 @@ async function readClaudeConfigFiles(projectRoot, graphFilePaths) {
2222
2264
  if (!existsSync15(fullPath))
2223
2265
  continue;
2224
2266
  try {
2225
- const content = await readFile14(fullPath, "utf-8");
2226
- const fileStat = await stat2(fullPath);
2267
+ const content = await readFile15(fullPath, "utf-8");
2268
+ const fileStat = await stat3(fullPath);
2227
2269
  const lastMod = getGitLastModified(fullPath, projectRoot);
2228
2270
  files.push({ filePath: relPath, content, sizeBytes: fileStat.size, lastModified: lastMod });
2229
2271
  } catch {
@@ -2235,9 +2277,9 @@ function resolveFilePath(relPath, projectRoot) {
2235
2277
  if (relPath.startsWith(".claude/memory/")) {
2236
2278
  const absRoot = resolve4(projectRoot);
2237
2279
  const projectHash = absRoot.replace(/\//g, "-");
2238
- return join12(homedir7(), ".claude", "projects", projectHash, "memory", relPath.replace(".claude/memory/", ""));
2280
+ return join13(homedir8(), ".claude", "projects", projectHash, "memory", relPath.replace(".claude/memory/", ""));
2239
2281
  }
2240
- return join12(projectRoot, relPath);
2282
+ return join13(projectRoot, relPath);
2241
2283
  }
2242
2284
  function detectStaleFiles(allFiles, projectRoot) {
2243
2285
  const stale = [];
@@ -2267,6 +2309,7 @@ var init_scanner = __esm({
2267
2309
  init_env_manifest_scanner();
2268
2310
  init_marketplace_scanner();
2269
2311
  init_doppler_scanner();
2312
+ init_global_config_scanner();
2270
2313
  }
2271
2314
  });
2272
2315
 
@@ -2702,6 +2745,18 @@ ${proposedFiles.length} file(s) proposed for deletion:
2702
2745
  }
2703
2746
  console.log(chalk12.green(` Uploaded ${configFiles.length} config file(s).`));
2704
2747
  }
2748
+ if (result.globalConfigFiles.length > 0 && deviceId) {
2749
+ for (const file of result.globalConfigFiles) {
2750
+ await supabase.from("device_config_files").upsert({
2751
+ device_id: deviceId,
2752
+ file_path: file.filePath,
2753
+ content: file.content,
2754
+ size_bytes: file.sizeBytes,
2755
+ last_modified: file.lastModified
2756
+ }, { onConflict: "device_id,file_path" });
2757
+ }
2758
+ console.log(chalk12.green(` Uploaded ${result.globalConfigFiles.length} global config file(s).`));
2759
+ }
2705
2760
  } else {
2706
2761
  console.log(chalk12.yellow("\nThis folder is not linked to a project on your dashboard."));
2707
2762
  if (!process.stdin.isTTY) {
@@ -2790,6 +2845,18 @@ ${proposedFiles.length} file(s) proposed for deletion:
2790
2845
  device_id: inlineDeviceId
2791
2846
  }, { onConflict: "folder_id,file_path,device_id" });
2792
2847
  }
2848
+ if (result.globalConfigFiles.length > 0 && inlineDeviceId) {
2849
+ for (const file of result.globalConfigFiles) {
2850
+ await sb.from("device_config_files").upsert({
2851
+ device_id: inlineDeviceId,
2852
+ file_path: file.filePath,
2853
+ content: file.content,
2854
+ size_bytes: file.sizeBytes,
2855
+ last_modified: file.lastModified
2856
+ }, { onConflict: "device_id,file_path" });
2857
+ }
2858
+ console.log(chalk12.green(` Uploaded ${result.globalConfigFiles.length} global config file(s).`));
2859
+ }
2793
2860
  await saveState({
2794
2861
  lastFolderId: folderId,
2795
2862
  lastDeviceName: deviceName,
@@ -2821,16 +2888,16 @@ var init_map = __esm({
2821
2888
  });
2822
2889
 
2823
2890
  // dist/mcp/read-configs.js
2824
- import { readFile as readFile12 } from "node:fs/promises";
2825
- import { join as join15 } from "node:path";
2826
- import { homedir as homedir9 } from "node:os";
2891
+ import { readFile as readFile13 } from "node:fs/promises";
2892
+ import { join as join16 } from "node:path";
2893
+ import { homedir as homedir10 } from "node:os";
2827
2894
  import { existsSync as existsSync12 } from "node:fs";
2828
2895
  import { readdir as readdir6 } from "node:fs/promises";
2829
2896
  async function readJsonSafe(path) {
2830
2897
  try {
2831
2898
  if (!existsSync12(path))
2832
2899
  return null;
2833
- const raw = await readFile12(path, "utf-8");
2900
+ const raw = await readFile13(path, "utf-8");
2834
2901
  return JSON.parse(raw);
2835
2902
  } catch {
2836
2903
  return null;
@@ -2890,52 +2957,52 @@ function parseFlatConfig(data, source) {
2890
2957
  return entries;
2891
2958
  }
2892
2959
  async function readAllMcpConfigs() {
2893
- const home = homedir9();
2960
+ const home = homedir10();
2894
2961
  const entries = [];
2895
- const userConfig = await readJsonSafe(join15(home, ".claude.json"));
2962
+ const userConfig = await readJsonSafe(join16(home, ".claude.json"));
2896
2963
  entries.push(...parseServers(userConfig, "global"));
2897
- const globalMcp = await readJsonSafe(join15(home, ".claude", "mcp.json"));
2964
+ const globalMcp = await readJsonSafe(join16(home, ".claude", "mcp.json"));
2898
2965
  entries.push(...parseServers(globalMcp, "global"));
2899
- const cwdMcp = await readJsonSafe(join15(process.cwd(), ".mcp.json"));
2966
+ const cwdMcp = await readJsonSafe(join16(process.cwd(), ".mcp.json"));
2900
2967
  entries.push(...parseServers(cwdMcp, "project"));
2901
- const pluginsBase = join15(home, ".claude", "plugins", "marketplaces");
2968
+ const pluginsBase = join16(home, ".claude", "plugins", "marketplaces");
2902
2969
  if (existsSync12(pluginsBase)) {
2903
2970
  try {
2904
2971
  const marketplaces = await readdir6(pluginsBase, { withFileTypes: true });
2905
2972
  for (const mp of marketplaces) {
2906
2973
  if (!mp.isDirectory())
2907
2974
  continue;
2908
- const extDir = join15(pluginsBase, mp.name, "external_plugins");
2975
+ const extDir = join16(pluginsBase, mp.name, "external_plugins");
2909
2976
  if (!existsSync12(extDir))
2910
2977
  continue;
2911
2978
  const plugins = await readdir6(extDir, { withFileTypes: true });
2912
2979
  for (const plugin of plugins) {
2913
2980
  if (!plugin.isDirectory())
2914
2981
  continue;
2915
- const pluginMcp = await readJsonSafe(join15(extDir, plugin.name, ".mcp.json"));
2982
+ const pluginMcp = await readJsonSafe(join16(extDir, plugin.name, ".mcp.json"));
2916
2983
  entries.push(...parseServers(pluginMcp, "plugin"));
2917
2984
  }
2918
2985
  }
2919
2986
  } catch {
2920
2987
  }
2921
2988
  }
2922
- const cacheBase = join15(home, ".claude", "plugins", "cache");
2989
+ const cacheBase = join16(home, ".claude", "plugins", "cache");
2923
2990
  if (existsSync12(cacheBase)) {
2924
2991
  try {
2925
2992
  const registries = await readdir6(cacheBase, { withFileTypes: true });
2926
2993
  for (const reg of registries) {
2927
2994
  if (!reg.isDirectory())
2928
2995
  continue;
2929
- const regDir = join15(cacheBase, reg.name);
2996
+ const regDir = join16(cacheBase, reg.name);
2930
2997
  const plugins = await readdir6(regDir, { withFileTypes: true });
2931
2998
  for (const plugin of plugins) {
2932
2999
  if (!plugin.isDirectory())
2933
3000
  continue;
2934
- const versionDirs = await readdir6(join15(regDir, plugin.name), { withFileTypes: true });
3001
+ const versionDirs = await readdir6(join16(regDir, plugin.name), { withFileTypes: true });
2935
3002
  for (const ver of versionDirs) {
2936
3003
  if (!ver.isDirectory())
2937
3004
  continue;
2938
- const mcpPath = join15(regDir, plugin.name, ver.name, ".mcp.json");
3005
+ const mcpPath = join16(regDir, plugin.name, ver.name, ".mcp.json");
2939
3006
  const flatData = await readJsonSafe(mcpPath);
2940
3007
  if (flatData) {
2941
3008
  entries.push(...parseFlatConfig(flatData, "plugin"));
@@ -3950,41 +4017,41 @@ init_map();
3950
4017
 
3951
4018
  // dist/commands/simulate.js
3952
4019
  init_dist();
3953
- import { join as join13 } from "node:path";
4020
+ import { join as join14 } from "node:path";
3954
4021
  import { existsSync as existsSync9 } from "node:fs";
3955
- import { homedir as homedir8 } from "node:os";
4022
+ import { homedir as homedir9 } from "node:os";
3956
4023
  import chalk13 from "chalk";
3957
4024
  async function simulateCommand(prompt) {
3958
4025
  const projectRoot = process.cwd();
3959
4026
  console.log(chalk13.blue(`Simulating prompt: "${prompt}"
3960
4027
  `));
3961
4028
  console.log(chalk13.dim("Files Claude would load:\n"));
3962
- const globalClaude = join13(homedir8(), ".claude", "CLAUDE.md");
4029
+ const globalClaude = join14(homedir9(), ".claude", "CLAUDE.md");
3963
4030
  if (existsSync9(globalClaude)) {
3964
4031
  console.log(chalk13.green(" \u2713 ~/.claude/CLAUDE.md (global)"));
3965
4032
  }
3966
4033
  for (const rootFile of ROOT_FILES) {
3967
- const fullPath = join13(projectRoot, rootFile);
4034
+ const fullPath = join14(projectRoot, rootFile);
3968
4035
  if (existsSync9(fullPath)) {
3969
4036
  console.log(chalk13.green(` \u2713 ${rootFile} (project root)`));
3970
4037
  }
3971
4038
  }
3972
4039
  const settingsFiles = [
3973
- join13(homedir8(), ".claude", "settings.json"),
3974
- join13(homedir8(), ".claude", "settings.local.json"),
3975
- join13(projectRoot, ".claude", "settings.json"),
3976
- join13(projectRoot, ".claude", "settings.local.json")
4040
+ join14(homedir9(), ".claude", "settings.json"),
4041
+ join14(homedir9(), ".claude", "settings.local.json"),
4042
+ join14(projectRoot, ".claude", "settings.json"),
4043
+ join14(projectRoot, ".claude", "settings.local.json")
3977
4044
  ];
3978
4045
  for (const sf of settingsFiles) {
3979
4046
  if (existsSync9(sf)) {
3980
- const display = sf.startsWith(homedir8()) ? sf.replace(homedir8(), "~") : sf.replace(projectRoot + "/", "");
4047
+ const display = sf.startsWith(homedir9()) ? sf.replace(homedir9(), "~") : sf.replace(projectRoot + "/", "");
3981
4048
  console.log(chalk13.green(` \u2713 ${display} (settings)`));
3982
4049
  }
3983
4050
  }
3984
4051
  const words = prompt.split(/\s+/);
3985
4052
  for (const word of words) {
3986
4053
  const cleaned = word.replace(/['"]/g, "");
3987
- const candidatePath = join13(projectRoot, cleaned);
4054
+ const candidatePath = join14(projectRoot, cleaned);
3988
4055
  if (existsSync9(candidatePath) && cleaned.includes("/")) {
3989
4056
  console.log(chalk13.cyan(` \u2192 ${cleaned} (referenced in prompt)`));
3990
4057
  }
@@ -3993,18 +4060,18 @@ async function simulateCommand(prompt) {
3993
4060
  }
3994
4061
 
3995
4062
  // dist/commands/print.js
3996
- import { join as join14 } from "node:path";
3997
- import { readFile as readFile10, writeFile as writeFile3 } from "node:fs/promises";
4063
+ import { join as join15 } from "node:path";
4064
+ import { readFile as readFile11, writeFile as writeFile3 } from "node:fs/promises";
3998
4065
  import { existsSync as existsSync10 } from "node:fs";
3999
4066
  import chalk14 from "chalk";
4000
4067
  async function printCommand(title) {
4001
4068
  const projectRoot = process.cwd();
4002
- const scanDataPath = join14(projectRoot, "output", "index.html");
4069
+ const scanDataPath = join15(projectRoot, "output", "index.html");
4003
4070
  if (!existsSync10(scanDataPath)) {
4004
4071
  console.error(chalk14.red("No scan data found. Run: md4ai scan"));
4005
4072
  process.exit(1);
4006
4073
  }
4007
- const html = await readFile10(scanDataPath, "utf-8");
4074
+ const html = await readFile11(scanDataPath, "utf-8");
4008
4075
  const match = html.match(/<script type="application\/json" id="scan-data">([\s\S]*?)<\/script>/);
4009
4076
  if (!match) {
4010
4077
  console.error(chalk14.red("Could not extract scan data from output/index.html"));
@@ -4012,7 +4079,7 @@ async function printCommand(title) {
4012
4079
  }
4013
4080
  const result = JSON.parse(match[1]);
4014
4081
  const printHtml = generatePrintHtml(result, title);
4015
- const outputPath = join14(projectRoot, "output", `print-${Date.now()}.html`);
4082
+ const outputPath = join15(projectRoot, "output", `print-${Date.now()}.html`);
4016
4083
  await writeFile3(outputPath, printHtml, "utf-8");
4017
4084
  console.log(chalk14.green(`Print-ready wall sheet: ${outputPath}`));
4018
4085
  }
@@ -4167,6 +4234,18 @@ Linking "${folder.name}" to this device...
4167
4234
  }
4168
4235
  console.log(chalk15.green(` Uploaded ${configFiles.length} config file(s).`));
4169
4236
  }
4237
+ if (result.globalConfigFiles.length > 0) {
4238
+ for (const file of result.globalConfigFiles) {
4239
+ await supabase.from("device_config_files").upsert({
4240
+ device_id: deviceId,
4241
+ file_path: file.filePath,
4242
+ content: file.content,
4243
+ size_bytes: file.sizeBytes,
4244
+ last_modified: file.lastModified
4245
+ }, { onConflict: "device_id,file_path" });
4246
+ }
4247
+ console.log(chalk15.green(` Uploaded ${result.globalConfigFiles.length} global config file(s).`));
4248
+ }
4170
4249
  await supabase.from("device_paths").update({ last_synced: (/* @__PURE__ */ new Date()).toISOString() }).eq("folder_id", folder.id).eq("device_name", deviceName);
4171
4250
  await saveState({
4172
4251
  lastFolderId: folder.id,
@@ -4182,7 +4261,7 @@ Linking "${folder.name}" to this device...
4182
4261
  }
4183
4262
 
4184
4263
  // dist/commands/import-bundle.js
4185
- import { readFile as readFile11, writeFile as writeFile4, mkdir as mkdir3, stat as fsStat } from "node:fs/promises";
4264
+ import { readFile as readFile12, writeFile as writeFile4, mkdir as mkdir3, stat as fsStat } from "node:fs/promises";
4186
4265
  import { dirname as dirname3, resolve as resolve7 } from "node:path";
4187
4266
  import { existsSync as existsSync11 } from "node:fs";
4188
4267
  import chalk16 from "chalk";
@@ -4199,7 +4278,7 @@ async function importBundleCommand(zipPath) {
4199
4278
  process.exit(1);
4200
4279
  }
4201
4280
  const JSZip = (await import("jszip")).default;
4202
- const zipData = await readFile11(zipPath);
4281
+ const zipData = await readFile12(zipPath);
4203
4282
  const zip = await JSZip.loadAsync(zipData);
4204
4283
  const manifestFile = zip.file("manifest.json");
4205
4284
  if (!manifestFile) {
@@ -4561,8 +4640,8 @@ async function fetchGitHubVersions(repo, signal) {
4561
4640
  init_mcp_watch();
4562
4641
 
4563
4642
  // dist/commands/init-manifest.js
4564
- import { resolve as resolve8, join as join16, relative as relative4, dirname as dirname4 } from "node:path";
4565
- import { readFile as readFile13, writeFile as writeFile5, mkdir as mkdir4 } from "node:fs/promises";
4643
+ import { resolve as resolve8, join as join17, relative as relative4, dirname as dirname4 } from "node:path";
4644
+ import { readFile as readFile14, writeFile as writeFile5, mkdir as mkdir4 } from "node:fs/promises";
4566
4645
  import { existsSync as existsSync13 } from "node:fs";
4567
4646
  import chalk21 from "chalk";
4568
4647
  var SECRET_PATTERNS = [
@@ -4580,7 +4659,7 @@ function isLikelySecret(name) {
4580
4659
  async function discoverEnvFiles(projectRoot) {
4581
4660
  const apps = [];
4582
4661
  for (const envName of [".env", ".env.local", ".env.example"]) {
4583
- const envPath = join16(projectRoot, envName);
4662
+ const envPath = join17(projectRoot, envName);
4584
4663
  if (existsSync13(envPath)) {
4585
4664
  const vars = await extractVarNames(envPath);
4586
4665
  if (vars.length > 0) {
@@ -4591,11 +4670,11 @@ async function discoverEnvFiles(projectRoot) {
4591
4670
  }
4592
4671
  const subdirs = ["web", "cli", "api", "app", "server", "packages"];
4593
4672
  for (const sub of subdirs) {
4594
- const subDir = join16(projectRoot, sub);
4673
+ const subDir = join17(projectRoot, sub);
4595
4674
  if (!existsSync13(subDir))
4596
4675
  continue;
4597
4676
  for (const envName of [".env.local", ".env", ".env.example"]) {
4598
- const envPath = join16(subDir, envName);
4677
+ const envPath = join17(subDir, envName);
4599
4678
  if (existsSync13(envPath)) {
4600
4679
  const vars = await extractVarNames(envPath);
4601
4680
  if (vars.length > 0) {
@@ -4612,7 +4691,7 @@ async function discoverEnvFiles(projectRoot) {
4612
4691
  return apps;
4613
4692
  }
4614
4693
  async function extractVarNames(envPath) {
4615
- const content = await readFile13(envPath, "utf-8");
4694
+ const content = await readFile14(envPath, "utf-8");
4616
4695
  const vars = [];
4617
4696
  for (const line of content.split("\n")) {
4618
4697
  const trimmed = line.trim();
@@ -4657,7 +4736,7 @@ function generateManifest(apps) {
4657
4736
  }
4658
4737
  async function initManifestCommand() {
4659
4738
  const projectRoot = resolve8(process.cwd());
4660
- const manifestPath = join16(projectRoot, "docs", "reference", "env-manifest.md");
4739
+ const manifestPath = join17(projectRoot, "docs", "reference", "env-manifest.md");
4661
4740
  if (existsSync13(manifestPath)) {
4662
4741
  console.log(chalk21.yellow(`Manifest already exists: ${relative4(projectRoot, manifestPath)}`));
4663
4742
  console.log(chalk21.dim("Edit it directly to make changes."));
@@ -5046,9 +5125,9 @@ async function dopplerDisconnectCommand() {
5046
5125
  }
5047
5126
  const { dopplerToken: _, ...rest } = creds;
5048
5127
  const { writeFile: writeFile6, chmod: chmod2 } = await import("node:fs/promises");
5049
- const { join: join17 } = await import("node:path");
5050
- const { homedir: homedir10 } = await import("node:os");
5051
- const credPath = join17(homedir10(), ".md4ai", "credentials.json");
5128
+ const { join: join18 } = await import("node:path");
5129
+ const { homedir: homedir11 } = await import("node:os");
5130
+ const credPath = join18(homedir11(), ".md4ai", "credentials.json");
5052
5131
  await writeFile6(credPath, JSON.stringify(rest, null, 2), "utf-8");
5053
5132
  await chmod2(credPath, 384);
5054
5133
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "md4ai",
3
- "version": "0.18.4",
3
+ "version": "0.19.0",
4
4
  "description": "CLI for MD4AI — scan Claude projects and sync to your dashboard",
5
5
  "type": "module",
6
6
  "bin": {