md4ai 0.14.1 → 0.16.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.
- package/dist/index.bundled.js +97 -17
- package/package.json +1 -1
package/dist/index.bundled.js
CHANGED
|
@@ -122,7 +122,7 @@ var CURRENT_VERSION;
|
|
|
122
122
|
var init_check_update = __esm({
|
|
123
123
|
"dist/check-update.js"() {
|
|
124
124
|
"use strict";
|
|
125
|
-
CURRENT_VERSION = true ? "0.
|
|
125
|
+
CURRENT_VERSION = true ? "0.16.0" : "0.0.0-dev";
|
|
126
126
|
}
|
|
127
127
|
});
|
|
128
128
|
|
|
@@ -1109,7 +1109,9 @@ var init_tooling_detector = __esm({
|
|
|
1109
1109
|
{ name: "pnpm", command: "pnpm", args: ["--version"], conditionFile: "pnpm-lock.yaml" },
|
|
1110
1110
|
{ name: "supabase-cli", command: "npx", args: ["supabase", "--version"] },
|
|
1111
1111
|
{ name: "vercel-cli", command: "npx", args: ["vercel", "--version"] },
|
|
1112
|
-
{ name: "claude-code", command: "claude", args: ["--version"] }
|
|
1112
|
+
{ name: "claude-code", command: "claude", args: ["--version"] },
|
|
1113
|
+
{ name: "gh", command: "gh", args: ["--version"] },
|
|
1114
|
+
{ name: "git", command: "git", args: ["--version"] }
|
|
1113
1115
|
];
|
|
1114
1116
|
}
|
|
1115
1117
|
});
|
|
@@ -1767,6 +1769,51 @@ async function discoverSkills(installPath) {
|
|
|
1767
1769
|
skills.sort((a, b) => a.name.localeCompare(b.name));
|
|
1768
1770
|
return skills;
|
|
1769
1771
|
}
|
|
1772
|
+
async function checkPluginLatestVersions(plugins) {
|
|
1773
|
+
const results = [];
|
|
1774
|
+
for (const plugin of plugins) {
|
|
1775
|
+
let latestVersion = null;
|
|
1776
|
+
if (plugin.homepageUrl && plugin.homepageUrl.includes("github.com") && !plugin.homepageUrl.includes("/tree/main/plugins/")) {
|
|
1777
|
+
try {
|
|
1778
|
+
const match = plugin.homepageUrl.match(/github\.com\/([^/]+\/[^/]+)/);
|
|
1779
|
+
if (match) {
|
|
1780
|
+
const ownerRepo = match[1];
|
|
1781
|
+
const controller = new AbortController();
|
|
1782
|
+
const timeout = setTimeout(() => controller.abort(), 3e3);
|
|
1783
|
+
let res = await fetch(`https://api.github.com/repos/${ownerRepo}/releases/latest`, {
|
|
1784
|
+
signal: controller.signal,
|
|
1785
|
+
headers: { Accept: "application/vnd.github.v3+json" }
|
|
1786
|
+
});
|
|
1787
|
+
clearTimeout(timeout);
|
|
1788
|
+
if (res.ok) {
|
|
1789
|
+
const data = await res.json();
|
|
1790
|
+
latestVersion = data.tag_name?.replace(/^v/, "") ?? null;
|
|
1791
|
+
} else {
|
|
1792
|
+
const controller2 = new AbortController();
|
|
1793
|
+
const timeout2 = setTimeout(() => controller2.abort(), 3e3);
|
|
1794
|
+
res = await fetch(`https://api.github.com/repos/${ownerRepo}/tags?per_page=1`, {
|
|
1795
|
+
signal: controller2.signal,
|
|
1796
|
+
headers: { Accept: "application/vnd.github.v3+json" }
|
|
1797
|
+
});
|
|
1798
|
+
clearTimeout(timeout2);
|
|
1799
|
+
if (res.ok) {
|
|
1800
|
+
const data = await res.json();
|
|
1801
|
+
latestVersion = data[0]?.name?.replace(/^v/, "") ?? null;
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
} catch {
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
results.push({
|
|
1809
|
+
pluginName: plugin.pluginName,
|
|
1810
|
+
installedVersion: plugin.version,
|
|
1811
|
+
latestVersion,
|
|
1812
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1813
|
+
});
|
|
1814
|
+
}
|
|
1815
|
+
return results;
|
|
1816
|
+
}
|
|
1770
1817
|
var init_marketplace_scanner = __esm({
|
|
1771
1818
|
"dist/scanner/marketplace-scanner.js"() {
|
|
1772
1819
|
"use strict";
|
|
@@ -2054,6 +2101,7 @@ async function scanProject(projectRoot, folderId) {
|
|
|
2054
2101
|
brokenRefs.sort((a, b) => a.depth - b.depth || a.from.localeCompare(b.from));
|
|
2055
2102
|
const scanData = JSON.stringify({ graph, orphans, brokenRefs, skills, staleFiles, toolings, envManifest, marketplacePlugins, doppler: doppler2 });
|
|
2056
2103
|
const dataHash = createHash("sha256").update(scanData).digest("hex");
|
|
2104
|
+
const pluginVersions = await checkPluginLatestVersions(marketplacePlugins);
|
|
2057
2105
|
return {
|
|
2058
2106
|
graph,
|
|
2059
2107
|
orphans,
|
|
@@ -2064,6 +2112,7 @@ async function scanProject(projectRoot, folderId) {
|
|
|
2064
2112
|
envManifest,
|
|
2065
2113
|
doppler: doppler2,
|
|
2066
2114
|
marketplacePlugins,
|
|
2115
|
+
pluginVersions,
|
|
2067
2116
|
scannedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2068
2117
|
dataHash
|
|
2069
2118
|
};
|
|
@@ -2288,12 +2337,14 @@ var init_html_generator = __esm({
|
|
|
2288
2337
|
});
|
|
2289
2338
|
|
|
2290
2339
|
// dist/commands/push-toolings.js
|
|
2291
|
-
async function pushToolings(supabase, folderId, toolings) {
|
|
2340
|
+
async function pushToolings(supabase, folderId, toolings, deviceId) {
|
|
2292
2341
|
if (!toolings.length)
|
|
2293
2342
|
return;
|
|
2294
2343
|
const { data: registry } = await supabase.from("tools_registry").select("id, name");
|
|
2295
2344
|
const registryMap = new Map((registry ?? []).map((r) => [r.name, r.id]));
|
|
2296
|
-
|
|
2345
|
+
const projectToolings = toolings.filter((t) => t.detection_source !== "cli");
|
|
2346
|
+
const deviceToolings = toolings.filter((t) => t.detection_source === "cli");
|
|
2347
|
+
for (const tooling of projectToolings) {
|
|
2297
2348
|
const toolId = registryMap.get(tooling.tool_name) ?? null;
|
|
2298
2349
|
await supabase.from("project_toolings").upsert({
|
|
2299
2350
|
folder_id: folderId,
|
|
@@ -2304,6 +2355,19 @@ async function pushToolings(supabase, folderId, toolings) {
|
|
|
2304
2355
|
detected_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
2305
2356
|
}, { onConflict: "folder_id,tool_name,detection_source" });
|
|
2306
2357
|
}
|
|
2358
|
+
if (deviceId && deviceToolings.length) {
|
|
2359
|
+
for (const tooling of deviceToolings) {
|
|
2360
|
+
const toolId = registryMap.get(tooling.tool_name) ?? null;
|
|
2361
|
+
await supabase.from("device_toolings").upsert({
|
|
2362
|
+
device_id: deviceId,
|
|
2363
|
+
tool_id: toolId,
|
|
2364
|
+
tool_name: tooling.tool_name,
|
|
2365
|
+
detected_version: tooling.detected_version,
|
|
2366
|
+
detection_source: tooling.detection_source,
|
|
2367
|
+
detected_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
2368
|
+
}, { onConflict: "device_id,tool_name,detection_source" });
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2307
2371
|
}
|
|
2308
2372
|
var init_push_toolings = __esm({
|
|
2309
2373
|
"dist/commands/push-toolings.js"() {
|
|
@@ -2569,12 +2633,13 @@ ${proposedFiles.length} file(s) proposed for deletion:
|
|
|
2569
2633
|
env_manifest_json: result.envManifest,
|
|
2570
2634
|
doppler_json: result.doppler,
|
|
2571
2635
|
marketplace_plugins_json: result.marketplacePlugins,
|
|
2636
|
+
plugin_versions_json: result.pluginVersions,
|
|
2572
2637
|
data_hash: result.dataHash,
|
|
2573
2638
|
scanned_at: result.scannedAt,
|
|
2574
2639
|
cli_version: CURRENT_VERSION
|
|
2575
2640
|
}, { onConflict: "folder_id,device_id" });
|
|
2576
2641
|
}
|
|
2577
|
-
await pushToolings(supabase, folder_id, result.toolings);
|
|
2642
|
+
await pushToolings(supabase, folder_id, result.toolings, deviceId);
|
|
2578
2643
|
const manifestForHealth = result.envManifest ?? storedManifest;
|
|
2579
2644
|
if (manifestForHealth) {
|
|
2580
2645
|
await pushHealthResults(supabase, folder_id, manifestForHealth, deviceId);
|
|
@@ -2689,12 +2754,13 @@ ${proposedFiles.length} file(s) proposed for deletion:
|
|
|
2689
2754
|
env_manifest_json: result.envManifest,
|
|
2690
2755
|
doppler_json: result.doppler,
|
|
2691
2756
|
marketplace_plugins_json: result.marketplacePlugins,
|
|
2757
|
+
plugin_versions_json: result.pluginVersions,
|
|
2692
2758
|
data_hash: result.dataHash,
|
|
2693
2759
|
scanned_at: result.scannedAt,
|
|
2694
2760
|
cli_version: CURRENT_VERSION
|
|
2695
2761
|
}, { onConflict: "folder_id,device_id" });
|
|
2696
2762
|
}
|
|
2697
|
-
await pushToolings(sb, folderId, result.toolings);
|
|
2763
|
+
await pushToolings(sb, folderId, result.toolings, inlineDeviceId);
|
|
2698
2764
|
if (result.envManifest) {
|
|
2699
2765
|
await pushHealthResults(sb, folderId, result.envManifest, inlineDeviceId);
|
|
2700
2766
|
}
|
|
@@ -2802,12 +2868,13 @@ async function syncCommand(options) {
|
|
|
2802
2868
|
stale_files_json: result.staleFiles,
|
|
2803
2869
|
broken_refs_json: result.brokenRefs,
|
|
2804
2870
|
env_manifest_json: result.envManifest,
|
|
2871
|
+
plugin_versions_json: result.pluginVersions,
|
|
2805
2872
|
data_hash: result.dataHash,
|
|
2806
2873
|
scanned_at: result.scannedAt,
|
|
2807
2874
|
cli_version: CURRENT_VERSION
|
|
2808
2875
|
}, { onConflict: "folder_id,device_id" });
|
|
2809
2876
|
}
|
|
2810
|
-
await pushToolings(supabase, device.folder_id, result.toolings);
|
|
2877
|
+
await pushToolings(supabase, device.folder_id, result.toolings, allDeviceId);
|
|
2811
2878
|
await supabase.from("device_paths").update({ last_synced: (/* @__PURE__ */ new Date()).toISOString() }).eq("folder_id", device.folder_id).eq("device_name", device.device_name);
|
|
2812
2879
|
console.log(chalk15.green(` Done: ${device.device_name}`));
|
|
2813
2880
|
} catch (err) {
|
|
@@ -2865,12 +2932,13 @@ async function syncCommand(options) {
|
|
|
2865
2932
|
skills_table_json: result.skills,
|
|
2866
2933
|
stale_files_json: result.staleFiles,
|
|
2867
2934
|
broken_refs_json: result.brokenRefs,
|
|
2935
|
+
plugin_versions_json: result.pluginVersions,
|
|
2868
2936
|
data_hash: result.dataHash,
|
|
2869
2937
|
scanned_at: result.scannedAt,
|
|
2870
2938
|
cli_version: CURRENT_VERSION
|
|
2871
2939
|
}, { onConflict: "folder_id,device_id" });
|
|
2872
2940
|
}
|
|
2873
|
-
await pushToolings(supabase, device.folder_id, result.toolings);
|
|
2941
|
+
await pushToolings(supabase, device.folder_id, result.toolings, singleDeviceId);
|
|
2874
2942
|
await supabase.from("device_paths").update({ last_synced: (/* @__PURE__ */ new Date()).toISOString() }).eq("folder_id", device.folder_id).eq("device_name", device.device_name);
|
|
2875
2943
|
await saveState({ lastSyncAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
2876
2944
|
console.log(chalk15.green("Synced."));
|
|
@@ -3595,7 +3663,7 @@ async function checkPendingRescans(supabase, deviceId, deviceName) {
|
|
|
3595
3663
|
data_hash: result.dataHash,
|
|
3596
3664
|
rescan_requested_at: null
|
|
3597
3665
|
}).eq("id", folder.id);
|
|
3598
|
-
await pushToolings(supabase, folder.id, result.toolings);
|
|
3666
|
+
await pushToolings(supabase, folder.id, result.toolings, deviceId);
|
|
3599
3667
|
await supabase.from("device_paths").update({ last_synced: (/* @__PURE__ */ new Date()).toISOString() }).eq("folder_id", folder.id).eq("device_name", deviceName);
|
|
3600
3668
|
} catch {
|
|
3601
3669
|
await supabase.from("claude_folders").update({ rescan_requested_at: null }).eq("id", folder.id);
|
|
@@ -4082,11 +4150,12 @@ Linking "${folder.name}" to this device...
|
|
|
4082
4150
|
env_manifest_json: result.envManifest,
|
|
4083
4151
|
doppler_json: result.doppler,
|
|
4084
4152
|
marketplace_plugins_json: result.marketplacePlugins,
|
|
4153
|
+
plugin_versions_json: result.pluginVersions,
|
|
4085
4154
|
data_hash: result.dataHash,
|
|
4086
4155
|
scanned_at: result.scannedAt,
|
|
4087
4156
|
cli_version: CURRENT_VERSION
|
|
4088
4157
|
}, { onConflict: "folder_id,device_id" });
|
|
4089
|
-
await pushToolings(supabase, folder.id, result.toolings);
|
|
4158
|
+
await pushToolings(supabase, folder.id, result.toolings, deviceId);
|
|
4090
4159
|
const graphPaths = result.graph.nodes.map((n) => n.filePath);
|
|
4091
4160
|
const configFiles = await readClaudeConfigFiles(cwd, graphPaths);
|
|
4092
4161
|
if (configFiles.length > 0) {
|
|
@@ -5037,18 +5106,29 @@ initSentry();
|
|
|
5037
5106
|
if (process.argv.length <= 2) {
|
|
5038
5107
|
void startCommand();
|
|
5039
5108
|
} else {
|
|
5040
|
-
program.
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5109
|
+
program.parseAsync().then(() => {
|
|
5110
|
+
const ran = program.args[0];
|
|
5111
|
+
const skipAutoCheck = ["update", "check-update", "mcp-watch", "start"];
|
|
5112
|
+
if (!skipAutoCheck.includes(ran)) {
|
|
5113
|
+
autoCheckForUpdate();
|
|
5114
|
+
}
|
|
5115
|
+
}).catch(async (err) => {
|
|
5116
|
+
captureException2(err);
|
|
5117
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
5118
|
+
console.error(`\x1B[31mError: ${msg}\x1B[0m`);
|
|
5119
|
+
await flushSentry();
|
|
5120
|
+
process.exit(1);
|
|
5121
|
+
});
|
|
5046
5122
|
}
|
|
5047
5123
|
process.on("uncaughtException", async (err) => {
|
|
5048
5124
|
captureException2(err);
|
|
5049
5125
|
await flushSentry();
|
|
5050
5126
|
process.exit(1);
|
|
5051
5127
|
});
|
|
5052
|
-
process.on("unhandledRejection", (reason) => {
|
|
5128
|
+
process.on("unhandledRejection", async (reason) => {
|
|
5053
5129
|
captureException2(reason);
|
|
5130
|
+
const msg = reason instanceof Error ? reason.message : String(reason);
|
|
5131
|
+
console.error(`\x1B[31mError: ${msg}\x1B[0m`);
|
|
5132
|
+
await flushSentry();
|
|
5133
|
+
process.exit(1);
|
|
5054
5134
|
});
|