@massu/core 2.1.0 → 2.3.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/CHANGELOG.md +43 -0
- package/dist/cli.js +321 -261
- package/package.json +3 -2
package/dist/cli.js
CHANGED
|
@@ -70,13 +70,13 @@ var init_node_floor = __esm({
|
|
|
70
70
|
"src/lib/node-floor.ts"() {
|
|
71
71
|
"use strict";
|
|
72
72
|
MIN_NODE_MAJOR = 22;
|
|
73
|
-
MIN_NODE_MINOR =
|
|
73
|
+
MIN_NODE_MINOR = 16;
|
|
74
74
|
}
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
// src/credentials.ts
|
|
78
78
|
import { homedir as homedir2 } from "os";
|
|
79
|
-
import { resolve
|
|
79
|
+
import { resolve } from "path";
|
|
80
80
|
import {
|
|
81
81
|
existsSync as existsSync2,
|
|
82
82
|
readFileSync,
|
|
@@ -86,10 +86,10 @@ import {
|
|
|
86
86
|
chmodSync
|
|
87
87
|
} from "fs";
|
|
88
88
|
function credentialsDir(home = homedir2()) {
|
|
89
|
-
return
|
|
89
|
+
return resolve(home, ".massu");
|
|
90
90
|
}
|
|
91
91
|
function credentialsPath(home = homedir2()) {
|
|
92
|
-
return
|
|
92
|
+
return resolve(credentialsDir(home), "credentials");
|
|
93
93
|
}
|
|
94
94
|
function readUserCredentials(home = homedir2()) {
|
|
95
95
|
try {
|
|
@@ -718,7 +718,7 @@ var init_db_driver = __esm({
|
|
|
718
718
|
DEFAULT_DB_ENGINE = "node-sqlite";
|
|
719
719
|
DB_ENGINE_ENV = "MASSU_DB_ENGINE";
|
|
720
720
|
_nodeCtor = null;
|
|
721
|
-
NODE_SQLITE_REMEDY = "Node's built-in node:sqlite failed to open the database. Ensure Node >= 22.
|
|
721
|
+
NODE_SQLITE_REMEDY = "Node's built-in node:sqlite failed to open the database. Ensure Node >= 22.16.0 (`node --version`) and that this Node build includes SQLite, then restart your MCP client / Claude Code.";
|
|
722
722
|
}
|
|
723
723
|
});
|
|
724
724
|
|
|
@@ -907,7 +907,7 @@ __export(config_exports, {
|
|
|
907
907
|
getResolvedPaths: () => getResolvedPaths,
|
|
908
908
|
resetConfig: () => resetConfig
|
|
909
909
|
});
|
|
910
|
-
import { resolve as
|
|
910
|
+
import { resolve as resolve2, dirname as dirname3 } from "path";
|
|
911
911
|
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
|
|
912
912
|
import { homedir as homedir3 } from "os";
|
|
913
913
|
import { parse as parseYaml } from "yaml";
|
|
@@ -916,7 +916,7 @@ function findProjectRoot() {
|
|
|
916
916
|
const cwd = process.cwd();
|
|
917
917
|
let dir = cwd;
|
|
918
918
|
while (true) {
|
|
919
|
-
if (existsSync5(
|
|
919
|
+
if (existsSync5(resolve2(dir, "massu.config.yaml"))) {
|
|
920
920
|
return dir;
|
|
921
921
|
}
|
|
922
922
|
const parent = dirname3(dir);
|
|
@@ -925,10 +925,10 @@ function findProjectRoot() {
|
|
|
925
925
|
}
|
|
926
926
|
dir = cwd;
|
|
927
927
|
while (true) {
|
|
928
|
-
if (existsSync5(
|
|
928
|
+
if (existsSync5(resolve2(dir, "package.json"))) {
|
|
929
929
|
return dir;
|
|
930
930
|
}
|
|
931
|
-
if (existsSync5(
|
|
931
|
+
if (existsSync5(resolve2(dir, ".git"))) {
|
|
932
932
|
return dir;
|
|
933
933
|
}
|
|
934
934
|
const parent = dirname3(dir);
|
|
@@ -946,7 +946,7 @@ function getProjectRoot() {
|
|
|
946
946
|
function getConfig() {
|
|
947
947
|
if (_config) return _config;
|
|
948
948
|
const root = getProjectRoot();
|
|
949
|
-
const configPath =
|
|
949
|
+
const configPath = resolve2(root, "massu.config.yaml");
|
|
950
950
|
let rawYaml = {};
|
|
951
951
|
if (existsSync5(configPath)) {
|
|
952
952
|
const content = readFileSync4(configPath, "utf-8");
|
|
@@ -966,7 +966,7 @@ Hint: run \`massu config refresh\` to regenerate a valid config or fix the liste
|
|
|
966
966
|
);
|
|
967
967
|
}
|
|
968
968
|
const parsed = result.data;
|
|
969
|
-
const projectRoot = parsed.project.root === "auto" || !parsed.project.root ? root :
|
|
969
|
+
const projectRoot = parsed.project.root === "auto" || !parsed.project.root ? root : resolve2(root, parsed.project.root);
|
|
970
970
|
const fw = parsed.framework;
|
|
971
971
|
let router = fw.router;
|
|
972
972
|
let orm = fw.orm;
|
|
@@ -1054,35 +1054,35 @@ function getResolvedPaths() {
|
|
|
1054
1054
|
const root = getProjectRoot();
|
|
1055
1055
|
const claudeDirName = config.conventions?.claudeDirName ?? ".claude";
|
|
1056
1056
|
return {
|
|
1057
|
-
codegraphDbPath:
|
|
1058
|
-
dataDbPath:
|
|
1059
|
-
prismaSchemaPath:
|
|
1060
|
-
rootRouterPath:
|
|
1061
|
-
routersDir:
|
|
1062
|
-
srcDir:
|
|
1057
|
+
codegraphDbPath: resolve2(root, ".codegraph/codegraph.db"),
|
|
1058
|
+
dataDbPath: resolve2(root, ".massu/data.db"),
|
|
1059
|
+
prismaSchemaPath: resolve2(root, config.paths.schema ?? "prisma/schema.prisma"),
|
|
1060
|
+
rootRouterPath: resolve2(root, config.paths.routerRoot ?? "src/server/api/root.ts"),
|
|
1061
|
+
routersDir: resolve2(root, config.paths.routers ?? "src/server/api/routers"),
|
|
1062
|
+
srcDir: resolve2(root, config.paths.source),
|
|
1063
1063
|
pathAlias: Object.fromEntries(
|
|
1064
1064
|
Object.entries(config.paths.aliases).map(([alias, target]) => [
|
|
1065
1065
|
alias,
|
|
1066
|
-
|
|
1066
|
+
resolve2(root, target)
|
|
1067
1067
|
])
|
|
1068
1068
|
),
|
|
1069
1069
|
extensions: [".ts", ".tsx", ".js", ".jsx"],
|
|
1070
1070
|
indexFiles: ["index.ts", "index.tsx", "index.js", "index.jsx"],
|
|
1071
|
-
patternsDir:
|
|
1072
|
-
claudeMdPath:
|
|
1073
|
-
docsMapPath:
|
|
1074
|
-
helpSitePath:
|
|
1075
|
-
memoryDbPath:
|
|
1076
|
-
knowledgeDbPath:
|
|
1077
|
-
plansDir:
|
|
1078
|
-
docsDir:
|
|
1079
|
-
claudeDir:
|
|
1080
|
-
memoryDir:
|
|
1081
|
-
sessionStatePath:
|
|
1082
|
-
sessionArchivePath:
|
|
1083
|
-
mcpJsonPath:
|
|
1084
|
-
settingsPath:
|
|
1085
|
-
settingsLocalPath:
|
|
1071
|
+
patternsDir: resolve2(root, claudeDirName, "patterns"),
|
|
1072
|
+
claudeMdPath: resolve2(root, claudeDirName, "CLAUDE.md"),
|
|
1073
|
+
docsMapPath: resolve2(root, ".massu/docs-map.json"),
|
|
1074
|
+
helpSitePath: resolve2(root, "../" + config.project.name + "-help"),
|
|
1075
|
+
memoryDbPath: resolve2(root, ".massu/memory.db"),
|
|
1076
|
+
knowledgeDbPath: resolve2(root, ".massu/knowledge.db"),
|
|
1077
|
+
plansDir: resolve2(root, "docs/plans"),
|
|
1078
|
+
docsDir: resolve2(root, "docs"),
|
|
1079
|
+
claudeDir: resolve2(root, claudeDirName),
|
|
1080
|
+
memoryDir: resolve2(homedir3(), claudeDirName, "projects", encodeMemoryDirName(root), "memory"),
|
|
1081
|
+
sessionStatePath: resolve2(root, config.conventions?.sessionStatePath ?? `${claudeDirName}/session-state/CURRENT.md`),
|
|
1082
|
+
sessionArchivePath: resolve2(root, config.conventions?.sessionArchivePath ?? `${claudeDirName}/session-state/archive`),
|
|
1083
|
+
mcpJsonPath: resolve2(root, ".mcp.json"),
|
|
1084
|
+
settingsPath: resolve2(root, claudeDirName, "settings.json"),
|
|
1085
|
+
settingsLocalPath: resolve2(root, claudeDirName, "settings.local.json")
|
|
1086
1086
|
};
|
|
1087
1087
|
}
|
|
1088
1088
|
function resetConfig() {
|
|
@@ -1539,10 +1539,10 @@ var init_memory_vector = __esm({
|
|
|
1539
1539
|
|
|
1540
1540
|
// src/db-backup.ts
|
|
1541
1541
|
import { existsSync as existsSync6, mkdirSync as mkdirSync4, readdirSync as readdirSync2, statSync as statSync2, unlinkSync, copyFileSync, rmSync as rmSync4 } from "fs";
|
|
1542
|
-
import { resolve as
|
|
1542
|
+
import { resolve as resolve3, join as join3, basename, dirname as dirname4 } from "path";
|
|
1543
1543
|
import { homedir as homedir4 } from "os";
|
|
1544
1544
|
function dbBackupsRoot(home = homedir4()) {
|
|
1545
|
-
return
|
|
1545
|
+
return resolve3(home, ".massu", "db-backups");
|
|
1546
1546
|
}
|
|
1547
1547
|
function projectBackupDir(projectRoot, home = homedir4()) {
|
|
1548
1548
|
const slug = basename(projectRoot).replace(/[^A-Za-z0-9._-]/g, "_") || "project";
|
|
@@ -4667,7 +4667,7 @@ import {
|
|
|
4667
4667
|
rmSync as rmSync5,
|
|
4668
4668
|
writeSync
|
|
4669
4669
|
} from "fs";
|
|
4670
|
-
import { dirname as dirname8, resolve as
|
|
4670
|
+
import { dirname as dirname8, resolve as resolve5 } from "path";
|
|
4671
4671
|
function atomicWriteFile(targetPath, content, mode = 420) {
|
|
4672
4672
|
const tmpPath = `${targetPath}.${process.pid}.tmp`;
|
|
4673
4673
|
try {
|
|
@@ -4706,10 +4706,10 @@ function readSettingsAtPath(absolutePath) {
|
|
|
4706
4706
|
}
|
|
4707
4707
|
}
|
|
4708
4708
|
function readSettingsLocal(claudeDir) {
|
|
4709
|
-
return readSettingsAtPath(
|
|
4709
|
+
return readSettingsAtPath(resolve5(claudeDir, "settings.local.json"));
|
|
4710
4710
|
}
|
|
4711
4711
|
function writeSettingsLocalAtomic(claudeDir, settings) {
|
|
4712
|
-
const targetPath =
|
|
4712
|
+
const targetPath = resolve5(claudeDir, "settings.local.json");
|
|
4713
4713
|
const dir = dirname8(targetPath);
|
|
4714
4714
|
if (!existsSync11(dir)) {
|
|
4715
4715
|
mkdirSync7(dir, { recursive: true });
|
|
@@ -4959,14 +4959,14 @@ import {
|
|
|
4959
4959
|
readdirSync as readdirSync4,
|
|
4960
4960
|
statSync as statSync3
|
|
4961
4961
|
} from "fs";
|
|
4962
|
-
import { resolve as
|
|
4962
|
+
import { resolve as resolve6, dirname as dirname9, join as join8 } from "path";
|
|
4963
4963
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4964
4964
|
import { createHash as createHash3 } from "crypto";
|
|
4965
4965
|
function dirHoldsAssets(dir) {
|
|
4966
4966
|
if (!existsSync12(dir)) return false;
|
|
4967
4967
|
try {
|
|
4968
4968
|
return readdirSync4(dir).some(
|
|
4969
|
-
(e2) => e2.endsWith(".md") || statSync3(
|
|
4969
|
+
(e2) => e2.endsWith(".md") || statSync3(resolve6(dir, e2)).isDirectory()
|
|
4970
4970
|
);
|
|
4971
4971
|
} catch {
|
|
4972
4972
|
return false;
|
|
@@ -4976,11 +4976,11 @@ function resolveAssetDir(assetName) {
|
|
|
4976
4976
|
const cwd = process.cwd();
|
|
4977
4977
|
const candidates = [
|
|
4978
4978
|
// 1. npm-installed: node_modules/@massu/core/{assetName}
|
|
4979
|
-
|
|
4979
|
+
resolve6(cwd, "node_modules/@massu/core", assetName),
|
|
4980
4980
|
// 2. Relative to compiled dist/cli.js → ../{assetName}
|
|
4981
|
-
|
|
4981
|
+
resolve6(__dirname, "..", assetName),
|
|
4982
4982
|
// 3. Relative to source src/commands/ → ../../{assetName}
|
|
4983
|
-
|
|
4983
|
+
resolve6(__dirname, "../..", assetName)
|
|
4984
4984
|
];
|
|
4985
4985
|
for (const c2 of candidates) {
|
|
4986
4986
|
if (dirHoldsAssets(c2)) return c2;
|
|
@@ -5011,7 +5011,7 @@ function hashContent(content) {
|
|
|
5011
5011
|
return createHash3("sha256").update(content, "utf-8").digest("hex");
|
|
5012
5012
|
}
|
|
5013
5013
|
function loadManifest(claudeDir) {
|
|
5014
|
-
const path =
|
|
5014
|
+
const path = resolve6(claudeDir, MANIFEST_RELPATH);
|
|
5015
5015
|
if (!existsSync12(path)) {
|
|
5016
5016
|
return emptyManifest();
|
|
5017
5017
|
}
|
|
@@ -5027,11 +5027,11 @@ function loadManifest(claudeDir) {
|
|
|
5027
5027
|
}
|
|
5028
5028
|
}
|
|
5029
5029
|
function saveManifest(claudeDir, manifest) {
|
|
5030
|
-
const dir =
|
|
5030
|
+
const dir = resolve6(claudeDir, ".massu");
|
|
5031
5031
|
if (!existsSync12(dir)) {
|
|
5032
5032
|
mkdirSync8(dir, { recursive: true });
|
|
5033
5033
|
}
|
|
5034
|
-
const finalPath =
|
|
5034
|
+
const finalPath = resolve6(dir, "install-manifest.json");
|
|
5035
5035
|
manifest.generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5036
5036
|
atomicWriteFile(finalPath, JSON.stringify(manifest, null, 2));
|
|
5037
5037
|
}
|
|
@@ -5093,17 +5093,17 @@ function pickVariant(baseName, sourceDir, framework) {
|
|
|
5093
5093
|
}
|
|
5094
5094
|
for (const cand of candidates) {
|
|
5095
5095
|
if (cand.subFramework) {
|
|
5096
|
-
const subPath =
|
|
5096
|
+
const subPath = resolve6(sourceDir, `${baseName}.${cand.lang}-${cand.subFramework}.md`);
|
|
5097
5097
|
if (existsSync12(subPath)) {
|
|
5098
5098
|
return { kind: "hit", suffix: `.${cand.lang}-${cand.subFramework}` };
|
|
5099
5099
|
}
|
|
5100
5100
|
}
|
|
5101
|
-
const langPath =
|
|
5101
|
+
const langPath = resolve6(sourceDir, `${baseName}.${cand.lang}.md`);
|
|
5102
5102
|
if (existsSync12(langPath)) {
|
|
5103
5103
|
return { kind: "hit", suffix: `.${cand.lang}` };
|
|
5104
5104
|
}
|
|
5105
5105
|
}
|
|
5106
|
-
const defaultPath =
|
|
5106
|
+
const defaultPath = resolve6(sourceDir, `${baseName}.md`);
|
|
5107
5107
|
if (existsSync12(defaultPath)) {
|
|
5108
5108
|
return { kind: "hit", suffix: "" };
|
|
5109
5109
|
}
|
|
@@ -5125,10 +5125,10 @@ function syncDirectory(sourceDir, targetDir, framework, manifest, manifestKeyPre
|
|
|
5125
5125
|
}
|
|
5126
5126
|
const entries = readdirSync4(sourceDir);
|
|
5127
5127
|
for (const entry of entries) {
|
|
5128
|
-
const sourcePath =
|
|
5128
|
+
const sourcePath = resolve6(sourceDir, entry);
|
|
5129
5129
|
const entryStat = statSync3(sourcePath);
|
|
5130
5130
|
if (entryStat.isDirectory()) {
|
|
5131
|
-
const subTargetDir =
|
|
5131
|
+
const subTargetDir = resolve6(targetDir, entry);
|
|
5132
5132
|
const subPrefix = manifestKeyPrefix === "" ? entry : `${manifestKeyPrefix}/${entry}`;
|
|
5133
5133
|
const subStats = syncDirectory(
|
|
5134
5134
|
sourcePath,
|
|
@@ -5157,12 +5157,12 @@ function syncDirectory(sourceDir, targetDir, framework, manifest, manifestKeyPre
|
|
|
5157
5157
|
const suffix = choice.kind === "hit" ? choice.suffix : "";
|
|
5158
5158
|
sourceFilename = suffix === "" ? `${baseName}.md` : `${baseName}${suffix}.md`;
|
|
5159
5159
|
}
|
|
5160
|
-
const resolvedSourcePath =
|
|
5160
|
+
const resolvedSourcePath = resolve6(sourceDir, sourceFilename);
|
|
5161
5161
|
if (!existsSync12(resolvedSourcePath)) {
|
|
5162
5162
|
continue;
|
|
5163
5163
|
}
|
|
5164
5164
|
const targetFilename = topLevel ? `${baseName}.md` : entry;
|
|
5165
|
-
const targetPath =
|
|
5165
|
+
const targetPath = resolve6(targetDir, targetFilename);
|
|
5166
5166
|
const rawContent = readFileSync8(resolvedSourcePath, "utf-8");
|
|
5167
5167
|
let sourceContent;
|
|
5168
5168
|
try {
|
|
@@ -5266,8 +5266,8 @@ function buildTemplateVars() {
|
|
|
5266
5266
|
}
|
|
5267
5267
|
function installCommands(projectRoot, opts = {}) {
|
|
5268
5268
|
const claudeDirName = getConfig().conventions?.claudeDirName ?? ".claude";
|
|
5269
|
-
const claudeDir =
|
|
5270
|
-
const targetDir =
|
|
5269
|
+
const claudeDir = resolve6(projectRoot, claudeDirName);
|
|
5270
|
+
const targetDir = resolve6(claudeDir, "commands");
|
|
5271
5271
|
if (!existsSync12(targetDir)) {
|
|
5272
5272
|
mkdirSync8(targetDir, { recursive: true });
|
|
5273
5273
|
}
|
|
@@ -5298,7 +5298,7 @@ function installCommands(projectRoot, opts = {}) {
|
|
|
5298
5298
|
}
|
|
5299
5299
|
function installAll(projectRoot, opts = {}) {
|
|
5300
5300
|
const claudeDirName = getConfig().conventions?.claudeDirName ?? ".claude";
|
|
5301
|
-
const claudeDir =
|
|
5301
|
+
const claudeDir = resolve6(projectRoot, claudeDirName);
|
|
5302
5302
|
const assets = {};
|
|
5303
5303
|
let totalInstalled = 0;
|
|
5304
5304
|
let totalUpdated = 0;
|
|
@@ -5311,7 +5311,7 @@ function installAll(projectRoot, opts = {}) {
|
|
|
5311
5311
|
for (const assetType of ASSET_TYPES) {
|
|
5312
5312
|
const sourceDir = resolveAssetDir(assetType.name);
|
|
5313
5313
|
if (!sourceDir) continue;
|
|
5314
|
-
const targetDir =
|
|
5314
|
+
const targetDir = resolve6(claudeDir, assetType.targetSubdir);
|
|
5315
5315
|
const stats = syncDirectory(
|
|
5316
5316
|
sourceDir,
|
|
5317
5317
|
targetDir,
|
|
@@ -6376,21 +6376,21 @@ import {
|
|
|
6376
6376
|
fsyncSync as fsyncSync3,
|
|
6377
6377
|
closeSync as closeSync3,
|
|
6378
6378
|
existsSync as existsSync14,
|
|
6379
|
-
realpathSync,
|
|
6379
|
+
realpathSync as realpathSync2,
|
|
6380
6380
|
unlinkSync as unlinkSync2,
|
|
6381
6381
|
accessSync as accessSync2,
|
|
6382
6382
|
statSync as statSync5,
|
|
6383
6383
|
chmodSync as chmodSync3,
|
|
6384
6384
|
constants
|
|
6385
6385
|
} from "fs";
|
|
6386
|
-
import { dirname as dirname10, resolve as
|
|
6386
|
+
import { dirname as dirname10, resolve as resolve7, relative as relative3, isAbsolute, basename as basename3, sep } from "path";
|
|
6387
6387
|
import { createHash as createHash4 } from "crypto";
|
|
6388
6388
|
function assertContainedIn(rootDir, candidate, opts = {}) {
|
|
6389
6389
|
if (candidate.includes("\0")) {
|
|
6390
6390
|
throw new PathEscapeError("path contains a NUL byte");
|
|
6391
6391
|
}
|
|
6392
|
-
const root =
|
|
6393
|
-
const abs =
|
|
6392
|
+
const root = resolve7(rootDir);
|
|
6393
|
+
const abs = resolve7(root, candidate);
|
|
6394
6394
|
if (!opts.allowNested) {
|
|
6395
6395
|
const rel = relative3(root, abs);
|
|
6396
6396
|
if (rel.includes(sep)) {
|
|
@@ -6409,11 +6409,11 @@ function assertContainedIn(rootDir, candidate, opts = {}) {
|
|
|
6409
6409
|
}
|
|
6410
6410
|
function isContainedIn(rootDir, candidate, opts = {}) {
|
|
6411
6411
|
if (candidate.includes("\0")) return false;
|
|
6412
|
-
const root =
|
|
6413
|
-
const abs =
|
|
6412
|
+
const root = resolve7(rootDir);
|
|
6413
|
+
const abs = resolve7(root, candidate);
|
|
6414
6414
|
const rel = relative3(root, abs);
|
|
6415
6415
|
if (rel === "" && !opts.allowRoot) return false;
|
|
6416
|
-
if (rel.startsWith("..") ||
|
|
6416
|
+
if (rel.startsWith("..") || isAbsolute(rel)) return false;
|
|
6417
6417
|
let probe = abs;
|
|
6418
6418
|
while (!existsSync14(probe) && probe.length > 1) {
|
|
6419
6419
|
const parent = dirname10(probe);
|
|
@@ -6423,18 +6423,18 @@ function isContainedIn(rootDir, candidate, opts = {}) {
|
|
|
6423
6423
|
let realRoot;
|
|
6424
6424
|
let realProbe;
|
|
6425
6425
|
try {
|
|
6426
|
-
realRoot =
|
|
6427
|
-
realProbe =
|
|
6426
|
+
realRoot = realpathSync2(root);
|
|
6427
|
+
realProbe = realpathSync2(probe);
|
|
6428
6428
|
} catch {
|
|
6429
6429
|
return true;
|
|
6430
6430
|
}
|
|
6431
6431
|
const realRel = relative3(realRoot, realProbe);
|
|
6432
6432
|
if (realRel === "") return true;
|
|
6433
|
-
return !realRel.startsWith("..") && !
|
|
6433
|
+
return !realRel.startsWith("..") && !isAbsolute(realRel);
|
|
6434
6434
|
}
|
|
6435
6435
|
function atomicWriteFileSync(destPath, contents) {
|
|
6436
6436
|
const dir = dirname10(destPath);
|
|
6437
|
-
const tmp =
|
|
6437
|
+
const tmp = resolve7(dir, `.${basename3(destPath)}.massu-tmp-${process.pid}`);
|
|
6438
6438
|
let destMode;
|
|
6439
6439
|
if (existsSync14(destPath)) {
|
|
6440
6440
|
accessSync2(destPath, constants.W_OK);
|
|
@@ -9964,7 +9964,7 @@ var require_pattern = __commonJS({
|
|
|
9964
9964
|
const absolute = [];
|
|
9965
9965
|
const relative15 = [];
|
|
9966
9966
|
for (const pattern of patterns) {
|
|
9967
|
-
if (
|
|
9967
|
+
if (isAbsolute5(pattern)) {
|
|
9968
9968
|
absolute.push(pattern);
|
|
9969
9969
|
} else {
|
|
9970
9970
|
relative15.push(pattern);
|
|
@@ -9973,10 +9973,10 @@ var require_pattern = __commonJS({
|
|
|
9973
9973
|
return [absolute, relative15];
|
|
9974
9974
|
}
|
|
9975
9975
|
exports.partitionAbsoluteAndRelative = partitionAbsoluteAndRelative;
|
|
9976
|
-
function
|
|
9976
|
+
function isAbsolute5(pattern) {
|
|
9977
9977
|
return path.isAbsolute(pattern);
|
|
9978
9978
|
}
|
|
9979
|
-
exports.isAbsolute =
|
|
9979
|
+
exports.isAbsolute = isAbsolute5;
|
|
9980
9980
|
}
|
|
9981
9981
|
});
|
|
9982
9982
|
|
|
@@ -11060,41 +11060,41 @@ var require_queue = __commonJS({
|
|
|
11060
11060
|
queue.drained = drained;
|
|
11061
11061
|
return queue;
|
|
11062
11062
|
function push(value) {
|
|
11063
|
-
var p19 = new Promise(function(
|
|
11063
|
+
var p19 = new Promise(function(resolve45, reject) {
|
|
11064
11064
|
pushCb(value, function(err, result) {
|
|
11065
11065
|
if (err) {
|
|
11066
11066
|
reject(err);
|
|
11067
11067
|
return;
|
|
11068
11068
|
}
|
|
11069
|
-
|
|
11069
|
+
resolve45(result);
|
|
11070
11070
|
});
|
|
11071
11071
|
});
|
|
11072
11072
|
p19.catch(noop);
|
|
11073
11073
|
return p19;
|
|
11074
11074
|
}
|
|
11075
11075
|
function unshift(value) {
|
|
11076
|
-
var p19 = new Promise(function(
|
|
11076
|
+
var p19 = new Promise(function(resolve45, reject) {
|
|
11077
11077
|
unshiftCb(value, function(err, result) {
|
|
11078
11078
|
if (err) {
|
|
11079
11079
|
reject(err);
|
|
11080
11080
|
return;
|
|
11081
11081
|
}
|
|
11082
|
-
|
|
11082
|
+
resolve45(result);
|
|
11083
11083
|
});
|
|
11084
11084
|
});
|
|
11085
11085
|
p19.catch(noop);
|
|
11086
11086
|
return p19;
|
|
11087
11087
|
}
|
|
11088
11088
|
function drained() {
|
|
11089
|
-
var p19 = new Promise(function(
|
|
11089
|
+
var p19 = new Promise(function(resolve45) {
|
|
11090
11090
|
process.nextTick(function() {
|
|
11091
11091
|
if (queue.idle()) {
|
|
11092
|
-
|
|
11092
|
+
resolve45();
|
|
11093
11093
|
} else {
|
|
11094
11094
|
var previousDrain = queue.drain;
|
|
11095
11095
|
queue.drain = function() {
|
|
11096
11096
|
if (typeof previousDrain === "function") previousDrain();
|
|
11097
|
-
|
|
11097
|
+
resolve45();
|
|
11098
11098
|
queue.drain = previousDrain;
|
|
11099
11099
|
};
|
|
11100
11100
|
}
|
|
@@ -11580,9 +11580,9 @@ var require_stream3 = __commonJS({
|
|
|
11580
11580
|
});
|
|
11581
11581
|
}
|
|
11582
11582
|
_getStat(filepath) {
|
|
11583
|
-
return new Promise((
|
|
11583
|
+
return new Promise((resolve45, reject) => {
|
|
11584
11584
|
this._stat(filepath, this._fsStatSettings, (error, stats) => {
|
|
11585
|
-
return error === null ?
|
|
11585
|
+
return error === null ? resolve45(stats) : reject(error);
|
|
11586
11586
|
});
|
|
11587
11587
|
});
|
|
11588
11588
|
}
|
|
@@ -11606,10 +11606,10 @@ var require_async5 = __commonJS({
|
|
|
11606
11606
|
this._readerStream = new stream_1.default(this._settings);
|
|
11607
11607
|
}
|
|
11608
11608
|
dynamic(root, options) {
|
|
11609
|
-
return new Promise((
|
|
11609
|
+
return new Promise((resolve45, reject) => {
|
|
11610
11610
|
this._walkAsync(root, options, (error, entries) => {
|
|
11611
11611
|
if (error === null) {
|
|
11612
|
-
|
|
11612
|
+
resolve45(entries);
|
|
11613
11613
|
} else {
|
|
11614
11614
|
reject(error);
|
|
11615
11615
|
}
|
|
@@ -11619,10 +11619,10 @@ var require_async5 = __commonJS({
|
|
|
11619
11619
|
async static(patterns, options) {
|
|
11620
11620
|
const entries = [];
|
|
11621
11621
|
const stream = this._readerStream.static(patterns, options);
|
|
11622
|
-
return new Promise((
|
|
11622
|
+
return new Promise((resolve45, reject) => {
|
|
11623
11623
|
stream.once("error", reject);
|
|
11624
11624
|
stream.on("data", (entry) => entries.push(entry));
|
|
11625
|
-
stream.once("end", () =>
|
|
11625
|
+
stream.once("end", () => resolve45(entries));
|
|
11626
11626
|
});
|
|
11627
11627
|
}
|
|
11628
11628
|
};
|
|
@@ -12924,7 +12924,7 @@ var init_domain_inferrer = __esm({
|
|
|
12924
12924
|
|
|
12925
12925
|
// src/detect/regex-fallback.ts
|
|
12926
12926
|
import { existsSync as existsSync17, readdirSync as readdirSync8, readFileSync as readFileSync11, statSync as statSync7 } from "fs";
|
|
12927
|
-
import { resolve as
|
|
12927
|
+
import { resolve as resolve8, join as join12, basename as basename4 } from "path";
|
|
12928
12928
|
function introspectPython(detection, projectRoot) {
|
|
12929
12929
|
const sourceDir = resolveSourceDir(detection, "python", projectRoot);
|
|
12930
12930
|
if (!sourceDir) return null;
|
|
@@ -13090,7 +13090,7 @@ function resolveSourceDir(detection, lang, projectRoot) {
|
|
|
13090
13090
|
const list = info?.source_dirs ?? [];
|
|
13091
13091
|
if (list.length > 0) {
|
|
13092
13092
|
const first = list[0];
|
|
13093
|
-
const abs =
|
|
13093
|
+
const abs = resolve8(projectRoot, first);
|
|
13094
13094
|
return existsSync17(abs) ? abs : null;
|
|
13095
13095
|
}
|
|
13096
13096
|
return existsSync17(projectRoot) ? projectRoot : null;
|
|
@@ -15979,7 +15979,7 @@ __export(init_exports, {
|
|
|
15979
15979
|
writeConfigAtomic: () => writeConfigAtomic
|
|
15980
15980
|
});
|
|
15981
15981
|
import { closeSync as closeSync4, existsSync as existsSync19, fsyncSync as fsyncSync4, openSync as openSync4, readFileSync as readFileSync15, writeFileSync as writeFileSync5, writeSync as writeSync2, mkdirSync as mkdirSync10, readdirSync as readdirSync12, renameSync as renameSync4, rmSync as rmSync6, statSync as statSync10, chmodSync as chmodSync5 } from "fs";
|
|
15982
|
-
import { resolve as
|
|
15982
|
+
import { resolve as resolve9, basename as basename6, dirname as dirname12 } from "path";
|
|
15983
15983
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
15984
15984
|
import { homedir as homedir7 } from "os";
|
|
15985
15985
|
import { stringify as yamlStringify, parse as yamlParse } from "yaml";
|
|
@@ -15990,7 +15990,7 @@ function detectFramework(projectRoot) {
|
|
|
15990
15990
|
orm: "none",
|
|
15991
15991
|
ui: "none"
|
|
15992
15992
|
};
|
|
15993
|
-
const pkgPath =
|
|
15993
|
+
const pkgPath = resolve9(projectRoot, "package.json");
|
|
15994
15994
|
if (!existsSync19(pkgPath)) return result;
|
|
15995
15995
|
try {
|
|
15996
15996
|
const pkg = JSON.parse(readFileSync15(pkgPath, "utf-8"));
|
|
@@ -16027,7 +16027,7 @@ function detectPython(projectRoot) {
|
|
|
16027
16027
|
alembicDir: null
|
|
16028
16028
|
};
|
|
16029
16029
|
const markers = ["pyproject.toml", "setup.py", "requirements.txt", "Pipfile"];
|
|
16030
|
-
const hasMarker = markers.some((m3) => existsSync19(
|
|
16030
|
+
const hasMarker = markers.some((m3) => existsSync19(resolve9(projectRoot, m3)));
|
|
16031
16031
|
if (!hasMarker) return result;
|
|
16032
16032
|
result.detected = true;
|
|
16033
16033
|
const depFiles = [
|
|
@@ -16037,7 +16037,7 @@ function detectPython(projectRoot) {
|
|
|
16037
16037
|
{ file: "Pipfile" }
|
|
16038
16038
|
];
|
|
16039
16039
|
for (const { file } of depFiles) {
|
|
16040
|
-
const filePath =
|
|
16040
|
+
const filePath = resolve9(projectRoot, file);
|
|
16041
16041
|
if (existsSync19(filePath)) {
|
|
16042
16042
|
try {
|
|
16043
16043
|
const content = readFileSync15(filePath, "utf-8").toLowerCase();
|
|
@@ -16047,19 +16047,19 @@ function detectPython(projectRoot) {
|
|
|
16047
16047
|
}
|
|
16048
16048
|
}
|
|
16049
16049
|
}
|
|
16050
|
-
if (existsSync19(
|
|
16050
|
+
if (existsSync19(resolve9(projectRoot, "alembic.ini"))) {
|
|
16051
16051
|
result.hasAlembic = true;
|
|
16052
|
-
if (existsSync19(
|
|
16052
|
+
if (existsSync19(resolve9(projectRoot, "alembic"))) {
|
|
16053
16053
|
result.alembicDir = "alembic";
|
|
16054
16054
|
}
|
|
16055
|
-
} else if (existsSync19(
|
|
16055
|
+
} else if (existsSync19(resolve9(projectRoot, "alembic"))) {
|
|
16056
16056
|
result.hasAlembic = true;
|
|
16057
16057
|
result.alembicDir = "alembic";
|
|
16058
16058
|
}
|
|
16059
16059
|
const candidateRoots = ["app", "src", "backend", "api"];
|
|
16060
16060
|
for (const candidate of candidateRoots) {
|
|
16061
|
-
const candidatePath =
|
|
16062
|
-
if (existsSync19(candidatePath) && existsSync19(
|
|
16061
|
+
const candidatePath = resolve9(projectRoot, candidate);
|
|
16062
|
+
if (existsSync19(candidatePath) && existsSync19(resolve9(candidatePath, "__init__.py"))) {
|
|
16063
16063
|
result.root = candidate;
|
|
16064
16064
|
break;
|
|
16065
16065
|
}
|
|
@@ -16083,7 +16083,7 @@ function generateConfig(projectRoot, framework) {
|
|
|
16083
16083
|
console.warn(
|
|
16084
16084
|
"[@massu/core] generateConfig() is deprecated since 1.2.1 \u2014 use buildConfigFromDetection instead. It cannot produce valid configs for monorepos."
|
|
16085
16085
|
);
|
|
16086
|
-
const configPath =
|
|
16086
|
+
const configPath = resolve9(projectRoot, "massu.config.yaml");
|
|
16087
16087
|
if (existsSync19(configPath)) {
|
|
16088
16088
|
return false;
|
|
16089
16089
|
}
|
|
@@ -16195,10 +16195,10 @@ function buildConfigFromDetection(opts) {
|
|
|
16195
16195
|
pathsSource = monorepoCommonRoot(detection.monorepo.packages);
|
|
16196
16196
|
}
|
|
16197
16197
|
}
|
|
16198
|
-
if (pathsSource === "src" && !existsSync19(
|
|
16198
|
+
if (pathsSource === "src" && !existsSync19(resolve9(projectRoot, "src"))) {
|
|
16199
16199
|
const fallbacks = ["app", "pages", "."];
|
|
16200
16200
|
for (const fallback of fallbacks) {
|
|
16201
|
-
if (fallback === "." || existsSync19(
|
|
16201
|
+
if (fallback === "." || existsSync19(resolve9(projectRoot, fallback))) {
|
|
16202
16202
|
pathsSource = fallback;
|
|
16203
16203
|
break;
|
|
16204
16204
|
}
|
|
@@ -16282,7 +16282,7 @@ function buildConfigFromDetection(opts) {
|
|
|
16282
16282
|
};
|
|
16283
16283
|
if (pyFw?.framework) pythonBlock.framework = pyFw.framework;
|
|
16284
16284
|
if (pyFw?.orm) pythonBlock.orm = pyFw.orm;
|
|
16285
|
-
if (existsSync19(
|
|
16285
|
+
if (existsSync19(resolve9(projectRoot, "alembic.ini")) || existsSync19(resolve9(projectRoot, "alembic"))) {
|
|
16286
16286
|
pythonBlock.alembic_dir = "alembic";
|
|
16287
16287
|
}
|
|
16288
16288
|
config.python = pythonBlock;
|
|
@@ -16306,7 +16306,7 @@ function applyVariantTemplate(config, templatesDir) {
|
|
|
16306
16306
|
}
|
|
16307
16307
|
}
|
|
16308
16308
|
if (templateId === null) return config;
|
|
16309
|
-
const templatePath =
|
|
16309
|
+
const templatePath = resolve9(templatesDir, templateId, "massu.config.yaml");
|
|
16310
16310
|
if (!existsSync19(templatePath)) return config;
|
|
16311
16311
|
let template;
|
|
16312
16312
|
try {
|
|
@@ -16431,7 +16431,7 @@ function validateWrittenConfig(configPath, projectRoot, checkPaths = true) {
|
|
|
16431
16431
|
if (checkPaths) {
|
|
16432
16432
|
const src = cfg.paths.source;
|
|
16433
16433
|
if (src && src !== ".") {
|
|
16434
|
-
const srcAbs =
|
|
16434
|
+
const srcAbs = resolve9(projectRoot, src);
|
|
16435
16435
|
if (!existsSync19(srcAbs)) {
|
|
16436
16436
|
return `paths.source '${src}' does not exist on disk`;
|
|
16437
16437
|
}
|
|
@@ -16442,7 +16442,7 @@ function validateWrittenConfig(configPath, projectRoot, checkPaths = true) {
|
|
|
16442
16442
|
if (!Array.isArray(rawDirs)) continue;
|
|
16443
16443
|
for (const d2 of rawDirs) {
|
|
16444
16444
|
if (typeof d2 !== "string" || d2 === ".") continue;
|
|
16445
|
-
const abs =
|
|
16445
|
+
const abs = resolve9(projectRoot, d2);
|
|
16446
16446
|
if (!existsSync19(abs)) {
|
|
16447
16447
|
return `framework.languages.${lang}.source_dirs '${d2}' does not exist on disk`;
|
|
16448
16448
|
}
|
|
@@ -16452,7 +16452,7 @@ function validateWrittenConfig(configPath, projectRoot, checkPaths = true) {
|
|
|
16452
16452
|
if (Array.isArray(mRoots)) {
|
|
16453
16453
|
for (const r2 of mRoots) {
|
|
16454
16454
|
if (typeof r2 !== "string" || r2 === ".") continue;
|
|
16455
|
-
if (!existsSync19(
|
|
16455
|
+
if (!existsSync19(resolve9(projectRoot, r2))) {
|
|
16456
16456
|
return `paths.monorepo_roots '${r2}' does not exist on disk`;
|
|
16457
16457
|
}
|
|
16458
16458
|
}
|
|
@@ -16484,18 +16484,18 @@ function resolveTemplatesDir() {
|
|
|
16484
16484
|
const cwd = process.cwd();
|
|
16485
16485
|
const candidates = [
|
|
16486
16486
|
// Project-local install: `<project>/node_modules/@massu/core/templates`.
|
|
16487
|
-
|
|
16487
|
+
resolve9(cwd, "node_modules/@massu/core/templates"),
|
|
16488
16488
|
// Bundled cli.js layout: cli.js sits at `<package>/dist/cli.js`, so
|
|
16489
16489
|
// templates live one level up at `<package>/templates`. (Plan 1.5.1
|
|
16490
16490
|
// bug discovery: pre-existing layout assumed `dist/commands/init.js`
|
|
16491
16491
|
// depth which never matched the bundled cli, so resolveTemplatesDir
|
|
16492
16492
|
// returned null in production for both `--template` mode AND the
|
|
16493
16493
|
// applyVariantTemplate path.)
|
|
16494
|
-
|
|
16494
|
+
resolve9(__dirname2, "../templates"),
|
|
16495
16495
|
// Legacy nested layouts retained as fallbacks (in case a future
|
|
16496
16496
|
// build moves cli.js back into a subdirectory).
|
|
16497
|
-
|
|
16498
|
-
|
|
16497
|
+
resolve9(__dirname2, "../../templates"),
|
|
16498
|
+
resolve9(__dirname2, "../../../templates")
|
|
16499
16499
|
];
|
|
16500
16500
|
for (const c2 of candidates) {
|
|
16501
16501
|
if (existsSync19(c2)) return c2;
|
|
@@ -16507,7 +16507,7 @@ function copyTemplateConfig(templateName, targetPath, projectName) {
|
|
|
16507
16507
|
if (!templatesDir) {
|
|
16508
16508
|
return { success: false, error: `Templates directory not found (looked in node_modules and dist/src)` };
|
|
16509
16509
|
}
|
|
16510
|
-
const srcPath =
|
|
16510
|
+
const srcPath = resolve9(templatesDir, templateName, "massu.config.yaml");
|
|
16511
16511
|
if (!existsSync19(srcPath)) {
|
|
16512
16512
|
return { success: false, error: `Template '${templateName}' not found at ${srcPath}` };
|
|
16513
16513
|
}
|
|
@@ -16522,8 +16522,8 @@ function copyTemplateConfig(templateName, targetPath, projectName) {
|
|
|
16522
16522
|
}
|
|
16523
16523
|
function getInstallerVersion() {
|
|
16524
16524
|
const candidates = [
|
|
16525
|
-
|
|
16526
|
-
|
|
16525
|
+
resolve9(__dirname2, "../package.json"),
|
|
16526
|
+
resolve9(__dirname2, "../../package.json")
|
|
16527
16527
|
];
|
|
16528
16528
|
for (const candidate of candidates) {
|
|
16529
16529
|
if (existsSync19(candidate)) {
|
|
@@ -16541,7 +16541,7 @@ function getInstallerVersion() {
|
|
|
16541
16541
|
);
|
|
16542
16542
|
}
|
|
16543
16543
|
function registerMcpServer(projectRoot) {
|
|
16544
|
-
const mcpPath =
|
|
16544
|
+
const mcpPath = resolve9(projectRoot, ".mcp.json");
|
|
16545
16545
|
let existing = {};
|
|
16546
16546
|
if (existsSync19(mcpPath)) {
|
|
16547
16547
|
try {
|
|
@@ -16566,11 +16566,11 @@ function registerMcpServer(projectRoot) {
|
|
|
16566
16566
|
}
|
|
16567
16567
|
function resolveHooksDir() {
|
|
16568
16568
|
const cwd = process.cwd();
|
|
16569
|
-
const nodeModulesPath =
|
|
16569
|
+
const nodeModulesPath = resolve9(cwd, "node_modules/@massu/core/dist/hooks");
|
|
16570
16570
|
if (existsSync19(nodeModulesPath)) {
|
|
16571
16571
|
return "node_modules/@massu/core/dist/hooks";
|
|
16572
16572
|
}
|
|
16573
|
-
const localPath =
|
|
16573
|
+
const localPath = resolve9(__dirname2, "../dist/hooks");
|
|
16574
16574
|
if (existsSync19(localPath)) {
|
|
16575
16575
|
return localPath;
|
|
16576
16576
|
}
|
|
@@ -16720,7 +16720,7 @@ function installHooks(projectRoot) {
|
|
|
16720
16720
|
} catch {
|
|
16721
16721
|
claudeDirName = ".claude";
|
|
16722
16722
|
}
|
|
16723
|
-
const claudeDir =
|
|
16723
|
+
const claudeDir = resolve9(projectRoot, claudeDirName);
|
|
16724
16724
|
if (!existsSync19(claudeDir)) {
|
|
16725
16725
|
mkdirSync10(claudeDir, { recursive: true });
|
|
16726
16726
|
}
|
|
@@ -16740,15 +16740,15 @@ function installHooks(projectRoot) {
|
|
|
16740
16740
|
}
|
|
16741
16741
|
function initMemoryDir(projectRoot) {
|
|
16742
16742
|
const encodedRoot = encodeMemoryDirName(projectRoot);
|
|
16743
|
-
const memoryDir =
|
|
16743
|
+
const memoryDir = resolve9(homedir7(), `.claude/projects/${encodedRoot}/memory`);
|
|
16744
16744
|
let migratedFromLegacy = false;
|
|
16745
|
-
const legacyDir =
|
|
16745
|
+
const legacyDir = resolve9(homedir7(), `.claude/projects/-${encodedRoot}/memory`);
|
|
16746
16746
|
if (existsSync19(legacyDir) && !existsSync19(memoryDir)) {
|
|
16747
16747
|
try {
|
|
16748
|
-
mkdirSync10(
|
|
16748
|
+
mkdirSync10(resolve9(memoryDir, ".."), { recursive: true });
|
|
16749
16749
|
renameSync4(legacyDir, memoryDir);
|
|
16750
16750
|
try {
|
|
16751
|
-
const legacyParent =
|
|
16751
|
+
const legacyParent = resolve9(legacyDir, "..");
|
|
16752
16752
|
if (existsSync19(legacyParent) && readdirSync12(legacyParent).length === 0) {
|
|
16753
16753
|
rmSync6(legacyParent, { recursive: false });
|
|
16754
16754
|
}
|
|
@@ -16763,7 +16763,7 @@ function initMemoryDir(projectRoot) {
|
|
|
16763
16763
|
mkdirSync10(memoryDir, { recursive: true });
|
|
16764
16764
|
created = true;
|
|
16765
16765
|
}
|
|
16766
|
-
const memoryMdPath =
|
|
16766
|
+
const memoryMdPath = resolve9(memoryDir, "MEMORY.md");
|
|
16767
16767
|
let memoryMdCreated = false;
|
|
16768
16768
|
if (!existsSync19(memoryMdPath)) {
|
|
16769
16769
|
const projectName = basename6(projectRoot);
|
|
@@ -16879,7 +16879,7 @@ async function runInit(argv, overrides) {
|
|
|
16879
16879
|
log("Massu AI - Project Setup");
|
|
16880
16880
|
log("========================");
|
|
16881
16881
|
log("");
|
|
16882
|
-
const configPath =
|
|
16882
|
+
const configPath = resolve9(projectRoot, "massu.config.yaml");
|
|
16883
16883
|
if (existsSync19(configPath)) {
|
|
16884
16884
|
if (opts.ci && !opts.force) {
|
|
16885
16885
|
errLog(`error: massu.config.yaml already exists at ${configPath}`);
|
|
@@ -17019,7 +17019,7 @@ function installSideEffects(projectRoot, log, skipCommands = false, emptyStack =
|
|
|
17019
17019
|
const commandStats = cmdResult.assets.commands;
|
|
17020
17020
|
const stackResolved = !emptyStack && commandStats && (commandStats.installed > 0 || commandStats.updated > 0 || commandStats.kept > 0);
|
|
17021
17021
|
if (!stackResolved) {
|
|
17022
|
-
const placeholderPath =
|
|
17022
|
+
const placeholderPath = resolve9(cmdResult.claudeDir, "commands", "_massu-needs-stack.md");
|
|
17023
17023
|
if (!existsSync19(placeholderPath)) {
|
|
17024
17024
|
const placeholderBody = [
|
|
17025
17025
|
"# Massu \u2014 stack not yet detected",
|
|
@@ -17041,7 +17041,7 @@ function installSideEffects(projectRoot, log, skipCommands = false, emptyStack =
|
|
|
17041
17041
|
"\u2014 Massu"
|
|
17042
17042
|
].join("\n");
|
|
17043
17043
|
try {
|
|
17044
|
-
mkdirSync10(
|
|
17044
|
+
mkdirSync10(resolve9(cmdResult.claudeDir, "commands"), { recursive: true });
|
|
17045
17045
|
writeFileSync5(placeholderPath, placeholderBody, "utf-8");
|
|
17046
17046
|
log(" Wrote _massu-needs-stack.md placeholder (no stack detected yet)");
|
|
17047
17047
|
} catch {
|
|
@@ -17064,7 +17064,7 @@ function installSideEffects(projectRoot, log, skipCommands = false, emptyStack =
|
|
|
17064
17064
|
(async () => {
|
|
17065
17065
|
try {
|
|
17066
17066
|
const encodedRoot = encodeMemoryDirName(projectRoot);
|
|
17067
|
-
const memoryDir =
|
|
17067
|
+
const memoryDir = resolve9(homedir7(), ".claude", "projects", encodedRoot, "memory");
|
|
17068
17068
|
const memFiles = existsSync19(memoryDir) ? readdirSync12(memoryDir).filter((f2) => f2.endsWith(".md") && f2 !== "MEMORY.md") : [];
|
|
17069
17069
|
if (memFiles.length > 0) {
|
|
17070
17070
|
const { getMemoryDb: getMemoryDb2 } = await Promise.resolve().then(() => (init_memory_db(), memory_db_exports));
|
|
@@ -17836,7 +17836,7 @@ __export(hook_runner_exports, {
|
|
|
17836
17836
|
runHookRunner: () => runHookRunner
|
|
17837
17837
|
});
|
|
17838
17838
|
import { existsSync as existsSync21 } from "fs";
|
|
17839
|
-
import { resolve as
|
|
17839
|
+
import { resolve as resolve10, dirname as dirname13 } from "path";
|
|
17840
17840
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
17841
17841
|
import { spawn } from "child_process";
|
|
17842
17842
|
function resolveHookFile(hookName) {
|
|
@@ -17848,11 +17848,11 @@ function resolveHookFile(hookName) {
|
|
|
17848
17848
|
}
|
|
17849
17849
|
const candidates = [
|
|
17850
17850
|
// Bundled compiled layout: dist/cli.js → ./hooks/<file>.js
|
|
17851
|
-
|
|
17851
|
+
resolve10(__dirname3, "hooks", file),
|
|
17852
17852
|
// TS-source dev / sibling layout: src/commands/ → ../hooks/<file>
|
|
17853
|
-
|
|
17853
|
+
resolve10(__dirname3, "../hooks", file),
|
|
17854
17854
|
// TS-source dev fallback: src/commands/ → ../../dist/hooks/<file>
|
|
17855
|
-
|
|
17855
|
+
resolve10(__dirname3, "../../dist/hooks", file)
|
|
17856
17856
|
];
|
|
17857
17857
|
for (const candidate of candidates) {
|
|
17858
17858
|
if (existsSync21(candidate)) {
|
|
@@ -17929,11 +17929,11 @@ __export(doctor_exports, {
|
|
|
17929
17929
|
runValidateConfig: () => runValidateConfig
|
|
17930
17930
|
});
|
|
17931
17931
|
import { existsSync as existsSync22, readFileSync as readFileSync16, readdirSync as readdirSync13 } from "fs";
|
|
17932
|
-
import { resolve as
|
|
17932
|
+
import { resolve as resolve11, dirname as dirname14 } from "path";
|
|
17933
17933
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
17934
17934
|
import { parse as parseYaml4 } from "yaml";
|
|
17935
17935
|
function checkConfig(projectRoot) {
|
|
17936
|
-
const configPath =
|
|
17936
|
+
const configPath = resolve11(projectRoot, "massu.config.yaml");
|
|
17937
17937
|
if (!existsSync22(configPath)) {
|
|
17938
17938
|
return { name: "Configuration", status: "fail", detail: "massu.config.yaml not found. Run: npx massu init" };
|
|
17939
17939
|
}
|
|
@@ -18007,10 +18007,10 @@ function checkHooksConfig(_projectRoot2) {
|
|
|
18007
18007
|
}
|
|
18008
18008
|
}
|
|
18009
18009
|
function checkHookFiles(projectRoot) {
|
|
18010
|
-
const nodeModulesHooksDir =
|
|
18010
|
+
const nodeModulesHooksDir = resolve11(projectRoot, "node_modules/@massu/core/dist/hooks");
|
|
18011
18011
|
let hooksDir = nodeModulesHooksDir;
|
|
18012
18012
|
if (!existsSync22(nodeModulesHooksDir)) {
|
|
18013
|
-
const devHooksDir =
|
|
18013
|
+
const devHooksDir = resolve11(__dirname4, "../../dist/hooks");
|
|
18014
18014
|
if (existsSync22(devHooksDir)) {
|
|
18015
18015
|
hooksDir = devHooksDir;
|
|
18016
18016
|
} else {
|
|
@@ -18019,7 +18019,7 @@ function checkHookFiles(projectRoot) {
|
|
|
18019
18019
|
}
|
|
18020
18020
|
const missing = [];
|
|
18021
18021
|
for (const hookFile of EXPECTED_HOOKS) {
|
|
18022
|
-
if (!existsSync22(
|
|
18022
|
+
if (!existsSync22(resolve11(hooksDir, hookFile))) {
|
|
18023
18023
|
missing.push(hookFile);
|
|
18024
18024
|
}
|
|
18025
18025
|
}
|
|
@@ -18045,12 +18045,12 @@ async function checkHookExecution(projectRoot, opts = {}) {
|
|
|
18045
18045
|
detail: `Canary hook file unresolved: ${err instanceof Error ? err.message : String(err)}. Re-run: npx -y @massu/core init`
|
|
18046
18046
|
};
|
|
18047
18047
|
}
|
|
18048
|
-
const tmpCwd = mkdtempSync2(
|
|
18048
|
+
const tmpCwd = mkdtempSync2(resolve11(tmpdir2(), "massu-hook-canary-"));
|
|
18049
18049
|
try {
|
|
18050
|
-
const realConfig =
|
|
18050
|
+
const realConfig = resolve11(projectRoot, "massu.config.yaml");
|
|
18051
18051
|
if (existsSync22(realConfig)) {
|
|
18052
18052
|
try {
|
|
18053
|
-
copyFileSync4(realConfig,
|
|
18053
|
+
copyFileSync4(realConfig, resolve11(tmpCwd, "massu.config.yaml"));
|
|
18054
18054
|
} catch {
|
|
18055
18055
|
}
|
|
18056
18056
|
}
|
|
@@ -18113,7 +18113,7 @@ function checkNodeVersion2() {
|
|
|
18113
18113
|
return { name: "Node.js", status: "fail", detail: `v${version} \u2014 Node.js >= ${floor} is required (node:sqlite engine)` };
|
|
18114
18114
|
}
|
|
18115
18115
|
async function checkGitRepo(projectRoot) {
|
|
18116
|
-
const gitDir =
|
|
18116
|
+
const gitDir = resolve11(projectRoot, ".git");
|
|
18117
18117
|
if (!existsSync22(gitDir)) {
|
|
18118
18118
|
return { name: "Git Repository", status: "warn", detail: "Not a git repository (optional but recommended)" };
|
|
18119
18119
|
}
|
|
@@ -18253,7 +18253,7 @@ async function checkApiKeyHygiene(projectRoot) {
|
|
|
18253
18253
|
function checkPythonHealth(projectRoot) {
|
|
18254
18254
|
const config = getConfig();
|
|
18255
18255
|
if (!config.python?.root) return null;
|
|
18256
|
-
const pythonRoot =
|
|
18256
|
+
const pythonRoot = resolve11(projectRoot, config.python.root);
|
|
18257
18257
|
if (!existsSync22(pythonRoot)) {
|
|
18258
18258
|
return {
|
|
18259
18259
|
name: "Python",
|
|
@@ -18273,8 +18273,8 @@ function checkPythonHealth(projectRoot) {
|
|
|
18273
18273
|
if (entry.isDirectory()) {
|
|
18274
18274
|
const excludeDirs = config.python?.exclude_dirs || ["__pycache__", ".venv", "venv", ".mypy_cache", ".pytest_cache"];
|
|
18275
18275
|
if (!excludeDirs.includes(entry.name)) {
|
|
18276
|
-
const subdir =
|
|
18277
|
-
if (depth <= 2 && !existsSync22(
|
|
18276
|
+
const subdir = resolve11(dir, entry.name);
|
|
18277
|
+
if (depth <= 2 && !existsSync22(resolve11(subdir, "__init__.py"))) {
|
|
18278
18278
|
try {
|
|
18279
18279
|
const subEntries = readdirSync13(subdir);
|
|
18280
18280
|
if (subEntries.some((f2) => f2.endsWith(".py") && f2 !== "__init__.py")) {
|
|
@@ -18372,7 +18372,7 @@ async function runDoctor() {
|
|
|
18372
18372
|
}
|
|
18373
18373
|
async function runValidateConfig() {
|
|
18374
18374
|
const projectRoot = process.cwd();
|
|
18375
|
-
const configPath =
|
|
18375
|
+
const configPath = resolve11(projectRoot, "massu.config.yaml");
|
|
18376
18376
|
if (!existsSync22(configPath)) {
|
|
18377
18377
|
console.error("Error: massu.config.yaml not found in current directory");
|
|
18378
18378
|
console.error("Run: npx massu init");
|
|
@@ -18720,7 +18720,7 @@ __export(permissions_exports, {
|
|
|
18720
18720
|
handlePermissionsSubcommand: () => handlePermissionsSubcommand,
|
|
18721
18721
|
printPermissionsHelp: () => printPermissionsHelp
|
|
18722
18722
|
});
|
|
18723
|
-
import { resolve as
|
|
18723
|
+
import { resolve as resolve12 } from "path";
|
|
18724
18724
|
function resolveClaudeDir2() {
|
|
18725
18725
|
let claudeDirName = ".claude";
|
|
18726
18726
|
try {
|
|
@@ -18728,7 +18728,7 @@ function resolveClaudeDir2() {
|
|
|
18728
18728
|
} catch {
|
|
18729
18729
|
claudeDirName = ".claude";
|
|
18730
18730
|
}
|
|
18731
|
-
return
|
|
18731
|
+
return resolve12(process.cwd(), claudeDirName);
|
|
18732
18732
|
}
|
|
18733
18733
|
async function handlePermissionsSubcommand(args2) {
|
|
18734
18734
|
const sub = args2[0];
|
|
@@ -19156,7 +19156,7 @@ var init_license2 = __esm({
|
|
|
19156
19156
|
|
|
19157
19157
|
// src/changelog-generator.ts
|
|
19158
19158
|
import { existsSync as existsSync24, readFileSync as readFileSync17, readdirSync as readdirSync14 } from "fs";
|
|
19159
|
-
import { resolve as
|
|
19159
|
+
import { resolve as resolve13 } from "path";
|
|
19160
19160
|
function parseCommitsForPlanTokens(subjects) {
|
|
19161
19161
|
const tokens = /* @__PURE__ */ new Set();
|
|
19162
19162
|
const maintenance = [];
|
|
@@ -19181,7 +19181,7 @@ function loadPlanSummaries(tokens, planDir) {
|
|
|
19181
19181
|
let matchedFile = null;
|
|
19182
19182
|
let content = "";
|
|
19183
19183
|
for (const file of files) {
|
|
19184
|
-
const path =
|
|
19184
|
+
const path = resolve13(planDir, file);
|
|
19185
19185
|
const text18 = readFileSync17(path, "utf-8");
|
|
19186
19186
|
const tokenRe = new RegExp(
|
|
19187
19187
|
`^\\*\\*Plan Token\\*\\*:\\s*\`?${token.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&")}\`?(\\s|$)`,
|
|
@@ -19264,7 +19264,7 @@ __export(changelog_exports, {
|
|
|
19264
19264
|
});
|
|
19265
19265
|
import { execSync } from "child_process";
|
|
19266
19266
|
import { existsSync as existsSync25, readFileSync as readFileSync18 } from "fs";
|
|
19267
|
-
import { resolve as
|
|
19267
|
+
import { resolve as resolve14 } from "path";
|
|
19268
19268
|
function resolveRepoRoot() {
|
|
19269
19269
|
try {
|
|
19270
19270
|
return execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
|
|
@@ -19288,7 +19288,7 @@ function getCommitSubjects(range) {
|
|
|
19288
19288
|
}
|
|
19289
19289
|
}
|
|
19290
19290
|
function getCurrentVersion(repoRoot) {
|
|
19291
|
-
const pkgPath =
|
|
19291
|
+
const pkgPath = resolve14(repoRoot, "packages/core/package.json");
|
|
19292
19292
|
if (!existsSync25(pkgPath)) return "0.0.0";
|
|
19293
19293
|
const pkg = JSON.parse(readFileSync18(pkgPath, "utf-8"));
|
|
19294
19294
|
return pkg.version || "0.0.0";
|
|
@@ -19297,7 +19297,7 @@ function todayDate() {
|
|
|
19297
19297
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
19298
19298
|
}
|
|
19299
19299
|
function getLatestChangelogEntryBody(repoRoot) {
|
|
19300
|
-
const path =
|
|
19300
|
+
const path = resolve14(repoRoot, "CHANGELOG.md");
|
|
19301
19301
|
if (!existsSync25(path)) return "";
|
|
19302
19302
|
const content = readFileSync18(path, "utf-8");
|
|
19303
19303
|
const m3 = content.match(/^## \[[\d.]+\][^\n]*\n([\s\S]*?)(?=\n## \[|$)/m);
|
|
@@ -19306,7 +19306,7 @@ function getLatestChangelogEntryBody(repoRoot) {
|
|
|
19306
19306
|
async function handleChangelogSubcommand(args2) {
|
|
19307
19307
|
const sub = args2[0];
|
|
19308
19308
|
const repoRoot = resolveRepoRoot();
|
|
19309
|
-
const planDir =
|
|
19309
|
+
const planDir = resolve14(repoRoot, "docs/plans");
|
|
19310
19310
|
switch (sub) {
|
|
19311
19311
|
case "generate": {
|
|
19312
19312
|
const lastTag = getLastTag();
|
|
@@ -19688,9 +19688,9 @@ var init_memory_embed_backfill = __esm({
|
|
|
19688
19688
|
import { createHmac, randomBytes, timingSafeEqual } from "crypto";
|
|
19689
19689
|
import { readFileSync as readFileSync19, writeFileSync as writeFileSync6, existsSync as existsSync28, mkdirSync as mkdirSync12, chmodSync as chmodSync6, statSync as statSync12 } from "fs";
|
|
19690
19690
|
import { homedir as homedir8 } from "os";
|
|
19691
|
-
import { resolve as
|
|
19691
|
+
import { resolve as resolve15 } from "path";
|
|
19692
19692
|
function renderKeyPath(home = homedir8()) {
|
|
19693
|
-
return
|
|
19693
|
+
return resolve15(home, ".massu", "render-key");
|
|
19694
19694
|
}
|
|
19695
19695
|
function readRenderKey(home = homedir8()) {
|
|
19696
19696
|
const p19 = renderKeyPath(home);
|
|
@@ -19708,7 +19708,7 @@ function ensureRenderKey(home = homedir8()) {
|
|
|
19708
19708
|
if (existing) return existing;
|
|
19709
19709
|
const p19 = renderKeyPath(home);
|
|
19710
19710
|
try {
|
|
19711
|
-
const dir =
|
|
19711
|
+
const dir = resolve15(home, ".massu");
|
|
19712
19712
|
mkdirSync12(dir, { recursive: true, mode: 448 });
|
|
19713
19713
|
try {
|
|
19714
19714
|
chmodSync6(dir, 448);
|
|
@@ -20119,9 +20119,9 @@ import {
|
|
|
20119
20119
|
readFileSync as readFileSync22
|
|
20120
20120
|
} from "fs";
|
|
20121
20121
|
import { homedir as homedir9 } from "os";
|
|
20122
|
-
import { join as join17, resolve as
|
|
20122
|
+
import { join as join17, resolve as resolve16 } from "path";
|
|
20123
20123
|
function backupsRoot(home = homedir9()) {
|
|
20124
|
-
return
|
|
20124
|
+
return resolve16(home, ".massu", "memory-backups");
|
|
20125
20125
|
}
|
|
20126
20126
|
function backupStamp2(nowMs) {
|
|
20127
20127
|
return new Date(nowMs).toISOString().replace(/:/g, "-");
|
|
@@ -22227,7 +22227,7 @@ var init_promotion_apply_mac = __esm({
|
|
|
22227
22227
|
|
|
22228
22228
|
// src/rule-candidate-applier.ts
|
|
22229
22229
|
import { readFileSync as readFileSync29, writeFileSync as writeFileSync11, existsSync as existsSync38, unlinkSync as unlinkSync5, mkdirSync as mkdirSync17 } from "fs";
|
|
22230
|
-
import { join as join24, dirname as dirname19, isAbsolute as
|
|
22230
|
+
import { join as join24, dirname as dirname19, isAbsolute as isAbsolute2 } from "path";
|
|
22231
22231
|
import { homedir as homedir19 } from "os";
|
|
22232
22232
|
import { createHash as createHash11 } from "crypto";
|
|
22233
22233
|
function isRuleDestination(value) {
|
|
@@ -22530,7 +22530,7 @@ function computeDestinationTargets(opts, candidate, slug, projectRoot, home) {
|
|
|
22530
22530
|
throw new DestinationConfigError("custom-destination requires customDestination config entry");
|
|
22531
22531
|
}
|
|
22532
22532
|
const raw = opts.customDestination.path;
|
|
22533
|
-
const absolute =
|
|
22533
|
+
const absolute = isAbsolute2(raw) ? raw : join24(projectRoot, raw);
|
|
22534
22534
|
try {
|
|
22535
22535
|
assertContainedIn(projectRoot, absolute, { allowNested: true });
|
|
22536
22536
|
} catch (err) {
|
|
@@ -24704,7 +24704,7 @@ __export(show_template_exports, {
|
|
|
24704
24704
|
runShowTemplate: () => runShowTemplate
|
|
24705
24705
|
});
|
|
24706
24706
|
import { existsSync as existsSync43, readFileSync as readFileSync32 } from "fs";
|
|
24707
|
-
import { resolve as
|
|
24707
|
+
import { resolve as resolve17 } from "path";
|
|
24708
24708
|
function normalizeBaseName(input) {
|
|
24709
24709
|
return input.endsWith(".md") ? input.slice(0, -".md".length) : input;
|
|
24710
24710
|
}
|
|
@@ -24732,7 +24732,7 @@ async function runShowTemplate(args2) {
|
|
|
24732
24732
|
return;
|
|
24733
24733
|
}
|
|
24734
24734
|
const suffix = choice.kind === "hit" ? choice.suffix : "";
|
|
24735
|
-
const file = suffix === "" ?
|
|
24735
|
+
const file = suffix === "" ? resolve17(sourceDir, `${baseName}.md`) : resolve17(sourceDir, `${baseName}${suffix}.md`);
|
|
24736
24736
|
if (!existsSync43(file)) {
|
|
24737
24737
|
process.stderr.write(`massu: resolved template "${file}" no longer exists
|
|
24738
24738
|
`);
|
|
@@ -24792,9 +24792,9 @@ var init_passthrough = __esm({
|
|
|
24792
24792
|
});
|
|
24793
24793
|
|
|
24794
24794
|
// src/lib/installLock.ts
|
|
24795
|
-
import { resolve as
|
|
24795
|
+
import { resolve as resolve18 } from "path";
|
|
24796
24796
|
function withInstallLock(projectRoot, fn, opts = {}) {
|
|
24797
|
-
const lockPath =
|
|
24797
|
+
const lockPath = resolve18(projectRoot, ".massu", "installAll.lock");
|
|
24798
24798
|
return withFileLockSync(
|
|
24799
24799
|
lockPath,
|
|
24800
24800
|
fn,
|
|
@@ -24835,7 +24835,7 @@ __export(config_refresh_exports, {
|
|
|
24835
24835
|
runConfigRefresh: () => runConfigRefresh
|
|
24836
24836
|
});
|
|
24837
24837
|
import { existsSync as existsSync44, readFileSync as readFileSync33, rmSync as rmSync9 } from "fs";
|
|
24838
|
-
import { resolve as
|
|
24838
|
+
import { resolve as resolve19 } from "path";
|
|
24839
24839
|
import { parse as parseYaml5 } from "yaml";
|
|
24840
24840
|
function flatten(obj, prefix3 = "") {
|
|
24841
24841
|
const out = {};
|
|
@@ -24963,7 +24963,7 @@ function renderDiff(diff) {
|
|
|
24963
24963
|
}
|
|
24964
24964
|
async function runConfigRefresh(opts = {}) {
|
|
24965
24965
|
const cwd = opts.cwd ?? process.cwd();
|
|
24966
|
-
const configPath =
|
|
24966
|
+
const configPath = resolve19(cwd, "massu.config.yaml");
|
|
24967
24967
|
const log = opts.silent ? () => {
|
|
24968
24968
|
} : (s) => process.stdout.write(s);
|
|
24969
24969
|
if (!existsSync44(configPath)) {
|
|
@@ -25046,7 +25046,7 @@ async function runConfigRefresh(opts = {}) {
|
|
|
25046
25046
|
`);
|
|
25047
25047
|
const stackResolved = installResult.totalInstalled > 0 || installResult.totalUpdated > 0;
|
|
25048
25048
|
if (stackResolved) {
|
|
25049
|
-
const placeholderPath =
|
|
25049
|
+
const placeholderPath = resolve19(installResult.claudeDir, "commands", "_massu-needs-stack.md");
|
|
25050
25050
|
if (existsSync44(placeholderPath)) {
|
|
25051
25051
|
try {
|
|
25052
25052
|
rmSync9(placeholderPath, { force: true });
|
|
@@ -25157,10 +25157,10 @@ var init_gitToplevel = __esm({
|
|
|
25157
25157
|
|
|
25158
25158
|
// src/watch/lockfile-detector.ts
|
|
25159
25159
|
import { existsSync as existsSync45, statSync as statSync15 } from "fs";
|
|
25160
|
-
import { resolve as
|
|
25160
|
+
import { resolve as resolve20 } from "path";
|
|
25161
25161
|
function lockfileMidWrite(projectRoot, now = Date.now(), windowMs = LOCKFILE_WINDOW_MS) {
|
|
25162
25162
|
for (const lf of KNOWN_LOCKFILES) {
|
|
25163
|
-
const p19 =
|
|
25163
|
+
const p19 = resolve20(projectRoot, lf);
|
|
25164
25164
|
if (!existsSync45(p19)) continue;
|
|
25165
25165
|
try {
|
|
25166
25166
|
const stat = statSync15(p19);
|
|
@@ -25174,7 +25174,7 @@ function lockfileMidWrite(projectRoot, now = Date.now(), windowMs = LOCKFILE_WIN
|
|
|
25174
25174
|
function gitMidOperation(projectRoot) {
|
|
25175
25175
|
const sentinels = ["MERGE_HEAD", "REBASE_HEAD", "CHERRY_PICK_HEAD", "rebase-apply", "rebase-merge"];
|
|
25176
25176
|
for (const s of sentinels) {
|
|
25177
|
-
if (existsSync45(
|
|
25177
|
+
if (existsSync45(resolve20(projectRoot, ".git", s))) return true;
|
|
25178
25178
|
}
|
|
25179
25179
|
return false;
|
|
25180
25180
|
}
|
|
@@ -25374,12 +25374,12 @@ var init_paths = __esm({
|
|
|
25374
25374
|
|
|
25375
25375
|
// src/watch/state.ts
|
|
25376
25376
|
import { closeSync as closeSync5, existsSync as existsSync46, fsyncSync as fsyncSync5, mkdirSync as mkdirSync20, openSync as openSync5, readFileSync as readFileSync34, renameSync as renameSync5, rmSync as rmSync10, writeFileSync as writeFileSync15, writeSync as writeSync3 } from "fs";
|
|
25377
|
-
import { dirname as dirname21, resolve as
|
|
25377
|
+
import { dirname as dirname21, resolve as resolve21 } from "path";
|
|
25378
25378
|
function watchStatePath(projectRoot) {
|
|
25379
|
-
return
|
|
25379
|
+
return resolve21(projectRoot, ".massu", "watch-state.json");
|
|
25380
25380
|
}
|
|
25381
25381
|
function backupStatePath(projectRoot) {
|
|
25382
|
-
return
|
|
25382
|
+
return resolve21(projectRoot, ".massu", "watch-state.v0.bak.json");
|
|
25383
25383
|
}
|
|
25384
25384
|
function readState(projectRoot) {
|
|
25385
25385
|
const path = watchStatePath(projectRoot);
|
|
@@ -25729,7 +25729,7 @@ __export(watch_exports, {
|
|
|
25729
25729
|
runWatch: () => runWatch
|
|
25730
25730
|
});
|
|
25731
25731
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
25732
|
-
import { basename as basename8, dirname as dirname22, resolve as
|
|
25732
|
+
import { basename as basename8, dirname as dirname22, resolve as resolve22 } from "path";
|
|
25733
25733
|
import { appendFileSync as appendFileSync4, existsSync as existsSync47, mkdirSync as mkdirSync21, readFileSync as readFileSync35 } from "fs";
|
|
25734
25734
|
function parseFlags(args2) {
|
|
25735
25735
|
const out = {
|
|
@@ -25755,7 +25755,7 @@ function parseFlags(args2) {
|
|
|
25755
25755
|
}
|
|
25756
25756
|
function findClaudeBg() {
|
|
25757
25757
|
const home = process.env.HOME ?? "";
|
|
25758
|
-
const fixed = home ?
|
|
25758
|
+
const fixed = home ? resolve22(home, ".claude", "bin", "claude-bg") : null;
|
|
25759
25759
|
if (fixed && existsSync47(fixed)) return fixed;
|
|
25760
25760
|
const which = spawnSync5("which", ["claude-bg"], { encoding: "utf-8" });
|
|
25761
25761
|
if (which.status === 0 && which.stdout) {
|
|
@@ -25899,7 +25899,7 @@ async function runForeground(root) {
|
|
|
25899
25899
|
}
|
|
25900
25900
|
throw err;
|
|
25901
25901
|
}
|
|
25902
|
-
return new Promise((
|
|
25902
|
+
return new Promise((resolve45) => {
|
|
25903
25903
|
const shutdown = async () => {
|
|
25904
25904
|
if (stopped) return;
|
|
25905
25905
|
stopped = true;
|
|
@@ -25909,7 +25909,7 @@ async function runForeground(root) {
|
|
|
25909
25909
|
process.chdir(priorCwd);
|
|
25910
25910
|
} catch {
|
|
25911
25911
|
}
|
|
25912
|
-
|
|
25912
|
+
resolve45({ exitCode: 0 });
|
|
25913
25913
|
};
|
|
25914
25914
|
process.on("SIGINT", () => {
|
|
25915
25915
|
void shutdown();
|
|
@@ -25970,7 +25970,7 @@ async function runOnQuiescent(projectRoot) {
|
|
|
25970
25970
|
);
|
|
25971
25971
|
}
|
|
25972
25972
|
function refreshLogPath(projectRoot) {
|
|
25973
|
-
return
|
|
25973
|
+
return resolve22(projectRoot, ".massu", "refresh-log.jsonl");
|
|
25974
25974
|
}
|
|
25975
25975
|
function appendRefreshLog(projectRoot, event) {
|
|
25976
25976
|
const path = refreshLogPath(projectRoot);
|
|
@@ -26446,13 +26446,13 @@ var init_fetcher = __esm({
|
|
|
26446
26446
|
// src/security/manifest-cache.ts
|
|
26447
26447
|
import { existsSync as existsSync49, readFileSync as readFileSync36, statSync as statSync17 } from "node:fs";
|
|
26448
26448
|
import { homedir as homedir21 } from "node:os";
|
|
26449
|
-
import { resolve as
|
|
26449
|
+
import { resolve as resolve23 } from "node:path";
|
|
26450
26450
|
import { z as z5 } from "zod";
|
|
26451
26451
|
function defaultCachePaths() {
|
|
26452
|
-
const dir =
|
|
26452
|
+
const dir = resolve23(homedir21(), ".massu");
|
|
26453
26453
|
return {
|
|
26454
|
-
cachePath:
|
|
26455
|
-
lockPath:
|
|
26454
|
+
cachePath: resolve23(dir, "adapter-manifest.json"),
|
|
26455
|
+
lockPath: resolve23(dir, ".adapter-manifest.lock")
|
|
26456
26456
|
};
|
|
26457
26457
|
}
|
|
26458
26458
|
function loadCachedManifest(paths = defaultCachePaths()) {
|
|
@@ -26652,13 +26652,13 @@ var init_adapter_origin = __esm({
|
|
|
26652
26652
|
// src/security/local-fingerprint.ts
|
|
26653
26653
|
import { existsSync as existsSync50, readFileSync as readFileSync37, lstatSync as lstatSync5 } from "node:fs";
|
|
26654
26654
|
import { homedir as homedir22 } from "node:os";
|
|
26655
|
-
import { resolve as
|
|
26655
|
+
import { resolve as resolve24, isAbsolute as isAbsolute3 } from "node:path";
|
|
26656
26656
|
import { createHash as createHash14 } from "node:crypto";
|
|
26657
26657
|
import { z as z6 } from "zod";
|
|
26658
26658
|
function computeLocalFingerprint(localPaths, projectRoot) {
|
|
26659
26659
|
const tuples = [];
|
|
26660
26660
|
for (const p19 of localPaths) {
|
|
26661
|
-
const abs =
|
|
26661
|
+
const abs = isAbsolute3(p19) ? p19 : resolve24(projectRoot, p19);
|
|
26662
26662
|
let contentTag;
|
|
26663
26663
|
try {
|
|
26664
26664
|
const lst = lstatSync5(abs);
|
|
@@ -26730,7 +26730,7 @@ var init_local_fingerprint = __esm({
|
|
|
26730
26730
|
"use strict";
|
|
26731
26731
|
init_atomic_write();
|
|
26732
26732
|
init_manifest_schema();
|
|
26733
|
-
FINGERPRINT_PATH =
|
|
26733
|
+
FINGERPRINT_PATH = resolve24(homedir22(), ".massu", "adapters-local-fingerprint.json");
|
|
26734
26734
|
FingerprintSentinelSchema = z6.object({
|
|
26735
26735
|
fingerprint: z6.string().regex(/^[0-9a-f]{64}$/),
|
|
26736
26736
|
source: z6.enum(["cli", "cli-resync"]),
|
|
@@ -26749,7 +26749,7 @@ var init_local_fingerprint = __esm({
|
|
|
26749
26749
|
import { readFileSync as readFileSync38, readdirSync as readdirSync17, lstatSync as lstatSync6, existsSync as existsSync51 } from "node:fs";
|
|
26750
26750
|
import { join as join28, relative as relative7, sep as sep2 } from "node:path";
|
|
26751
26751
|
import { homedir as homedir23 } from "node:os";
|
|
26752
|
-
import { resolve as
|
|
26752
|
+
import { resolve as resolve25 } from "node:path";
|
|
26753
26753
|
import { createHash as createHash15 } from "node:crypto";
|
|
26754
26754
|
import { z as z7 } from "zod";
|
|
26755
26755
|
function containsHiddenDirs(packageDir) {
|
|
@@ -26876,7 +26876,7 @@ var init_install_tracking = __esm({
|
|
|
26876
26876
|
"src/security/install-tracking.ts"() {
|
|
26877
26877
|
"use strict";
|
|
26878
26878
|
init_atomic_write();
|
|
26879
|
-
INSTALLED_MANIFEST_PATH =
|
|
26879
|
+
INSTALLED_MANIFEST_PATH = resolve25(homedir23(), ".massu", "adapter-manifest-installed.json");
|
|
26880
26880
|
DEFAULT_MAX_FILE_BYTES = 64 * 1024 * 1024;
|
|
26881
26881
|
EXCLUDED_DIR_NAMES = /* @__PURE__ */ new Set([".git", "node_modules", ".cache", ".tmp"]);
|
|
26882
26882
|
InstallEntrySchema = z7.object({
|
|
@@ -26900,10 +26900,10 @@ var init_install_tracking = __esm({
|
|
|
26900
26900
|
|
|
26901
26901
|
// src/detect/adapters/discover.ts
|
|
26902
26902
|
import { existsSync as existsSync52, readdirSync as readdirSync18, readFileSync as readFileSync39, lstatSync as lstatSync7 } from "node:fs";
|
|
26903
|
-
import { resolve as
|
|
26903
|
+
import { resolve as resolve26, isAbsolute as isAbsolute4 } from "node:path";
|
|
26904
26904
|
import { z as z8 } from "zod";
|
|
26905
26905
|
function walkNodeModules(projectRoot, warnings) {
|
|
26906
|
-
const nodeModulesDir =
|
|
26906
|
+
const nodeModulesDir = resolve26(projectRoot, "node_modules");
|
|
26907
26907
|
if (!existsSync52(nodeModulesDir)) {
|
|
26908
26908
|
return [];
|
|
26909
26909
|
}
|
|
@@ -26917,7 +26917,7 @@ function walkNodeModules(projectRoot, warnings) {
|
|
|
26917
26917
|
}
|
|
26918
26918
|
for (const entry of topLevelEntries) {
|
|
26919
26919
|
if (entry.startsWith(".")) continue;
|
|
26920
|
-
const entryPath =
|
|
26920
|
+
const entryPath = resolve26(nodeModulesDir, entry);
|
|
26921
26921
|
let entryStat;
|
|
26922
26922
|
try {
|
|
26923
26923
|
entryStat = lstatSync7(entryPath);
|
|
@@ -26939,7 +26939,7 @@ function walkNodeModules(projectRoot, warnings) {
|
|
|
26939
26939
|
continue;
|
|
26940
26940
|
}
|
|
26941
26941
|
for (const sub of scopedEntries) {
|
|
26942
|
-
const subPath =
|
|
26942
|
+
const subPath = resolve26(entryPath, sub);
|
|
26943
26943
|
let subStat;
|
|
26944
26944
|
try {
|
|
26945
26945
|
subStat = lstatSync7(subPath);
|
|
@@ -26958,7 +26958,7 @@ function walkNodeModules(projectRoot, warnings) {
|
|
|
26958
26958
|
return candidates;
|
|
26959
26959
|
}
|
|
26960
26960
|
function tryReadAdapterPackage(packageDir, warnings) {
|
|
26961
|
-
const pkgJsonPath =
|
|
26961
|
+
const pkgJsonPath = resolve26(packageDir, "package.json");
|
|
26962
26962
|
if (!existsSync52(pkgJsonPath)) return null;
|
|
26963
26963
|
let raw;
|
|
26964
26964
|
try {
|
|
@@ -27096,7 +27096,7 @@ function discoverAdapters(opts) {
|
|
|
27096
27096
|
const localSet = new Set(opts.configLocalPaths);
|
|
27097
27097
|
for (const localPath of opts.configLocalPaths) {
|
|
27098
27098
|
if (seenIds.has(localPath)) continue;
|
|
27099
|
-
const absPath =
|
|
27099
|
+
const absPath = isAbsolute4(localPath) ? localPath : resolve26(opts.projectRoot, localPath);
|
|
27100
27100
|
if (!existsSync52(absPath)) {
|
|
27101
27101
|
warnings.push(
|
|
27102
27102
|
`local adapter file not found: ${localPath} (resolved to ${absPath}). Remove via: massu adapters remove-local ${localPath}`
|
|
@@ -27180,7 +27180,7 @@ __export(adapters_exports, {
|
|
|
27180
27180
|
runAdaptersSearch: () => runAdaptersSearch
|
|
27181
27181
|
});
|
|
27182
27182
|
import { existsSync as existsSync53, readFileSync as readFileSync40 } from "node:fs";
|
|
27183
|
-
import { resolve as
|
|
27183
|
+
import { resolve as resolve27 } from "node:path";
|
|
27184
27184
|
import { parseDocument } from "yaml";
|
|
27185
27185
|
async function handleAdaptersSubcommand(args2) {
|
|
27186
27186
|
const sub = args2[0];
|
|
@@ -27447,7 +27447,7 @@ function mutateLocalArray(mutator, command) {
|
|
|
27447
27447
|
);
|
|
27448
27448
|
return { exitCode: 2 };
|
|
27449
27449
|
}
|
|
27450
|
-
const yamlPath =
|
|
27450
|
+
const yamlPath = resolve27(projectRoot, "massu.config.yaml");
|
|
27451
27451
|
if (!existsSync53(yamlPath)) {
|
|
27452
27452
|
process.stderr.write(
|
|
27453
27453
|
`${command}: massu.config.yaml not found at ${yamlPath}. Run \`massu init\` first.
|
|
@@ -27478,7 +27478,7 @@ function mutateLocalArray(mutator, command) {
|
|
|
27478
27478
|
if (next === null) {
|
|
27479
27479
|
return { exitCode: 0 };
|
|
27480
27480
|
}
|
|
27481
|
-
const lockPath =
|
|
27481
|
+
const lockPath = resolve27(projectRoot, ".massu", "adapters-local-mutate.lock");
|
|
27482
27482
|
return withFileLockSync(lockPath, () => {
|
|
27483
27483
|
doc.setIn(["adapters", "local"], next);
|
|
27484
27484
|
const newYaml = doc.toString();
|
|
@@ -27547,7 +27547,7 @@ async function runAdaptersInstall(args2) {
|
|
|
27547
27547
|
`);
|
|
27548
27548
|
return { exitCode: 1 };
|
|
27549
27549
|
}
|
|
27550
|
-
const packageDir =
|
|
27550
|
+
const packageDir = resolve27(projectRoot, "node_modules", ...packageName.split("/"));
|
|
27551
27551
|
if (!existsSync53(packageDir)) {
|
|
27552
27552
|
process.stderr.write(
|
|
27553
27553
|
`install: ${packageName} is not installed in node_modules. Run \`npm install ${packageName}\` first.
|
|
@@ -27555,7 +27555,7 @@ async function runAdaptersInstall(args2) {
|
|
|
27555
27555
|
);
|
|
27556
27556
|
return { exitCode: 1 };
|
|
27557
27557
|
}
|
|
27558
|
-
const pkgJsonPath =
|
|
27558
|
+
const pkgJsonPath = resolve27(packageDir, "package.json");
|
|
27559
27559
|
if (!existsSync53(pkgJsonPath)) {
|
|
27560
27560
|
process.stderr.write(`install: ${packageName} has no package.json at ${pkgJsonPath}
|
|
27561
27561
|
`);
|
|
@@ -27682,7 +27682,7 @@ async function runAdaptersResign(_args) {
|
|
|
27682
27682
|
removeInstalledManifestEntry(name);
|
|
27683
27683
|
continue;
|
|
27684
27684
|
}
|
|
27685
|
-
const packageDir =
|
|
27685
|
+
const packageDir = resolve27(projectRoot, "node_modules", ...name.split("/"));
|
|
27686
27686
|
if (!existsSync53(packageDir)) {
|
|
27687
27687
|
removed++;
|
|
27688
27688
|
warnings.push(`${name}@${entry.version}: not present in node_modules \u2014 REMOVED from sidecar`);
|
|
@@ -28094,10 +28094,10 @@ var init_db2 = __esm({
|
|
|
28094
28094
|
});
|
|
28095
28095
|
|
|
28096
28096
|
// src/security-utils.ts
|
|
28097
|
-
import { resolve as
|
|
28097
|
+
import { resolve as resolve28, normalize } from "path";
|
|
28098
28098
|
function ensureWithinRoot(filePath, projectRoot) {
|
|
28099
|
-
const resolvedRoot =
|
|
28100
|
-
const resolvedPath =
|
|
28099
|
+
const resolvedRoot = resolve28(projectRoot);
|
|
28100
|
+
const resolvedPath = resolve28(resolvedRoot, filePath);
|
|
28101
28101
|
const normalizedPath = normalize(resolvedPath);
|
|
28102
28102
|
const normalizedRoot = normalize(resolvedRoot);
|
|
28103
28103
|
if (!normalizedPath.startsWith(normalizedRoot + "/") && normalizedPath !== normalizedRoot) {
|
|
@@ -28171,7 +28171,7 @@ var init_rules = __esm({
|
|
|
28171
28171
|
|
|
28172
28172
|
// src/import-resolver.ts
|
|
28173
28173
|
import { readFileSync as readFileSync41, existsSync as existsSync55, statSync as statSync19 } from "fs";
|
|
28174
|
-
import { resolve as
|
|
28174
|
+
import { resolve as resolve29, dirname as dirname25, join as join30 } from "path";
|
|
28175
28175
|
function parseImports(source) {
|
|
28176
28176
|
const imports = [];
|
|
28177
28177
|
const lines = source.split("\n");
|
|
@@ -28227,9 +28227,9 @@ function resolveImportPath(specifier, fromFile) {
|
|
|
28227
28227
|
let basePath;
|
|
28228
28228
|
if (specifier.startsWith("@/")) {
|
|
28229
28229
|
const paths = getResolvedPaths();
|
|
28230
|
-
basePath =
|
|
28230
|
+
basePath = resolve29(paths.pathAlias["@"] ?? paths.srcDir, specifier.slice(2));
|
|
28231
28231
|
} else {
|
|
28232
|
-
basePath =
|
|
28232
|
+
basePath = resolve29(dirname25(fromFile), specifier);
|
|
28233
28233
|
}
|
|
28234
28234
|
if (existsSync55(basePath) && !isDirectory(basePath)) {
|
|
28235
28235
|
return toRelative(basePath);
|
|
@@ -28279,7 +28279,7 @@ function buildImportIndex(dataDb, codegraphDb) {
|
|
|
28279
28279
|
const batchSize = 500;
|
|
28280
28280
|
let batch = [];
|
|
28281
28281
|
for (const file of files) {
|
|
28282
|
-
const absPath = ensureWithinRoot(
|
|
28282
|
+
const absPath = ensureWithinRoot(resolve29(projectRoot, file.path), projectRoot);
|
|
28283
28283
|
if (!existsSync55(absPath)) continue;
|
|
28284
28284
|
let source;
|
|
28285
28285
|
try {
|
|
@@ -28321,7 +28321,7 @@ var init_import_resolver = __esm({
|
|
|
28321
28321
|
|
|
28322
28322
|
// src/trpc-index.ts
|
|
28323
28323
|
import { readFileSync as readFileSync42, existsSync as existsSync56, readdirSync as readdirSync20 } from "fs";
|
|
28324
|
-
import { resolve as
|
|
28324
|
+
import { resolve as resolve30, join as join31 } from "path";
|
|
28325
28325
|
function parseRootRouter() {
|
|
28326
28326
|
const paths = getResolvedPaths();
|
|
28327
28327
|
const rootPath = paths.rootRouterPath;
|
|
@@ -28336,7 +28336,7 @@ function parseRootRouter() {
|
|
|
28336
28336
|
while ((match = importRegex.exec(source)) !== null) {
|
|
28337
28337
|
const variable = match[1];
|
|
28338
28338
|
let filePath = match[2];
|
|
28339
|
-
const fullPath =
|
|
28339
|
+
const fullPath = resolve30(paths.routersDir, filePath);
|
|
28340
28340
|
for (const ext of [".ts", ".tsx", ""]) {
|
|
28341
28341
|
const candidate = fullPath + ext;
|
|
28342
28342
|
const routersRelPath = getConfig().paths.routers ?? "src/server/api/routers";
|
|
@@ -28364,7 +28364,7 @@ function parseRootRouter() {
|
|
|
28364
28364
|
return mappings;
|
|
28365
28365
|
}
|
|
28366
28366
|
function extractProcedures(routerFilePath) {
|
|
28367
|
-
const absPath =
|
|
28367
|
+
const absPath = resolve30(getProjectRoot(), routerFilePath);
|
|
28368
28368
|
if (!existsSync56(absPath)) return [];
|
|
28369
28369
|
const source = readFileSync42(absPath, "utf-8");
|
|
28370
28370
|
const procedures = [];
|
|
@@ -28389,9 +28389,9 @@ function findUICallSites(routerKey, procedureName) {
|
|
|
28389
28389
|
const root = getProjectRoot();
|
|
28390
28390
|
const src = config.paths.source;
|
|
28391
28391
|
const searchDirs = [
|
|
28392
|
-
|
|
28393
|
-
|
|
28394
|
-
|
|
28392
|
+
resolve30(root, config.paths.pages ?? src + "/app"),
|
|
28393
|
+
resolve30(root, config.paths.components ?? src + "/components"),
|
|
28394
|
+
resolve30(root, config.paths.hooks ?? src + "/hooks")
|
|
28395
28395
|
];
|
|
28396
28396
|
const searchPattern = `api.${routerKey}.${procedureName}`;
|
|
28397
28397
|
for (const dir of searchDirs) {
|
|
@@ -28474,7 +28474,7 @@ var init_trpc_index = __esm({
|
|
|
28474
28474
|
|
|
28475
28475
|
// src/page-deps.ts
|
|
28476
28476
|
import { readFileSync as readFileSync43, existsSync as existsSync57 } from "fs";
|
|
28477
|
-
import { resolve as
|
|
28477
|
+
import { resolve as resolve31 } from "path";
|
|
28478
28478
|
function deriveRoute(pageFile) {
|
|
28479
28479
|
let route = pageFile.replace(/^src\/app/, "").replace(/\/page\.tsx?$/, "").replace(/\/page\.jsx?$/, "");
|
|
28480
28480
|
return route || "/";
|
|
@@ -28512,7 +28512,7 @@ function findRouterCalls(files) {
|
|
|
28512
28512
|
const routers = /* @__PURE__ */ new Set();
|
|
28513
28513
|
const projectRoot = getProjectRoot();
|
|
28514
28514
|
for (const file of files) {
|
|
28515
|
-
const absPath = ensureWithinRoot(
|
|
28515
|
+
const absPath = ensureWithinRoot(resolve31(projectRoot, file), projectRoot);
|
|
28516
28516
|
if (!existsSync57(absPath)) continue;
|
|
28517
28517
|
try {
|
|
28518
28518
|
const source = readFileSync43(absPath, "utf-8");
|
|
@@ -28533,7 +28533,7 @@ function findTablesFromRouters(routerNames, dataDb) {
|
|
|
28533
28533
|
`SELECT DISTINCT router_file FROM ${t("trpc_procedures")} WHERE router_name = ? LIMIT 10000`
|
|
28534
28534
|
).all(routerName);
|
|
28535
28535
|
for (const proc of procs) {
|
|
28536
|
-
const absPath = ensureWithinRoot(
|
|
28536
|
+
const absPath = ensureWithinRoot(resolve31(getProjectRoot(), proc.router_file), getProjectRoot());
|
|
28537
28537
|
if (!existsSync57(absPath)) continue;
|
|
28538
28538
|
try {
|
|
28539
28539
|
const source = readFileSync43(absPath, "utf-8");
|
|
@@ -29089,11 +29089,11 @@ var init_import_parser = __esm({
|
|
|
29089
29089
|
|
|
29090
29090
|
// src/python/import-resolver.ts
|
|
29091
29091
|
import { readFileSync as readFileSync45, existsSync as existsSync59, readdirSync as readdirSync22 } from "fs";
|
|
29092
|
-
import { resolve as
|
|
29092
|
+
import { resolve as resolve33, join as join33, relative as relative8, dirname as dirname26 } from "path";
|
|
29093
29093
|
function resolvePythonModulePath(module, fromFile, pythonRoot, level) {
|
|
29094
29094
|
const projectRoot = getProjectRoot();
|
|
29095
29095
|
if (level > 0) {
|
|
29096
|
-
let baseDir = dirname26(
|
|
29096
|
+
let baseDir = dirname26(resolve33(projectRoot, fromFile));
|
|
29097
29097
|
for (let i = 1; i < level; i++) {
|
|
29098
29098
|
baseDir = dirname26(baseDir);
|
|
29099
29099
|
}
|
|
@@ -29105,7 +29105,7 @@ function resolvePythonModulePath(module, fromFile, pythonRoot, level) {
|
|
|
29105
29105
|
return tryResolvePythonPath(baseDir, projectRoot);
|
|
29106
29106
|
}
|
|
29107
29107
|
const parts = module.split(".");
|
|
29108
|
-
const candidate = join33(
|
|
29108
|
+
const candidate = join33(resolve33(projectRoot, pythonRoot), ...parts);
|
|
29109
29109
|
return tryResolvePythonPath(candidate, projectRoot);
|
|
29110
29110
|
}
|
|
29111
29111
|
function tryResolvePythonPath(basePath, projectRoot) {
|
|
@@ -29138,7 +29138,7 @@ function walkPythonFiles(dir, excludeDirs) {
|
|
|
29138
29138
|
}
|
|
29139
29139
|
function buildPythonImportIndex(dataDb, pythonRoot, excludeDirs = ["__pycache__", ".venv", "venv", ".mypy_cache", ".pytest_cache"]) {
|
|
29140
29140
|
const projectRoot = getProjectRoot();
|
|
29141
|
-
const absRoot =
|
|
29141
|
+
const absRoot = resolve33(projectRoot, pythonRoot);
|
|
29142
29142
|
dataDb.exec(`DELETE FROM ${t("py_imports")}`);
|
|
29143
29143
|
const insertStmt = dataDb.prepare(
|
|
29144
29144
|
`INSERT INTO ${t("py_imports")} (source_file, target_file, import_type, imported_names, line) VALUES (?, ?, ?, ?, ?)`
|
|
@@ -30469,7 +30469,7 @@ var init_memory_tools = __esm({
|
|
|
30469
30469
|
|
|
30470
30470
|
// src/docs-tools.ts
|
|
30471
30471
|
import { readFileSync as readFileSync50, existsSync as existsSync60 } from "fs";
|
|
30472
|
-
import { resolve as
|
|
30472
|
+
import { resolve as resolve34, basename as basename9 } from "path";
|
|
30473
30473
|
function p4(baseName) {
|
|
30474
30474
|
return `${getConfig().toolPrefix}_${baseName}`;
|
|
30475
30475
|
}
|
|
@@ -30597,9 +30597,9 @@ function extractFrontmatter(content) {
|
|
|
30597
30597
|
}
|
|
30598
30598
|
function extractProcedureNames(routerPath) {
|
|
30599
30599
|
const root = getProjectRoot();
|
|
30600
|
-
const absPath = ensureWithinRoot(
|
|
30600
|
+
const absPath = ensureWithinRoot(resolve34(getResolvedPaths().srcDir, "..", routerPath), root);
|
|
30601
30601
|
if (!existsSync60(absPath)) {
|
|
30602
|
-
const altPath = ensureWithinRoot(
|
|
30602
|
+
const altPath = ensureWithinRoot(resolve34(getResolvedPaths().srcDir, "../server/api/routers", basename9(routerPath)), root);
|
|
30603
30603
|
if (!existsSync60(altPath)) return [];
|
|
30604
30604
|
return extractProcedureNamesFromContent(readFileSync50(altPath, "utf-8"));
|
|
30605
30605
|
}
|
|
@@ -30643,7 +30643,7 @@ function handleDocsAudit(args2) {
|
|
|
30643
30643
|
for (const [mappingId, triggeringFiles] of affectedMappings) {
|
|
30644
30644
|
const mapping = docsMap.mappings.find((m3) => m3.id === mappingId);
|
|
30645
30645
|
if (!mapping) continue;
|
|
30646
|
-
const helpPagePath = ensureWithinRoot(
|
|
30646
|
+
const helpPagePath = ensureWithinRoot(resolve34(getResolvedPaths().helpSitePath, mapping.helpPage), getProjectRoot());
|
|
30647
30647
|
if (!existsSync60(helpPagePath)) {
|
|
30648
30648
|
results.push({
|
|
30649
30649
|
helpPage: mapping.helpPage,
|
|
@@ -30696,7 +30696,7 @@ function handleDocsAudit(args2) {
|
|
|
30696
30696
|
});
|
|
30697
30697
|
for (const [guideName, parentId] of Object.entries(docsMap.userGuideInheritance.examples)) {
|
|
30698
30698
|
if (parentId === mappingId) {
|
|
30699
|
-
const guidePath = ensureWithinRoot(
|
|
30699
|
+
const guidePath = ensureWithinRoot(resolve34(getResolvedPaths().helpSitePath, `pages/user-guides/${guideName}/index.mdx`), getProjectRoot());
|
|
30700
30700
|
if (existsSync60(guidePath)) {
|
|
30701
30701
|
const guideContent = readFileSync50(guidePath, "utf-8");
|
|
30702
30702
|
const guideFrontmatter = extractFrontmatter(guideContent);
|
|
@@ -30731,7 +30731,7 @@ function handleDocsCoverage(args2) {
|
|
|
30731
30731
|
const gaps = [];
|
|
30732
30732
|
const mappings = filterDomain ? docsMap.mappings.filter((m3) => m3.id === filterDomain) : docsMap.mappings;
|
|
30733
30733
|
for (const mapping of mappings) {
|
|
30734
|
-
const helpPagePath = ensureWithinRoot(
|
|
30734
|
+
const helpPagePath = ensureWithinRoot(resolve34(getResolvedPaths().helpSitePath, mapping.helpPage), getProjectRoot());
|
|
30735
30735
|
const exists = existsSync60(helpPagePath);
|
|
30736
30736
|
let hasContent = false;
|
|
30737
30737
|
let lineCount = 0;
|
|
@@ -31080,7 +31080,7 @@ var init_observability_tools = __esm({
|
|
|
31080
31080
|
|
|
31081
31081
|
// src/sentinel-db.ts
|
|
31082
31082
|
import { existsSync as existsSync61 } from "fs";
|
|
31083
|
-
import { resolve as
|
|
31083
|
+
import { resolve as resolve35 } from "path";
|
|
31084
31084
|
function parsePortalScope(raw) {
|
|
31085
31085
|
if (!raw) return [];
|
|
31086
31086
|
try {
|
|
@@ -31316,22 +31316,22 @@ function validateFeatures(db, domainFilter) {
|
|
|
31316
31316
|
const missingProcedures = [];
|
|
31317
31317
|
const missingPages = [];
|
|
31318
31318
|
for (const comp of components) {
|
|
31319
|
-
const absPath =
|
|
31319
|
+
const absPath = resolve35(PROJECT_ROOT, comp.component_file);
|
|
31320
31320
|
if (!existsSync61(absPath)) {
|
|
31321
31321
|
missingComponents.push(comp.component_file);
|
|
31322
31322
|
}
|
|
31323
31323
|
}
|
|
31324
31324
|
for (const proc of procedures) {
|
|
31325
|
-
const routerPath =
|
|
31325
|
+
const routerPath = resolve35(PROJECT_ROOT, `src/server/api/routers/${proc.router_name}.ts`);
|
|
31326
31326
|
if (!existsSync61(routerPath)) {
|
|
31327
31327
|
missingProcedures.push({ router: proc.router_name, procedure: proc.procedure_name });
|
|
31328
31328
|
}
|
|
31329
31329
|
}
|
|
31330
31330
|
for (const page of pages) {
|
|
31331
31331
|
const routeToPath = page.page_route.replace(/^\/(portal-[^/]+\/)?/, "src/app/").replace(/\/$/, "") + "/page.tsx";
|
|
31332
|
-
const absPath =
|
|
31332
|
+
const absPath = resolve35(PROJECT_ROOT, routeToPath);
|
|
31333
31333
|
if (page.page_route.startsWith("/") && !existsSync61(absPath)) {
|
|
31334
|
-
const altPath =
|
|
31334
|
+
const altPath = resolve35(PROJECT_ROOT, `src/app${page.page_route}/page.tsx`);
|
|
31335
31335
|
if (!existsSync61(altPath)) {
|
|
31336
31336
|
missingPages.push(page.page_route);
|
|
31337
31337
|
}
|
|
@@ -31859,7 +31859,7 @@ var init_sentinel_tools = __esm({
|
|
|
31859
31859
|
|
|
31860
31860
|
// src/sentinel-scanner.ts
|
|
31861
31861
|
import { readFileSync as readFileSync51, existsSync as existsSync62, readdirSync as readdirSync27, statSync as statSync20 } from "fs";
|
|
31862
|
-
import { resolve as
|
|
31862
|
+
import { resolve as resolve36, join as join38, basename as basename10, dirname as dirname27, relative as relative13 } from "path";
|
|
31863
31863
|
function inferDomain(filePath) {
|
|
31864
31864
|
const domains = getConfig().domains;
|
|
31865
31865
|
const path = filePath.toLowerCase();
|
|
@@ -31990,7 +31990,7 @@ function scanComponentExports(dataDb) {
|
|
|
31990
31990
|
const projectRoot = getProjectRoot();
|
|
31991
31991
|
const componentsBase = config.paths.components ?? config.paths.source + "/components";
|
|
31992
31992
|
const componentDirs = [];
|
|
31993
|
-
const basePath =
|
|
31993
|
+
const basePath = resolve36(projectRoot, componentsBase);
|
|
31994
31994
|
if (existsSync62(basePath)) {
|
|
31995
31995
|
try {
|
|
31996
31996
|
const entries = readdirSync27(basePath, { withFileTypes: true });
|
|
@@ -32003,7 +32003,7 @@ function scanComponentExports(dataDb) {
|
|
|
32003
32003
|
}
|
|
32004
32004
|
}
|
|
32005
32005
|
for (const dir of componentDirs) {
|
|
32006
|
-
const absDir =
|
|
32006
|
+
const absDir = resolve36(projectRoot, dir);
|
|
32007
32007
|
if (!existsSync62(absDir)) continue;
|
|
32008
32008
|
const files = walkDir2(absDir).filter((f2) => f2.endsWith(".tsx") || f2.endsWith(".ts"));
|
|
32009
32009
|
for (const file of files) {
|
|
@@ -33588,7 +33588,7 @@ var init_security_scorer = __esm({
|
|
|
33588
33588
|
|
|
33589
33589
|
// src/dependency-scorer.ts
|
|
33590
33590
|
import { existsSync as existsSync65, readFileSync as readFileSync54 } from "fs";
|
|
33591
|
-
import { resolve as
|
|
33591
|
+
import { resolve as resolve37 } from "path";
|
|
33592
33592
|
function p13(baseName) {
|
|
33593
33593
|
return `${getConfig().toolPrefix}_${baseName}`;
|
|
33594
33594
|
}
|
|
@@ -33620,7 +33620,7 @@ function calculateDepRisk(factors) {
|
|
|
33620
33620
|
return Math.min(100, risk);
|
|
33621
33621
|
}
|
|
33622
33622
|
function getInstalledPackages(projectRoot) {
|
|
33623
|
-
const pkgPath =
|
|
33623
|
+
const pkgPath = resolve37(projectRoot, "package.json");
|
|
33624
33624
|
if (!existsSync65(pkgPath)) return /* @__PURE__ */ new Map();
|
|
33625
33625
|
try {
|
|
33626
33626
|
const pkg = JSON.parse(readFileSync54(pkgPath, "utf-8"));
|
|
@@ -34230,7 +34230,7 @@ var init_regression_detector = __esm({
|
|
|
34230
34230
|
// src/knowledge-indexer.ts
|
|
34231
34231
|
import { createHash as createHash16 } from "crypto";
|
|
34232
34232
|
import { readFileSync as readFileSync55, readdirSync as readdirSync28, statSync as statSync21, existsSync as existsSync66 } from "fs";
|
|
34233
|
-
import { resolve as
|
|
34233
|
+
import { resolve as resolve38, relative as relative14, basename as basename11, extname as extname2 } from "path";
|
|
34234
34234
|
function getKnowledgePaths() {
|
|
34235
34235
|
const resolved = getResolvedPaths();
|
|
34236
34236
|
const config = getConfig();
|
|
@@ -34258,7 +34258,7 @@ function discoverMarkdownFiles(baseDir) {
|
|
|
34258
34258
|
try {
|
|
34259
34259
|
const entries = readdirSync28(dir, { withFileTypes: true });
|
|
34260
34260
|
for (const entry of entries) {
|
|
34261
|
-
const fullPath =
|
|
34261
|
+
const fullPath = resolve38(dir, entry.name);
|
|
34262
34262
|
if (entry.isDirectory()) {
|
|
34263
34263
|
if (entry.name === "archive" && dir.includes("session-state")) continue;
|
|
34264
34264
|
if (entry.name === "archive" && dir.includes("status")) continue;
|
|
@@ -34753,7 +34753,7 @@ var init_knowledge_indexer = __esm({
|
|
|
34753
34753
|
|
|
34754
34754
|
// src/knowledge-tools.ts
|
|
34755
34755
|
import { readFileSync as readFileSync56, writeFileSync as writeFileSync16, appendFileSync as appendFileSync5, readdirSync as readdirSync29 } from "fs";
|
|
34756
|
-
import { resolve as
|
|
34756
|
+
import { resolve as resolve39, basename as basename12 } from "path";
|
|
34757
34757
|
function p16(baseName) {
|
|
34758
34758
|
return `${getConfig().toolPrefix}_${baseName}`;
|
|
34759
34759
|
}
|
|
@@ -35492,7 +35492,7 @@ function handleCorrect(db, args2) {
|
|
|
35492
35492
|
if (!wrong || !correction || !rule) {
|
|
35493
35493
|
return text15("Error: wrong, correction, and rule are all required.");
|
|
35494
35494
|
}
|
|
35495
|
-
const correctionsPath =
|
|
35495
|
+
const correctionsPath = resolve39(getResolvedPaths().memoryDir, "corrections.md");
|
|
35496
35496
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
35497
35497
|
const title = rule.slice(0, 60);
|
|
35498
35498
|
const entry = formatCorrectionEntry({
|
|
@@ -36462,7 +36462,7 @@ var init_framework_supports = __esm({
|
|
|
36462
36462
|
|
|
36463
36463
|
// src/tools.ts
|
|
36464
36464
|
import { readFileSync as readFileSync57, existsSync as existsSync68 } from "fs";
|
|
36465
|
-
import { resolve as
|
|
36465
|
+
import { resolve as resolve40, basename as basename13 } from "path";
|
|
36466
36466
|
function prefix2() {
|
|
36467
36467
|
return getConfig().toolPrefix;
|
|
36468
36468
|
}
|
|
@@ -36497,7 +36497,7 @@ function ensureIndexes(dataDb, codegraphDb, force = false) {
|
|
|
36497
36497
|
if (config.python?.root) {
|
|
36498
36498
|
const pythonRoot = config.python.root;
|
|
36499
36499
|
const excludeDirs = config.python.exclude_dirs || ["__pycache__", ".venv", "venv", ".mypy_cache", ".pytest_cache"];
|
|
36500
|
-
if (force || isPythonDataStale(dataDb,
|
|
36500
|
+
if (force || isPythonDataStale(dataDb, resolve40(getProjectRoot(), pythonRoot))) {
|
|
36501
36501
|
const pyImports = buildPythonImportIndex(dataDb, pythonRoot, excludeDirs);
|
|
36502
36502
|
results.push(`Python imports: ${pyImports}`);
|
|
36503
36503
|
const pyRoutes = buildPythonRouteIndex(dataDb, pythonRoot, excludeDirs);
|
|
@@ -36880,7 +36880,7 @@ function handleContext(file, dataDb, codegraphDb) {
|
|
|
36880
36880
|
try {
|
|
36881
36881
|
const resolvedPaths = getResolvedPaths();
|
|
36882
36882
|
const root = getProjectRoot();
|
|
36883
|
-
const absFilePath = ensureWithinRoot(
|
|
36883
|
+
const absFilePath = ensureWithinRoot(resolve40(resolvedPaths.srcDir, "..", file), root);
|
|
36884
36884
|
if (existsSync68(absFilePath)) {
|
|
36885
36885
|
const fileContent = readFileSync57(absFilePath, "utf-8").slice(0, 3e3);
|
|
36886
36886
|
const keywords = [];
|
|
@@ -37319,7 +37319,7 @@ function handleSchema(args2) {
|
|
|
37319
37319
|
lines.push("Checking all column references against Prisma schema...");
|
|
37320
37320
|
lines.push("");
|
|
37321
37321
|
const projectRoot = getProjectRoot();
|
|
37322
|
-
const absPath = ensureWithinRoot(
|
|
37322
|
+
const absPath = ensureWithinRoot(resolve40(projectRoot, file), projectRoot);
|
|
37323
37323
|
if (!existsSync68(absPath)) {
|
|
37324
37324
|
return text17(`File not found: ${file}`);
|
|
37325
37325
|
}
|
|
@@ -37756,7 +37756,7 @@ var init_startup_health = __esm({
|
|
|
37756
37756
|
// src/server.ts
|
|
37757
37757
|
var server_exports = {};
|
|
37758
37758
|
import { readFileSync as readFileSync58 } from "fs";
|
|
37759
|
-
import { resolve as
|
|
37759
|
+
import { resolve as resolve41, dirname as dirname28 } from "path";
|
|
37760
37760
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
37761
37761
|
function pruneMemoryOnStartup() {
|
|
37762
37762
|
try {
|
|
@@ -37804,7 +37804,7 @@ var init_server = __esm({
|
|
|
37804
37804
|
__dirname5 = dirname28(fileURLToPath6(import.meta.url));
|
|
37805
37805
|
PKG_VERSION = (() => {
|
|
37806
37806
|
try {
|
|
37807
|
-
const pkg = JSON.parse(readFileSync58(
|
|
37807
|
+
const pkg = JSON.parse(readFileSync58(resolve41(__dirname5, "..", "package.json"), "utf-8"));
|
|
37808
37808
|
return pkg.version ?? "0.0.0";
|
|
37809
37809
|
} catch {
|
|
37810
37810
|
return "0.0.0";
|
|
@@ -38108,11 +38108,11 @@ __export(config_upgrade_exports, {
|
|
|
38108
38108
|
runConfigUpgrade: () => runConfigUpgrade
|
|
38109
38109
|
});
|
|
38110
38110
|
import { existsSync as existsSync69, readFileSync as readFileSync59, writeFileSync as writeFileSync17, copyFileSync as copyFileSync3, unlinkSync as unlinkSync6 } from "fs";
|
|
38111
|
-
import { resolve as
|
|
38111
|
+
import { resolve as resolve42 } from "path";
|
|
38112
38112
|
import { parse as parseYaml6 } from "yaml";
|
|
38113
38113
|
async function runConfigUpgrade(opts = {}) {
|
|
38114
38114
|
const cwd = opts.cwd ?? process.cwd();
|
|
38115
|
-
const configPath =
|
|
38115
|
+
const configPath = resolve42(cwd, "massu.config.yaml");
|
|
38116
38116
|
const bakPath = `${configPath}.bak`;
|
|
38117
38117
|
const log = opts.silent ? () => {
|
|
38118
38118
|
} : (s) => process.stdout.write(s);
|
|
@@ -38200,7 +38200,7 @@ __export(config_check_drift_exports, {
|
|
|
38200
38200
|
runConfigCheckDrift: () => runConfigCheckDrift
|
|
38201
38201
|
});
|
|
38202
38202
|
import { existsSync as existsSync70, readFileSync as readFileSync60 } from "fs";
|
|
38203
|
-
import { resolve as
|
|
38203
|
+
import { resolve as resolve43 } from "path";
|
|
38204
38204
|
import { parse as parseYaml7 } from "yaml";
|
|
38205
38205
|
function renderChanges(changes) {
|
|
38206
38206
|
if (changes.length === 0) return "(none)\n";
|
|
@@ -38208,7 +38208,7 @@ function renderChanges(changes) {
|
|
|
38208
38208
|
}
|
|
38209
38209
|
async function runConfigCheckDrift(opts = {}) {
|
|
38210
38210
|
const cwd = opts.cwd ?? process.cwd();
|
|
38211
|
-
const configPath =
|
|
38211
|
+
const configPath = resolve43(cwd, "massu.config.yaml");
|
|
38212
38212
|
const log = opts.silent ? () => {
|
|
38213
38213
|
} : (s) => process.stdout.write(s);
|
|
38214
38214
|
const err = opts.silent ? () => {
|
|
@@ -38295,29 +38295,30 @@ var init_config_check_drift = __esm({
|
|
|
38295
38295
|
|
|
38296
38296
|
// src/cli.ts
|
|
38297
38297
|
import { readFileSync as readFileSync61 } from "fs";
|
|
38298
|
-
import { resolve as
|
|
38298
|
+
import { resolve as resolve44, dirname as dirname29 } from "path";
|
|
38299
38299
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
38300
38300
|
|
|
38301
38301
|
// src/lib/node-bootstrap.ts
|
|
38302
38302
|
init_node_floor();
|
|
38303
|
-
import { existsSync, readdirSync, statSync } from "fs";
|
|
38303
|
+
import { existsSync, readdirSync, statSync, realpathSync } from "fs";
|
|
38304
38304
|
import { spawnSync, execFileSync } from "child_process";
|
|
38305
38305
|
import { homedir } from "os";
|
|
38306
|
-
import {
|
|
38306
|
+
import { win32 as pathWin32, posix as pathPosix } from "path";
|
|
38307
38307
|
var REEXEC_SENTINEL_ENV = "MASSU_BOOTSTRAP_REEXEC";
|
|
38308
38308
|
var OPT_OUT_ENV = "MASSU_NO_NODE_BOOTSTRAP";
|
|
38309
|
-
function allowlistPatterns(env) {
|
|
38309
|
+
function allowlistPatterns(env, platform = process.platform) {
|
|
38310
|
+
if (platform === "win32") return windowsAllowlistPatterns(env);
|
|
38310
38311
|
const patterns = [];
|
|
38311
38312
|
const rawHome = env.HOME || homedir();
|
|
38312
|
-
const home = rawHome && isAbsolute(rawHome) ? rawHome : null;
|
|
38313
|
+
const home = rawHome && pathPosix.isAbsolute(rawHome) ? rawHome : null;
|
|
38313
38314
|
const addAbs = (dir, suffix) => {
|
|
38314
|
-
if (dir && isAbsolute(dir)) patterns.push(resolve(dir, suffix));
|
|
38315
|
+
if (dir && pathPosix.isAbsolute(dir)) patterns.push(pathPosix.resolve(dir, suffix));
|
|
38315
38316
|
};
|
|
38316
|
-
addAbs(env.NVM_DIR ?? (home && resolve(home, ".nvm")), "versions/node/*/bin/node");
|
|
38317
|
-
addAbs(env.FNM_DIR ?? (home && resolve(home, ".local/share/fnm")), "node-versions/*/installation/bin/node");
|
|
38318
|
-
addAbs(env.VOLTA_HOME ?? (home && resolve(home, ".volta")), "tools/image/node/*/bin/node");
|
|
38319
|
-
addAbs(env.ASDF_DATA_DIR ?? (home && resolve(home, ".asdf")), "installs/nodejs/*/bin/node");
|
|
38320
|
-
addAbs(env.N_PREFIX ?? (home && resolve(home, "n")), "bin/node");
|
|
38317
|
+
addAbs(env.NVM_DIR ?? (home && pathPosix.resolve(home, ".nvm")), "versions/node/*/bin/node");
|
|
38318
|
+
addAbs(env.FNM_DIR ?? (home && pathPosix.resolve(home, ".local/share/fnm")), "node-versions/*/installation/bin/node");
|
|
38319
|
+
addAbs(env.VOLTA_HOME ?? (home && pathPosix.resolve(home, ".volta")), "tools/image/node/*/bin/node");
|
|
38320
|
+
addAbs(env.ASDF_DATA_DIR ?? (home && pathPosix.resolve(home, ".asdf")), "installs/nodejs/*/bin/node");
|
|
38321
|
+
addAbs(env.N_PREFIX ?? (home && pathPosix.resolve(home, "n")), "bin/node");
|
|
38321
38322
|
patterns.push(
|
|
38322
38323
|
"/opt/homebrew/opt/node@*/bin/node",
|
|
38323
38324
|
"/usr/local/opt/node@*/bin/node",
|
|
@@ -38326,6 +38327,44 @@ function allowlistPatterns(env) {
|
|
|
38326
38327
|
);
|
|
38327
38328
|
return patterns;
|
|
38328
38329
|
}
|
|
38330
|
+
function winManagerDirs(env) {
|
|
38331
|
+
const abs = (d2) => d2 && pathWin32.isAbsolute(d2) ? d2 : null;
|
|
38332
|
+
const appdata = abs(env.APPDATA);
|
|
38333
|
+
const localappdata = abs(env.LOCALAPPDATA);
|
|
38334
|
+
return {
|
|
38335
|
+
userprofile: abs(env.USERPROFILE),
|
|
38336
|
+
nvmHome: abs(env.NVM_HOME),
|
|
38337
|
+
nvmSymlink: abs(env.NVM_SYMLINK),
|
|
38338
|
+
fnmDir: abs(env.FNM_DIR) ?? (appdata ? `${appdata}\\fnm` : null),
|
|
38339
|
+
voltaHome: abs(env.VOLTA_HOME) ?? (localappdata ? `${localappdata}\\Volta` : null),
|
|
38340
|
+
localappdata
|
|
38341
|
+
};
|
|
38342
|
+
}
|
|
38343
|
+
function windowsAllowlistRoots(env) {
|
|
38344
|
+
const d2 = winManagerDirs(env);
|
|
38345
|
+
const roots = [];
|
|
38346
|
+
for (const r2 of [d2.userprofile, d2.nvmHome, d2.nvmSymlink, d2.fnmDir, d2.voltaHome, d2.localappdata]) {
|
|
38347
|
+
if (r2) roots.push(r2);
|
|
38348
|
+
}
|
|
38349
|
+
roots.push("C:\\Program Files\\nodejs", "C:\\Program Files (x86)\\nodejs");
|
|
38350
|
+
return roots;
|
|
38351
|
+
}
|
|
38352
|
+
function windowsAllowlistPatterns(env) {
|
|
38353
|
+
const d2 = winManagerDirs(env);
|
|
38354
|
+
const patterns = [];
|
|
38355
|
+
const add = (dir, suffix) => {
|
|
38356
|
+
if (dir) patterns.push(`${dir}\\${suffix}`);
|
|
38357
|
+
};
|
|
38358
|
+
add(d2.nvmHome, "v*\\node.exe");
|
|
38359
|
+
add(d2.nvmSymlink, "node.exe");
|
|
38360
|
+
add(d2.fnmDir, "node-versions\\v*\\installation\\node.exe");
|
|
38361
|
+
add(d2.voltaHome, "tools\\image\\node\\*\\node.exe");
|
|
38362
|
+
add(d2.userprofile, "scoop\\apps\\nodejs\\current\\node.exe");
|
|
38363
|
+
add(d2.userprofile, "scoop\\apps\\nodejs-lts\\current\\node.exe");
|
|
38364
|
+
add(d2.localappdata, "Programs\\nodejs\\node.exe");
|
|
38365
|
+
patterns.push("C:\\Program Files\\nodejs\\node.exe", "C:\\Program Files (x86)\\nodejs\\node.exe");
|
|
38366
|
+
return patterns;
|
|
38367
|
+
}
|
|
38329
38368
|
function isOwnershipTrusted(candidate) {
|
|
38330
38369
|
const getuid = process.getuid;
|
|
38331
38370
|
if (typeof getuid !== "function") return true;
|
|
@@ -38336,8 +38375,22 @@ function isOwnershipTrusted(candidate) {
|
|
|
38336
38375
|
return false;
|
|
38337
38376
|
}
|
|
38338
38377
|
}
|
|
38378
|
+
function isWindowsTrusted(candidate, env) {
|
|
38379
|
+
let resolved;
|
|
38380
|
+
try {
|
|
38381
|
+
resolved = pathWin32.resolve(realpathSync(candidate));
|
|
38382
|
+
} catch {
|
|
38383
|
+
resolved = pathWin32.resolve(candidate);
|
|
38384
|
+
}
|
|
38385
|
+
const target = resolved.toLowerCase();
|
|
38386
|
+
for (const root of windowsAllowlistRoots(env)) {
|
|
38387
|
+
const base = pathWin32.resolve(root).toLowerCase();
|
|
38388
|
+
if (target === base || target.startsWith(base + pathWin32.sep)) return true;
|
|
38389
|
+
}
|
|
38390
|
+
return false;
|
|
38391
|
+
}
|
|
38339
38392
|
function expandSingleStarGlob(pattern) {
|
|
38340
|
-
const parts = pattern.split(
|
|
38393
|
+
const parts = pattern.split(/[\\/]/);
|
|
38341
38394
|
const starIdx = parts.findIndex((p19) => p19.includes("*"));
|
|
38342
38395
|
if (starIdx === -1) {
|
|
38343
38396
|
return existsSync(pattern) ? [pattern] : [];
|
|
@@ -38371,16 +38424,23 @@ function probeNodeVersion(candidate) {
|
|
|
38371
38424
|
return null;
|
|
38372
38425
|
}
|
|
38373
38426
|
}
|
|
38374
|
-
function
|
|
38427
|
+
function isAcceptedCandidatePath(candidate, platform = process.platform) {
|
|
38428
|
+
if (platform === "win32") {
|
|
38429
|
+
return pathWin32.isAbsolute(candidate) && (/^[A-Za-z]:[\\/]/.test(candidate) || candidate.startsWith("\\\\"));
|
|
38430
|
+
}
|
|
38431
|
+
return candidate.startsWith("/");
|
|
38432
|
+
}
|
|
38433
|
+
function discoverCompatibleNode(env = process.env, platform = process.platform) {
|
|
38375
38434
|
const seen = /* @__PURE__ */ new Set();
|
|
38376
38435
|
let best = null;
|
|
38377
|
-
for (const pattern of allowlistPatterns(env)) {
|
|
38436
|
+
for (const pattern of allowlistPatterns(env, platform)) {
|
|
38378
38437
|
for (const candidate of expandSingleStarGlob(pattern)) {
|
|
38379
|
-
if (!candidate
|
|
38438
|
+
if (!isAcceptedCandidatePath(candidate, platform)) continue;
|
|
38380
38439
|
if (seen.has(candidate)) continue;
|
|
38381
38440
|
seen.add(candidate);
|
|
38382
38441
|
if (!existsSync(candidate)) continue;
|
|
38383
|
-
|
|
38442
|
+
const trusted = platform === "win32" ? isWindowsTrusted(candidate, env) : isOwnershipTrusted(candidate);
|
|
38443
|
+
if (!trusted) continue;
|
|
38384
38444
|
const v3 = probeNodeVersion(candidate);
|
|
38385
38445
|
if (!v3) continue;
|
|
38386
38446
|
if (!checkNodeVersion(`v${v3}`).ok) continue;
|
|
@@ -38737,7 +38797,7 @@ Examples:
|
|
|
38737
38797
|
}
|
|
38738
38798
|
function printVersion() {
|
|
38739
38799
|
try {
|
|
38740
|
-
const pkg = JSON.parse(readFileSync61(
|
|
38800
|
+
const pkg = JSON.parse(readFileSync61(resolve44(__dirname6, "../package.json"), "utf-8"));
|
|
38741
38801
|
console.log(`massu v${pkg.version}`);
|
|
38742
38802
|
} catch {
|
|
38743
38803
|
console.log("massu v0.1.0");
|