md4ai 0.18.4 → 0.19.1

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 +147 -63
  2. package/package.json +1 -1
@@ -12,6 +12,9 @@ var __export = (target, all) => {
12
12
  // dist/check-update.js
13
13
  import chalk from "chalk";
14
14
  import { execFileSync, spawn } from "node:child_process";
15
+ function wasUpdateHandedOff() {
16
+ return updateHandedOff;
17
+ }
15
18
  async function fetchLatest() {
16
19
  try {
17
20
  const controller = new AbortController();
@@ -98,6 +101,7 @@ async function promptUpdateIfAvailable(originalArgs) {
98
101
  return true;
99
102
  }
100
103
  console.log(chalk.green("\n Updated successfully! Re-running command...\n"));
104
+ updateHandedOff = true;
101
105
  const child = spawn("md4ai", originalArgs, {
102
106
  stdio: "inherit",
103
107
  shell: false
@@ -108,11 +112,12 @@ async function promptUpdateIfAvailable(originalArgs) {
108
112
  return true;
109
113
  }
110
114
  }
111
- var CURRENT_VERSION;
115
+ var CURRENT_VERSION, updateHandedOff;
112
116
  var init_check_update = __esm({
113
117
  "dist/check-update.js"() {
114
118
  "use strict";
115
- CURRENT_VERSION = true ? "0.18.4" : "0.0.0-dev";
119
+ CURRENT_VERSION = true ? "0.19.1" : "0.0.0-dev";
120
+ updateHandedOff = false;
116
121
  }
117
122
  });
118
123
 
@@ -1830,9 +1835,9 @@ var init_marketplace_scanner = __esm({
1830
1835
 
1831
1836
  // dist/doppler/auth.js
1832
1837
  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");
1838
+ const { join: join18 } = await import("node:path");
1839
+ const { homedir: homedir11 } = await import("node:os");
1840
+ const credPath = join18(homedir11(), ".md4ai", "credentials.json");
1836
1841
  const creds = await loadCredentials();
1837
1842
  if (creds?.dopplerToken) {
1838
1843
  return { token: creds.dopplerToken, sourcePath: credPath };
@@ -2072,6 +2077,46 @@ var init_doppler_scanner = __esm({
2072
2077
  }
2073
2078
  });
2074
2079
 
2080
+ // dist/scanner/global-config-scanner.js
2081
+ import { readFile as readFile10, stat as stat2 } from "node:fs/promises";
2082
+ import { join as join12 } from "node:path";
2083
+ import { homedir as homedir7 } from "node:os";
2084
+ async function scanGlobalConfigFiles() {
2085
+ const claudeDir = join12(homedir7(), ".claude");
2086
+ const results = [];
2087
+ for (const filename of GLOBAL_CONFIG_PATHS) {
2088
+ const fullPath = join12(claudeDir, filename);
2089
+ try {
2090
+ const [content, stats] = await Promise.all([
2091
+ readFile10(fullPath, "utf-8"),
2092
+ stat2(fullPath)
2093
+ ]);
2094
+ results.push({
2095
+ filePath: filename,
2096
+ content,
2097
+ sizeBytes: stats.size,
2098
+ lastModified: stats.mtime.toISOString()
2099
+ });
2100
+ } catch {
2101
+ }
2102
+ }
2103
+ return results;
2104
+ }
2105
+ var GLOBAL_CONFIG_PATHS;
2106
+ var init_global_config_scanner = __esm({
2107
+ "dist/scanner/global-config-scanner.js"() {
2108
+ "use strict";
2109
+ GLOBAL_CONFIG_PATHS = [
2110
+ "CLAUDE.md",
2111
+ "settings.json",
2112
+ "settings.local.json",
2113
+ "mcp.json",
2114
+ "remote-settings.json",
2115
+ "policy-limits.json"
2116
+ ];
2117
+ }
2118
+ });
2119
+
2075
2120
  // dist/scanner/index.js
2076
2121
  var scanner_exports = {};
2077
2122
  __export(scanner_exports, {
@@ -2079,9 +2124,9 @@ __export(scanner_exports, {
2079
2124
  scanProject: () => scanProject
2080
2125
  });
2081
2126
  import { readdir as readdir5 } from "node:fs/promises";
2082
- import { join as join12, relative as relative3, resolve as resolve4 } from "node:path";
2127
+ import { join as join13, relative as relative3, resolve as resolve4 } from "node:path";
2083
2128
  import { existsSync as existsSync7 } from "node:fs";
2084
- import { homedir as homedir7 } from "node:os";
2129
+ import { homedir as homedir8 } from "node:os";
2085
2130
  import { createHash } from "node:crypto";
2086
2131
  async function scanProject(projectRoot, folderId) {
2087
2132
  const allFiles = await discoverFiles(projectRoot);
@@ -2104,6 +2149,7 @@ async function scanProject(projectRoot, folderId) {
2104
2149
  const toolings = await detectToolings(projectRoot);
2105
2150
  const envManifest = await scanEnvManifest(projectRoot);
2106
2151
  const marketplacePlugins = await scanMarketplacePlugins();
2152
+ const globalConfigFiles = await scanGlobalConfigFiles();
2107
2153
  const doppler2 = await scanDoppler(projectRoot, folderId);
2108
2154
  if (doppler2 && envManifest) {
2109
2155
  const dopplerDrift = computeDopplerDrift(doppler2, envManifest);
@@ -2130,7 +2176,7 @@ async function scanProject(projectRoot, folderId) {
2130
2176
  depth: depthMap.get(br.from) ?? 999
2131
2177
  }));
2132
2178
  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 });
2179
+ const scanData = JSON.stringify({ graph, orphans, brokenRefs, skills, staleFiles, toolings, envManifest, marketplacePlugins, doppler: doppler2, globalConfigFiles });
2134
2180
  const dataHash = createHash("sha256").update(scanData).digest("hex");
2135
2181
  const pluginVersions = await checkPluginLatestVersions(marketplacePlugins);
2136
2182
  return {
@@ -2144,29 +2190,30 @@ async function scanProject(projectRoot, folderId) {
2144
2190
  doppler: doppler2,
2145
2191
  marketplacePlugins,
2146
2192
  pluginVersions,
2193
+ globalConfigFiles,
2147
2194
  scannedAt: (/* @__PURE__ */ new Date()).toISOString(),
2148
2195
  dataHash
2149
2196
  };
2150
2197
  }
2151
2198
  async function discoverFiles(projectRoot) {
2152
2199
  const files = [];
2153
- const claudeDir = join12(projectRoot, ".claude");
2200
+ const claudeDir = join13(projectRoot, ".claude");
2154
2201
  if (existsSync7(claudeDir)) {
2155
2202
  await walkDir(claudeDir, projectRoot, files);
2156
2203
  }
2157
- if (existsSync7(join12(projectRoot, "CLAUDE.md"))) {
2204
+ if (existsSync7(join13(projectRoot, "CLAUDE.md"))) {
2158
2205
  files.push("CLAUDE.md");
2159
2206
  }
2160
- if (existsSync7(join12(projectRoot, "skills.md"))) {
2207
+ if (existsSync7(join13(projectRoot, "skills.md"))) {
2161
2208
  files.push("skills.md");
2162
2209
  }
2163
- const plansDir = join12(projectRoot, "docs", "plans");
2210
+ const plansDir = join13(projectRoot, "docs", "plans");
2164
2211
  if (existsSync7(plansDir)) {
2165
2212
  await walkDir(plansDir, projectRoot, files);
2166
2213
  }
2167
2214
  const absRoot = resolve4(projectRoot);
2168
2215
  const projectHash = absRoot.replace(/\//g, "-");
2169
- const memoryDir = join12(homedir7(), ".claude", "projects", projectHash, "memory");
2216
+ const memoryDir = join13(homedir8(), ".claude", "projects", projectHash, "memory");
2170
2217
  if (existsSync7(memoryDir)) {
2171
2218
  const memEntries = await readdir5(memoryDir, { withFileTypes: true });
2172
2219
  for (const entry of memEntries) {
@@ -2180,7 +2227,7 @@ async function discoverFiles(projectRoot) {
2180
2227
  async function walkDir(dir, projectRoot, files) {
2181
2228
  const entries = await readdir5(dir, { withFileTypes: true });
2182
2229
  for (const entry of entries) {
2183
- const fullPath = join12(dir, entry.name);
2230
+ const fullPath = join13(dir, entry.name);
2184
2231
  if (entry.isDirectory()) {
2185
2232
  if (["node_modules", ".git", ".turbo", "cache", "session-env"].includes(entry.name))
2186
2233
  continue;
@@ -2199,7 +2246,7 @@ function identifyRoots(allFiles, projectRoot) {
2199
2246
  }
2200
2247
  }
2201
2248
  for (const globalFile of GLOBAL_ROOT_FILES) {
2202
- const expanded = globalFile.replace("~", homedir7());
2249
+ const expanded = globalFile.replace("~", homedir8());
2203
2250
  if (existsSync7(expanded)) {
2204
2251
  roots.push(globalFile);
2205
2252
  }
@@ -2207,7 +2254,7 @@ function identifyRoots(allFiles, projectRoot) {
2207
2254
  return roots;
2208
2255
  }
2209
2256
  async function readClaudeConfigFiles(projectRoot, graphFilePaths) {
2210
- const { readFile: readFile14, stat: stat2 } = await import("node:fs/promises");
2257
+ const { readFile: readFile15, stat: stat3 } = await import("node:fs/promises");
2211
2258
  const { existsSync: existsSync15 } = await import("node:fs");
2212
2259
  const filePaths = graphFilePaths ?? await discoverFiles(projectRoot);
2213
2260
  const files = [];
@@ -2222,8 +2269,8 @@ async function readClaudeConfigFiles(projectRoot, graphFilePaths) {
2222
2269
  if (!existsSync15(fullPath))
2223
2270
  continue;
2224
2271
  try {
2225
- const content = await readFile14(fullPath, "utf-8");
2226
- const fileStat = await stat2(fullPath);
2272
+ const content = await readFile15(fullPath, "utf-8");
2273
+ const fileStat = await stat3(fullPath);
2227
2274
  const lastMod = getGitLastModified(fullPath, projectRoot);
2228
2275
  files.push({ filePath: relPath, content, sizeBytes: fileStat.size, lastModified: lastMod });
2229
2276
  } catch {
@@ -2235,9 +2282,9 @@ function resolveFilePath(relPath, projectRoot) {
2235
2282
  if (relPath.startsWith(".claude/memory/")) {
2236
2283
  const absRoot = resolve4(projectRoot);
2237
2284
  const projectHash = absRoot.replace(/\//g, "-");
2238
- return join12(homedir7(), ".claude", "projects", projectHash, "memory", relPath.replace(".claude/memory/", ""));
2285
+ return join13(homedir8(), ".claude", "projects", projectHash, "memory", relPath.replace(".claude/memory/", ""));
2239
2286
  }
2240
- return join12(projectRoot, relPath);
2287
+ return join13(projectRoot, relPath);
2241
2288
  }
2242
2289
  function detectStaleFiles(allFiles, projectRoot) {
2243
2290
  const stale = [];
@@ -2267,6 +2314,7 @@ var init_scanner = __esm({
2267
2314
  init_env_manifest_scanner();
2268
2315
  init_marketplace_scanner();
2269
2316
  init_doppler_scanner();
2317
+ init_global_config_scanner();
2270
2318
  }
2271
2319
  });
2272
2320
 
@@ -2702,6 +2750,18 @@ ${proposedFiles.length} file(s) proposed for deletion:
2702
2750
  }
2703
2751
  console.log(chalk12.green(` Uploaded ${configFiles.length} config file(s).`));
2704
2752
  }
2753
+ if (result.globalConfigFiles.length > 0 && deviceId) {
2754
+ for (const file of result.globalConfigFiles) {
2755
+ await supabase.from("device_config_files").upsert({
2756
+ device_id: deviceId,
2757
+ file_path: file.filePath,
2758
+ content: file.content,
2759
+ size_bytes: file.sizeBytes,
2760
+ last_modified: file.lastModified
2761
+ }, { onConflict: "device_id,file_path" });
2762
+ }
2763
+ console.log(chalk12.green(` Uploaded ${result.globalConfigFiles.length} global config file(s).`));
2764
+ }
2705
2765
  } else {
2706
2766
  console.log(chalk12.yellow("\nThis folder is not linked to a project on your dashboard."));
2707
2767
  if (!process.stdin.isTTY) {
@@ -2790,6 +2850,18 @@ ${proposedFiles.length} file(s) proposed for deletion:
2790
2850
  device_id: inlineDeviceId
2791
2851
  }, { onConflict: "folder_id,file_path,device_id" });
2792
2852
  }
2853
+ if (result.globalConfigFiles.length > 0 && inlineDeviceId) {
2854
+ for (const file of result.globalConfigFiles) {
2855
+ await sb.from("device_config_files").upsert({
2856
+ device_id: inlineDeviceId,
2857
+ file_path: file.filePath,
2858
+ content: file.content,
2859
+ size_bytes: file.sizeBytes,
2860
+ last_modified: file.lastModified
2861
+ }, { onConflict: "device_id,file_path" });
2862
+ }
2863
+ console.log(chalk12.green(` Uploaded ${result.globalConfigFiles.length} global config file(s).`));
2864
+ }
2793
2865
  await saveState({
2794
2866
  lastFolderId: folderId,
2795
2867
  lastDeviceName: deviceName,
@@ -2821,16 +2893,16 @@ var init_map = __esm({
2821
2893
  });
2822
2894
 
2823
2895
  // 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";
2896
+ import { readFile as readFile13 } from "node:fs/promises";
2897
+ import { join as join16 } from "node:path";
2898
+ import { homedir as homedir10 } from "node:os";
2827
2899
  import { existsSync as existsSync12 } from "node:fs";
2828
2900
  import { readdir as readdir6 } from "node:fs/promises";
2829
2901
  async function readJsonSafe(path) {
2830
2902
  try {
2831
2903
  if (!existsSync12(path))
2832
2904
  return null;
2833
- const raw = await readFile12(path, "utf-8");
2905
+ const raw = await readFile13(path, "utf-8");
2834
2906
  return JSON.parse(raw);
2835
2907
  } catch {
2836
2908
  return null;
@@ -2890,52 +2962,52 @@ function parseFlatConfig(data, source) {
2890
2962
  return entries;
2891
2963
  }
2892
2964
  async function readAllMcpConfigs() {
2893
- const home = homedir9();
2965
+ const home = homedir10();
2894
2966
  const entries = [];
2895
- const userConfig = await readJsonSafe(join15(home, ".claude.json"));
2967
+ const userConfig = await readJsonSafe(join16(home, ".claude.json"));
2896
2968
  entries.push(...parseServers(userConfig, "global"));
2897
- const globalMcp = await readJsonSafe(join15(home, ".claude", "mcp.json"));
2969
+ const globalMcp = await readJsonSafe(join16(home, ".claude", "mcp.json"));
2898
2970
  entries.push(...parseServers(globalMcp, "global"));
2899
- const cwdMcp = await readJsonSafe(join15(process.cwd(), ".mcp.json"));
2971
+ const cwdMcp = await readJsonSafe(join16(process.cwd(), ".mcp.json"));
2900
2972
  entries.push(...parseServers(cwdMcp, "project"));
2901
- const pluginsBase = join15(home, ".claude", "plugins", "marketplaces");
2973
+ const pluginsBase = join16(home, ".claude", "plugins", "marketplaces");
2902
2974
  if (existsSync12(pluginsBase)) {
2903
2975
  try {
2904
2976
  const marketplaces = await readdir6(pluginsBase, { withFileTypes: true });
2905
2977
  for (const mp of marketplaces) {
2906
2978
  if (!mp.isDirectory())
2907
2979
  continue;
2908
- const extDir = join15(pluginsBase, mp.name, "external_plugins");
2980
+ const extDir = join16(pluginsBase, mp.name, "external_plugins");
2909
2981
  if (!existsSync12(extDir))
2910
2982
  continue;
2911
2983
  const plugins = await readdir6(extDir, { withFileTypes: true });
2912
2984
  for (const plugin of plugins) {
2913
2985
  if (!plugin.isDirectory())
2914
2986
  continue;
2915
- const pluginMcp = await readJsonSafe(join15(extDir, plugin.name, ".mcp.json"));
2987
+ const pluginMcp = await readJsonSafe(join16(extDir, plugin.name, ".mcp.json"));
2916
2988
  entries.push(...parseServers(pluginMcp, "plugin"));
2917
2989
  }
2918
2990
  }
2919
2991
  } catch {
2920
2992
  }
2921
2993
  }
2922
- const cacheBase = join15(home, ".claude", "plugins", "cache");
2994
+ const cacheBase = join16(home, ".claude", "plugins", "cache");
2923
2995
  if (existsSync12(cacheBase)) {
2924
2996
  try {
2925
2997
  const registries = await readdir6(cacheBase, { withFileTypes: true });
2926
2998
  for (const reg of registries) {
2927
2999
  if (!reg.isDirectory())
2928
3000
  continue;
2929
- const regDir = join15(cacheBase, reg.name);
3001
+ const regDir = join16(cacheBase, reg.name);
2930
3002
  const plugins = await readdir6(regDir, { withFileTypes: true });
2931
3003
  for (const plugin of plugins) {
2932
3004
  if (!plugin.isDirectory())
2933
3005
  continue;
2934
- const versionDirs = await readdir6(join15(regDir, plugin.name), { withFileTypes: true });
3006
+ const versionDirs = await readdir6(join16(regDir, plugin.name), { withFileTypes: true });
2935
3007
  for (const ver of versionDirs) {
2936
3008
  if (!ver.isDirectory())
2937
3009
  continue;
2938
- const mcpPath = join15(regDir, plugin.name, ver.name, ".mcp.json");
3010
+ const mcpPath = join16(regDir, plugin.name, ver.name, ".mcp.json");
2939
3011
  const flatData = await readJsonSafe(mcpPath);
2940
3012
  if (flatData) {
2941
3013
  entries.push(...parseFlatConfig(flatData, "plugin"));
@@ -3950,41 +4022,41 @@ init_map();
3950
4022
 
3951
4023
  // dist/commands/simulate.js
3952
4024
  init_dist();
3953
- import { join as join13 } from "node:path";
4025
+ import { join as join14 } from "node:path";
3954
4026
  import { existsSync as existsSync9 } from "node:fs";
3955
- import { homedir as homedir8 } from "node:os";
4027
+ import { homedir as homedir9 } from "node:os";
3956
4028
  import chalk13 from "chalk";
3957
4029
  async function simulateCommand(prompt) {
3958
4030
  const projectRoot = process.cwd();
3959
4031
  console.log(chalk13.blue(`Simulating prompt: "${prompt}"
3960
4032
  `));
3961
4033
  console.log(chalk13.dim("Files Claude would load:\n"));
3962
- const globalClaude = join13(homedir8(), ".claude", "CLAUDE.md");
4034
+ const globalClaude = join14(homedir9(), ".claude", "CLAUDE.md");
3963
4035
  if (existsSync9(globalClaude)) {
3964
4036
  console.log(chalk13.green(" \u2713 ~/.claude/CLAUDE.md (global)"));
3965
4037
  }
3966
4038
  for (const rootFile of ROOT_FILES) {
3967
- const fullPath = join13(projectRoot, rootFile);
4039
+ const fullPath = join14(projectRoot, rootFile);
3968
4040
  if (existsSync9(fullPath)) {
3969
4041
  console.log(chalk13.green(` \u2713 ${rootFile} (project root)`));
3970
4042
  }
3971
4043
  }
3972
4044
  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")
4045
+ join14(homedir9(), ".claude", "settings.json"),
4046
+ join14(homedir9(), ".claude", "settings.local.json"),
4047
+ join14(projectRoot, ".claude", "settings.json"),
4048
+ join14(projectRoot, ".claude", "settings.local.json")
3977
4049
  ];
3978
4050
  for (const sf of settingsFiles) {
3979
4051
  if (existsSync9(sf)) {
3980
- const display = sf.startsWith(homedir8()) ? sf.replace(homedir8(), "~") : sf.replace(projectRoot + "/", "");
4052
+ const display = sf.startsWith(homedir9()) ? sf.replace(homedir9(), "~") : sf.replace(projectRoot + "/", "");
3981
4053
  console.log(chalk13.green(` \u2713 ${display} (settings)`));
3982
4054
  }
3983
4055
  }
3984
4056
  const words = prompt.split(/\s+/);
3985
4057
  for (const word of words) {
3986
4058
  const cleaned = word.replace(/['"]/g, "");
3987
- const candidatePath = join13(projectRoot, cleaned);
4059
+ const candidatePath = join14(projectRoot, cleaned);
3988
4060
  if (existsSync9(candidatePath) && cleaned.includes("/")) {
3989
4061
  console.log(chalk13.cyan(` \u2192 ${cleaned} (referenced in prompt)`));
3990
4062
  }
@@ -3993,18 +4065,18 @@ async function simulateCommand(prompt) {
3993
4065
  }
3994
4066
 
3995
4067
  // dist/commands/print.js
3996
- import { join as join14 } from "node:path";
3997
- import { readFile as readFile10, writeFile as writeFile3 } from "node:fs/promises";
4068
+ import { join as join15 } from "node:path";
4069
+ import { readFile as readFile11, writeFile as writeFile3 } from "node:fs/promises";
3998
4070
  import { existsSync as existsSync10 } from "node:fs";
3999
4071
  import chalk14 from "chalk";
4000
4072
  async function printCommand(title) {
4001
4073
  const projectRoot = process.cwd();
4002
- const scanDataPath = join14(projectRoot, "output", "index.html");
4074
+ const scanDataPath = join15(projectRoot, "output", "index.html");
4003
4075
  if (!existsSync10(scanDataPath)) {
4004
4076
  console.error(chalk14.red("No scan data found. Run: md4ai scan"));
4005
4077
  process.exit(1);
4006
4078
  }
4007
- const html = await readFile10(scanDataPath, "utf-8");
4079
+ const html = await readFile11(scanDataPath, "utf-8");
4008
4080
  const match = html.match(/<script type="application\/json" id="scan-data">([\s\S]*?)<\/script>/);
4009
4081
  if (!match) {
4010
4082
  console.error(chalk14.red("Could not extract scan data from output/index.html"));
@@ -4012,7 +4084,7 @@ async function printCommand(title) {
4012
4084
  }
4013
4085
  const result = JSON.parse(match[1]);
4014
4086
  const printHtml = generatePrintHtml(result, title);
4015
- const outputPath = join14(projectRoot, "output", `print-${Date.now()}.html`);
4087
+ const outputPath = join15(projectRoot, "output", `print-${Date.now()}.html`);
4016
4088
  await writeFile3(outputPath, printHtml, "utf-8");
4017
4089
  console.log(chalk14.green(`Print-ready wall sheet: ${outputPath}`));
4018
4090
  }
@@ -4167,6 +4239,18 @@ Linking "${folder.name}" to this device...
4167
4239
  }
4168
4240
  console.log(chalk15.green(` Uploaded ${configFiles.length} config file(s).`));
4169
4241
  }
4242
+ if (result.globalConfigFiles.length > 0) {
4243
+ for (const file of result.globalConfigFiles) {
4244
+ await supabase.from("device_config_files").upsert({
4245
+ device_id: deviceId,
4246
+ file_path: file.filePath,
4247
+ content: file.content,
4248
+ size_bytes: file.sizeBytes,
4249
+ last_modified: file.lastModified
4250
+ }, { onConflict: "device_id,file_path" });
4251
+ }
4252
+ console.log(chalk15.green(` Uploaded ${result.globalConfigFiles.length} global config file(s).`));
4253
+ }
4170
4254
  await supabase.from("device_paths").update({ last_synced: (/* @__PURE__ */ new Date()).toISOString() }).eq("folder_id", folder.id).eq("device_name", deviceName);
4171
4255
  await saveState({
4172
4256
  lastFolderId: folder.id,
@@ -4182,7 +4266,7 @@ Linking "${folder.name}" to this device...
4182
4266
  }
4183
4267
 
4184
4268
  // dist/commands/import-bundle.js
4185
- import { readFile as readFile11, writeFile as writeFile4, mkdir as mkdir3, stat as fsStat } from "node:fs/promises";
4269
+ import { readFile as readFile12, writeFile as writeFile4, mkdir as mkdir3, stat as fsStat } from "node:fs/promises";
4186
4270
  import { dirname as dirname3, resolve as resolve7 } from "node:path";
4187
4271
  import { existsSync as existsSync11 } from "node:fs";
4188
4272
  import chalk16 from "chalk";
@@ -4199,7 +4283,7 @@ async function importBundleCommand(zipPath) {
4199
4283
  process.exit(1);
4200
4284
  }
4201
4285
  const JSZip = (await import("jszip")).default;
4202
- const zipData = await readFile11(zipPath);
4286
+ const zipData = await readFile12(zipPath);
4203
4287
  const zip = await JSZip.loadAsync(zipData);
4204
4288
  const manifestFile = zip.file("manifest.json");
4205
4289
  if (!manifestFile) {
@@ -4561,8 +4645,8 @@ async function fetchGitHubVersions(repo, signal) {
4561
4645
  init_mcp_watch();
4562
4646
 
4563
4647
  // 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";
4648
+ import { resolve as resolve8, join as join17, relative as relative4, dirname as dirname4 } from "node:path";
4649
+ import { readFile as readFile14, writeFile as writeFile5, mkdir as mkdir4 } from "node:fs/promises";
4566
4650
  import { existsSync as existsSync13 } from "node:fs";
4567
4651
  import chalk21 from "chalk";
4568
4652
  var SECRET_PATTERNS = [
@@ -4580,7 +4664,7 @@ function isLikelySecret(name) {
4580
4664
  async function discoverEnvFiles(projectRoot) {
4581
4665
  const apps = [];
4582
4666
  for (const envName of [".env", ".env.local", ".env.example"]) {
4583
- const envPath = join16(projectRoot, envName);
4667
+ const envPath = join17(projectRoot, envName);
4584
4668
  if (existsSync13(envPath)) {
4585
4669
  const vars = await extractVarNames(envPath);
4586
4670
  if (vars.length > 0) {
@@ -4591,11 +4675,11 @@ async function discoverEnvFiles(projectRoot) {
4591
4675
  }
4592
4676
  const subdirs = ["web", "cli", "api", "app", "server", "packages"];
4593
4677
  for (const sub of subdirs) {
4594
- const subDir = join16(projectRoot, sub);
4678
+ const subDir = join17(projectRoot, sub);
4595
4679
  if (!existsSync13(subDir))
4596
4680
  continue;
4597
4681
  for (const envName of [".env.local", ".env", ".env.example"]) {
4598
- const envPath = join16(subDir, envName);
4682
+ const envPath = join17(subDir, envName);
4599
4683
  if (existsSync13(envPath)) {
4600
4684
  const vars = await extractVarNames(envPath);
4601
4685
  if (vars.length > 0) {
@@ -4612,7 +4696,7 @@ async function discoverEnvFiles(projectRoot) {
4612
4696
  return apps;
4613
4697
  }
4614
4698
  async function extractVarNames(envPath) {
4615
- const content = await readFile13(envPath, "utf-8");
4699
+ const content = await readFile14(envPath, "utf-8");
4616
4700
  const vars = [];
4617
4701
  for (const line of content.split("\n")) {
4618
4702
  const trimmed = line.trim();
@@ -4657,7 +4741,7 @@ function generateManifest(apps) {
4657
4741
  }
4658
4742
  async function initManifestCommand() {
4659
4743
  const projectRoot = resolve8(process.cwd());
4660
- const manifestPath = join16(projectRoot, "docs", "reference", "env-manifest.md");
4744
+ const manifestPath = join17(projectRoot, "docs", "reference", "env-manifest.md");
4661
4745
  if (existsSync13(manifestPath)) {
4662
4746
  console.log(chalk21.yellow(`Manifest already exists: ${relative4(projectRoot, manifestPath)}`));
4663
4747
  console.log(chalk21.dim("Edit it directly to make changes."));
@@ -5046,9 +5130,9 @@ async function dopplerDisconnectCommand() {
5046
5130
  }
5047
5131
  const { dopplerToken: _, ...rest } = creds;
5048
5132
  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");
5133
+ const { join: join18 } = await import("node:path");
5134
+ const { homedir: homedir11 } = await import("node:os");
5135
+ const credPath = join18(homedir11(), ".md4ai", "credentials.json");
5052
5136
  await writeFile6(credPath, JSON.stringify(rest, null, 2), "utf-8");
5053
5137
  await chmod2(credPath, 384);
5054
5138
  try {
@@ -5134,7 +5218,7 @@ if (process.argv.length <= 2) {
5134
5218
  program.parseAsync().then(() => {
5135
5219
  const ran = program.args[0];
5136
5220
  const skipAutoCheck = ["update", "mcp-watch", "start"];
5137
- if (!skipAutoCheck.includes(ran)) {
5221
+ if (!skipAutoCheck.includes(ran) && !wasUpdateHandedOff()) {
5138
5222
  autoCheckForUpdate();
5139
5223
  }
5140
5224
  }).catch(async (err) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "md4ai",
3
- "version": "0.18.4",
3
+ "version": "0.19.1",
4
4
  "description": "CLI for MD4AI — scan Claude projects and sync to your dashboard",
5
5
  "type": "module",
6
6
  "bin": {