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.
- package/dist/index.bundled.js +140 -61
- package/package.json +1 -1
package/dist/index.bundled.js
CHANGED
|
@@ -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.
|
|
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:
|
|
1834
|
-
const { homedir:
|
|
1835
|
-
const credPath =
|
|
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
|
|
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
|
|
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 =
|
|
2195
|
+
const claudeDir = join13(projectRoot, ".claude");
|
|
2154
2196
|
if (existsSync7(claudeDir)) {
|
|
2155
2197
|
await walkDir(claudeDir, projectRoot, files);
|
|
2156
2198
|
}
|
|
2157
|
-
if (existsSync7(
|
|
2199
|
+
if (existsSync7(join13(projectRoot, "CLAUDE.md"))) {
|
|
2158
2200
|
files.push("CLAUDE.md");
|
|
2159
2201
|
}
|
|
2160
|
-
if (existsSync7(
|
|
2202
|
+
if (existsSync7(join13(projectRoot, "skills.md"))) {
|
|
2161
2203
|
files.push("skills.md");
|
|
2162
2204
|
}
|
|
2163
|
-
const plansDir =
|
|
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 =
|
|
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 =
|
|
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("~",
|
|
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:
|
|
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
|
|
2226
|
-
const fileStat = await
|
|
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
|
|
2280
|
+
return join13(homedir8(), ".claude", "projects", projectHash, "memory", relPath.replace(".claude/memory/", ""));
|
|
2239
2281
|
}
|
|
2240
|
-
return
|
|
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
|
|
2825
|
-
import { join as
|
|
2826
|
-
import { homedir as
|
|
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
|
|
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 =
|
|
2960
|
+
const home = homedir10();
|
|
2894
2961
|
const entries = [];
|
|
2895
|
-
const userConfig = await readJsonSafe(
|
|
2962
|
+
const userConfig = await readJsonSafe(join16(home, ".claude.json"));
|
|
2896
2963
|
entries.push(...parseServers(userConfig, "global"));
|
|
2897
|
-
const globalMcp = await readJsonSafe(
|
|
2964
|
+
const globalMcp = await readJsonSafe(join16(home, ".claude", "mcp.json"));
|
|
2898
2965
|
entries.push(...parseServers(globalMcp, "global"));
|
|
2899
|
-
const cwdMcp = await readJsonSafe(
|
|
2966
|
+
const cwdMcp = await readJsonSafe(join16(process.cwd(), ".mcp.json"));
|
|
2900
2967
|
entries.push(...parseServers(cwdMcp, "project"));
|
|
2901
|
-
const pluginsBase =
|
|
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 =
|
|
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(
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
|
4020
|
+
import { join as join14 } from "node:path";
|
|
3954
4021
|
import { existsSync as existsSync9 } from "node:fs";
|
|
3955
|
-
import { homedir as
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
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(
|
|
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 =
|
|
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
|
|
3997
|
-
import { readFile as
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
4565
|
-
import { readFile as
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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:
|
|
5050
|
-
const { homedir:
|
|
5051
|
-
const credPath =
|
|
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 {
|