md4ai 0.18.0 → 0.18.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.
@@ -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.0" : "0.0.0-dev";
115
+ CURRENT_VERSION = true ? "0.18.1" : "0.0.0-dev";
116
116
  }
117
117
  });
118
118
 
@@ -624,7 +624,7 @@ import { execFileSync as execFileSync2 } from "node:child_process";
624
624
  import { statSync } from "node:fs";
625
625
  function getGitLastModified(filePath, cwd) {
626
626
  try {
627
- const result = execFileSync2("git", ["log", "-1", "--format=%cI", "--", filePath], { cwd, encoding: "utf-8", timeout: 5e3 }).trim();
627
+ const result = execFileSync2("git", ["log", "-1", "--format=%cI", "--", filePath], { cwd, encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
628
628
  return result || null;
629
629
  } catch {
630
630
  try {
@@ -636,7 +636,7 @@ function getGitLastModified(filePath, cwd) {
636
636
  }
637
637
  function getGitCreationDate(filePath, cwd) {
638
638
  try {
639
- const result = execFileSync2("git", ["log", "--diff-filter=A", "--format=%cI", "--", filePath], { cwd, encoding: "utf-8", timeout: 5e3 }).trim();
639
+ const result = execFileSync2("git", ["log", "--diff-filter=A", "--format=%cI", "--", filePath], { cwd, encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
640
640
  return result || null;
641
641
  } catch {
642
642
  try {
@@ -2077,7 +2077,7 @@ __export(scanner_exports, {
2077
2077
  scanProject: () => scanProject
2078
2078
  });
2079
2079
  import { readdir as readdir5 } from "node:fs/promises";
2080
- import { join as join12, relative as relative3 } from "node:path";
2080
+ import { join as join12, relative as relative3, resolve as resolve4 } from "node:path";
2081
2081
  import { existsSync as existsSync7 } from "node:fs";
2082
2082
  import { homedir as homedir7 } from "node:os";
2083
2083
  import { createHash } from "node:crypto";
@@ -2087,7 +2087,7 @@ async function scanProject(projectRoot, folderId) {
2087
2087
  const allRefs = [];
2088
2088
  const allBrokenRefs = [];
2089
2089
  for (const file of allFiles) {
2090
- const fullPath = file.startsWith("/") ? file : join12(projectRoot, file);
2090
+ const fullPath = file.startsWith("/") ? file : resolveFilePath(file, projectRoot);
2091
2091
  try {
2092
2092
  const { refs, brokenRefs: brokenRefs2 } = await parseFileReferences(fullPath, projectRoot);
2093
2093
  allRefs.push(...refs);
@@ -2162,6 +2162,17 @@ async function discoverFiles(projectRoot) {
2162
2162
  if (existsSync7(plansDir)) {
2163
2163
  await walkDir(plansDir, projectRoot, files);
2164
2164
  }
2165
+ const absRoot = resolve4(projectRoot);
2166
+ const projectHash = absRoot.replace(/\//g, "-");
2167
+ const memoryDir = join12(homedir7(), ".claude", "projects", projectHash, "memory");
2168
+ if (existsSync7(memoryDir)) {
2169
+ const memEntries = await readdir5(memoryDir, { withFileTypes: true });
2170
+ for (const entry of memEntries) {
2171
+ if (entry.isFile() && entry.name.endsWith(".md")) {
2172
+ files.push(`.claude/memory/${entry.name}`);
2173
+ }
2174
+ }
2175
+ }
2165
2176
  return [...new Set(files)];
2166
2177
  }
2167
2178
  async function walkDir(dir, projectRoot, files) {
@@ -2205,7 +2216,7 @@ async function readClaudeConfigFiles(projectRoot, graphFilePaths) {
2205
2216
  if (relPath.startsWith("~") || relPath.startsWith("/"))
2206
2217
  continue;
2207
2218
  seen.add(relPath);
2208
- const fullPath = join12(projectRoot, relPath);
2219
+ const fullPath = resolveFilePath(relPath, projectRoot);
2209
2220
  if (!existsSync15(fullPath))
2210
2221
  continue;
2211
2222
  try {
@@ -2218,11 +2229,19 @@ async function readClaudeConfigFiles(projectRoot, graphFilePaths) {
2218
2229
  }
2219
2230
  return files;
2220
2231
  }
2232
+ function resolveFilePath(relPath, projectRoot) {
2233
+ if (relPath.startsWith(".claude/memory/")) {
2234
+ const absRoot = resolve4(projectRoot);
2235
+ const projectHash = absRoot.replace(/\//g, "-");
2236
+ return join12(homedir7(), ".claude", "projects", projectHash, "memory", relPath.replace(".claude/memory/", ""));
2237
+ }
2238
+ return join12(projectRoot, relPath);
2239
+ }
2221
2240
  function detectStaleFiles(allFiles, projectRoot) {
2222
2241
  const stale = [];
2223
2242
  const now = Date.now();
2224
2243
  for (const file of allFiles) {
2225
- const fullPath = join12(projectRoot, file);
2244
+ const fullPath = resolveFilePath(file, projectRoot);
2226
2245
  const lastMod = getGitLastModified(fullPath, projectRoot);
2227
2246
  if (lastMod) {
2228
2247
  const days = Math.floor((now - new Date(lastMod).getTime()) / (1e3 * 60 * 60 * 24));
@@ -2511,7 +2530,7 @@ var map_exports = {};
2511
2530
  __export(map_exports, {
2512
2531
  mapCommand: () => mapCommand
2513
2532
  });
2514
- import { resolve as resolve4, basename as basename2 } from "node:path";
2533
+ import { resolve as resolve5, basename as basename2 } from "node:path";
2515
2534
  import { writeFile as writeFile2, mkdir as mkdir2 } from "node:fs/promises";
2516
2535
  import { existsSync as existsSync8 } from "node:fs";
2517
2536
  import chalk12 from "chalk";
@@ -2523,7 +2542,7 @@ async function mapCommand(path, options) {
2523
2542
  const shouldContinue = await promptUpdateIfAvailable(args);
2524
2543
  if (!shouldContinue)
2525
2544
  return;
2526
- const projectRoot = resolve4(path ?? process.cwd());
2545
+ const projectRoot = resolve5(path ?? process.cwd());
2527
2546
  if (!existsSync8(projectRoot)) {
2528
2547
  console.error(chalk12.red(`Path not found: ${projectRoot}`));
2529
2548
  process.exit(1);
@@ -2561,11 +2580,11 @@ async function mapCommand(path, options) {
2561
2580
  console.log(chalk12.red(` ... and ${result.brokenRefs.length - 5} more`));
2562
2581
  }
2563
2582
  }
2564
- const outputDir = resolve4(projectRoot, "output");
2583
+ const outputDir = resolve5(projectRoot, "output");
2565
2584
  if (!existsSync8(outputDir)) {
2566
2585
  await mkdir2(outputDir, { recursive: true });
2567
2586
  }
2568
- const htmlPath = resolve4(outputDir, "index.html");
2587
+ const htmlPath = resolve5(outputDir, "index.html");
2569
2588
  const html = generateOfflineHtml(result, projectRoot);
2570
2589
  await writeFile2(htmlPath, html, "utf-8");
2571
2590
  console.log(chalk12.green(`
@@ -2591,9 +2610,9 @@ ${proposedFiles.length} file(s) proposed for deletion:
2591
2610
  value: f
2592
2611
  }))
2593
2612
  });
2594
- const resolvedRoot = resolve4(projectRoot);
2613
+ const resolvedRoot = resolve5(projectRoot);
2595
2614
  for (const file of toDelete) {
2596
- const fullPath = resolve4(projectRoot, file.file_path);
2615
+ const fullPath = resolve5(projectRoot, file.file_path);
2597
2616
  if (!fullPath.startsWith(resolvedRoot + "/")) {
2598
2617
  console.error(chalk12.red(` Blocked path traversal: ${file.file_path}`));
2599
2618
  continue;
@@ -3566,11 +3585,11 @@ var sync_exports = {};
3566
3585
  __export(sync_exports, {
3567
3586
  syncCommand: () => syncCommand
3568
3587
  });
3569
- import { resolve as resolve8 } from "node:path";
3588
+ import { resolve as resolve9 } from "node:path";
3570
3589
  import { existsSync as existsSync14 } from "node:fs";
3571
3590
  import chalk22 from "chalk";
3572
3591
  function isValidProjectPath(p) {
3573
- const resolved = resolve8(p);
3592
+ const resolved = resolve9(p);
3574
3593
  return resolved.startsWith("/") && !resolved.includes("..") && existsSync14(resolved);
3575
3594
  }
3576
3595
  async function syncCommand(options) {
@@ -4056,14 +4075,14 @@ init_scanner();
4056
4075
  init_push_toolings();
4057
4076
  init_device_utils();
4058
4077
  init_check_update();
4059
- import { resolve as resolve5 } from "node:path";
4078
+ import { resolve as resolve6 } from "node:path";
4060
4079
  import chalk15 from "chalk";
4061
4080
  async function linkCommand(projectId) {
4062
4081
  const shouldContinue = await promptUpdateIfAvailable(["link", projectId]);
4063
4082
  if (!shouldContinue)
4064
4083
  return;
4065
4084
  const { supabase, userId } = await getAuthenticatedClient();
4066
- const cwd = resolve5(process.cwd());
4085
+ const cwd = resolve6(process.cwd());
4067
4086
  const deviceName = detectDeviceName();
4068
4087
  const osType = detectOs();
4069
4088
  const { data: folder, error: folderErr } = await supabase.from("claude_folders").select("id, name").eq("id", projectId).single();
@@ -4162,7 +4181,7 @@ Linking "${folder.name}" to this device...
4162
4181
 
4163
4182
  // dist/commands/import-bundle.js
4164
4183
  import { readFile as readFile11, writeFile as writeFile4, mkdir as mkdir3, stat as fsStat } from "node:fs/promises";
4165
- import { dirname as dirname3, resolve as resolve6 } from "node:path";
4184
+ import { dirname as dirname3, resolve as resolve7 } from "node:path";
4166
4185
  import { existsSync as existsSync11 } from "node:fs";
4167
4186
  import chalk16 from "chalk";
4168
4187
  import { confirm as confirm3, input as input6 } from "@inquirer/prompts";
@@ -4219,9 +4238,9 @@ Files to extract:`));
4219
4238
  console.log(chalk16.yellow("Cancelled."));
4220
4239
  return;
4221
4240
  }
4222
- const resolvedTarget = resolve6(targetDir);
4241
+ const resolvedTarget = resolve7(targetDir);
4223
4242
  for (const file of files) {
4224
- const fullPath = resolve6(targetDir, file.filePath);
4243
+ const fullPath = resolve7(targetDir, file.filePath);
4225
4244
  if (!fullPath.startsWith(resolvedTarget + "/") && fullPath !== resolvedTarget) {
4226
4245
  console.error(chalk16.red(` Blocked path traversal: ${file.filePath}`));
4227
4246
  continue;
@@ -4540,7 +4559,7 @@ async function fetchGitHubVersions(repo, signal) {
4540
4559
  init_mcp_watch();
4541
4560
 
4542
4561
  // dist/commands/init-manifest.js
4543
- import { resolve as resolve7, join as join16, relative as relative4, dirname as dirname4 } from "node:path";
4562
+ import { resolve as resolve8, join as join16, relative as relative4, dirname as dirname4 } from "node:path";
4544
4563
  import { readFile as readFile13, writeFile as writeFile5, mkdir as mkdir4 } from "node:fs/promises";
4545
4564
  import { existsSync as existsSync13 } from "node:fs";
4546
4565
  import chalk21 from "chalk";
@@ -4635,7 +4654,7 @@ function generateManifest(apps) {
4635
4654
  return lines.join("\n");
4636
4655
  }
4637
4656
  async function initManifestCommand() {
4638
- const projectRoot = resolve7(process.cwd());
4657
+ const projectRoot = resolve8(process.cwd());
4639
4658
  const manifestPath = join16(projectRoot, "docs", "reference", "env-manifest.md");
4640
4659
  if (existsSync13(manifestPath)) {
4641
4660
  console.log(chalk21.yellow(`Manifest already exists: ${relative4(projectRoot, manifestPath)}`));
@@ -4844,7 +4863,7 @@ init_check_update();
4844
4863
  init_map();
4845
4864
  init_mcp_watch();
4846
4865
  import chalk24 from "chalk";
4847
- import { resolve as resolve9 } from "node:path";
4866
+ import { resolve as resolve10 } from "node:path";
4848
4867
  async function fetchLatestVersion2() {
4849
4868
  try {
4850
4869
  const controller = new AbortController();
@@ -4873,7 +4892,7 @@ function isNewer3(a, b) {
4873
4892
  return false;
4874
4893
  }
4875
4894
  async function startCommand() {
4876
- const projectRoot = resolve9(process.cwd());
4895
+ const projectRoot = resolve10(process.cwd());
4877
4896
  console.log("");
4878
4897
  console.log(chalk24.bold.cyan(` MD4AI v${CURRENT_VERSION}`));
4879
4898
  console.log(chalk24.dim(` ${projectRoot}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "md4ai",
3
- "version": "0.18.0",
3
+ "version": "0.18.1",
4
4
  "description": "CLI for MD4AI — scan Claude projects and sync to your dashboard",
5
5
  "type": "module",
6
6
  "bin": {