@massu/core 1.5.7 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter.d.ts +76 -0
- package/dist/adapter.js +431 -0
- package/dist/cli.js +818 -356
- package/dist/detect/adapters/.bundle-shasums.json +12 -0
- package/dist/detect/adapters/aspnet.js +577 -0
- package/dist/detect/adapters/go-chi.js +561 -0
- package/dist/detect/adapters/parse-guard.d.ts +69 -0
- package/dist/detect/adapters/parse-guard.js +54 -0
- package/dist/detect/adapters/phoenix.js +556 -0
- package/dist/detect/adapters/query-helpers.d.ts +60 -0
- package/dist/detect/adapters/query-helpers.js +85 -0
- package/dist/detect/adapters/rails.js +567 -0
- package/dist/detect/adapters/spring.js +582 -0
- package/dist/detect/adapters/tree-sitter-loader.d.ts +102 -0
- package/dist/detect/adapters/tree-sitter-loader.js +317 -0
- package/dist/detect/adapters/types.d.ts +151 -0
- package/dist/detect/adapters/types.js +0 -0
- package/dist/hooks/session-start.js +570 -5224
- package/package.json +17 -5
- package/src/adapter.ts +31 -0
- package/src/detect/adapters/aspnet.ts +4 -293
- package/src/detect/adapters/go-chi.ts +4 -261
- package/src/detect/adapters/phoenix.ts +4 -277
- package/src/detect/adapters/rails.ts +4 -279
- package/src/detect/adapters/spring.ts +4 -284
- package/src/security/registry-pubkey.generated.ts +1 -1
package/dist/cli.js
CHANGED
|
@@ -11159,22 +11159,440 @@ var init_python_flask = __esm({
|
|
|
11159
11159
|
}
|
|
11160
11160
|
});
|
|
11161
11161
|
|
|
11162
|
-
//
|
|
11163
|
-
import {
|
|
11162
|
+
// dist/adapter.js
|
|
11163
|
+
import { Query as Query2 } from "web-tree-sitter";
|
|
11164
|
+
import { createHash as createHash3 } from "crypto";
|
|
11165
|
+
import {
|
|
11166
|
+
mkdirSync as mkdirSync4,
|
|
11167
|
+
readdirSync as readdirSync9,
|
|
11168
|
+
readFileSync as readFileSync9,
|
|
11169
|
+
writeFileSync as writeFileSync2,
|
|
11170
|
+
renameSync as renameSync3,
|
|
11171
|
+
unlinkSync as unlinkSync2,
|
|
11172
|
+
lstatSync as lstatSync4,
|
|
11173
|
+
chmodSync as chmodSync2,
|
|
11174
|
+
utimesSync as utimesSync2
|
|
11175
|
+
} from "fs";
|
|
11176
|
+
import { homedir as homedir3 } from "os";
|
|
11177
|
+
import { dirname as dirname5, join as join9 } from "path";
|
|
11178
|
+
import { Language as Language2, Parser as Parser7 } from "web-tree-sitter";
|
|
11179
|
+
function compileQuery2(language, source, queryName) {
|
|
11180
|
+
let perLang = queryCache2.get(language);
|
|
11181
|
+
if (!perLang) {
|
|
11182
|
+
perLang = /* @__PURE__ */ new Map();
|
|
11183
|
+
queryCache2.set(language, perLang);
|
|
11184
|
+
}
|
|
11185
|
+
const cached = perLang.get(source);
|
|
11186
|
+
if (cached) return cached;
|
|
11187
|
+
let q2;
|
|
11188
|
+
try {
|
|
11189
|
+
q2 = new Query2(language, source);
|
|
11190
|
+
} catch (e2) {
|
|
11191
|
+
throw new InvalidQueryError2(queryName, source, e2);
|
|
11192
|
+
}
|
|
11193
|
+
perLang.set(source, q2);
|
|
11194
|
+
return q2;
|
|
11195
|
+
}
|
|
11196
|
+
function runQuery2(parser, source, queryText, queryName, filePath) {
|
|
11197
|
+
const language = parser.language;
|
|
11198
|
+
if (!language) {
|
|
11199
|
+
throw new InvalidQueryError2(
|
|
11200
|
+
queryName,
|
|
11201
|
+
queryText,
|
|
11202
|
+
new Error("Parser has no language assigned")
|
|
11203
|
+
);
|
|
11204
|
+
}
|
|
11205
|
+
const query = compileQuery2(language, queryText, queryName);
|
|
11206
|
+
const tree = parser.parse(source);
|
|
11207
|
+
if (!tree) return [];
|
|
11208
|
+
let matches;
|
|
11209
|
+
try {
|
|
11210
|
+
matches = query.matches(tree.rootNode);
|
|
11211
|
+
} catch (e2) {
|
|
11212
|
+
throw new InvalidQueryError2(queryName, queryText, e2);
|
|
11213
|
+
}
|
|
11214
|
+
const out = [];
|
|
11215
|
+
for (const match of matches) {
|
|
11216
|
+
if (!match.captures || match.captures.length === 0) continue;
|
|
11217
|
+
const captures = {};
|
|
11218
|
+
let earliestLine = Number.POSITIVE_INFINITY;
|
|
11219
|
+
for (const cap of match.captures) {
|
|
11220
|
+
const node = cap.node;
|
|
11221
|
+
captures[cap.name] = node.text;
|
|
11222
|
+
if (node.startPosition.row + 1 < earliestLine) {
|
|
11223
|
+
earliestLine = node.startPosition.row + 1;
|
|
11224
|
+
}
|
|
11225
|
+
}
|
|
11226
|
+
out.push({
|
|
11227
|
+
captures,
|
|
11228
|
+
file: filePath,
|
|
11229
|
+
line: Number.isFinite(earliestLine) ? earliestLine : 1,
|
|
11230
|
+
queryName
|
|
11231
|
+
});
|
|
11232
|
+
}
|
|
11233
|
+
try {
|
|
11234
|
+
tree.delete();
|
|
11235
|
+
} catch {
|
|
11236
|
+
}
|
|
11237
|
+
return out;
|
|
11238
|
+
}
|
|
11239
|
+
function getCacheDir2() {
|
|
11240
|
+
return process.env.MASSU_WASM_CACHE_DIR ?? join9(homedir3(), ".massu", "wasm-cache");
|
|
11241
|
+
}
|
|
11242
|
+
function getCachedPath2(language, sha) {
|
|
11243
|
+
return join9(getCacheDir2(), `${language}-${sha}.wasm`);
|
|
11244
|
+
}
|
|
11245
|
+
function getCacheRetainCount2() {
|
|
11246
|
+
const env = process.env.MASSU_WASM_CACHE_RETAIN;
|
|
11247
|
+
if (env) {
|
|
11248
|
+
const n = Number(env);
|
|
11249
|
+
if (Number.isFinite(n) && n >= 1 && n <= 1024) return Math.floor(n);
|
|
11250
|
+
}
|
|
11251
|
+
return DEFAULT_CACHE_RETAIN_COUNT2;
|
|
11252
|
+
}
|
|
11253
|
+
function touchCacheFile2(path) {
|
|
11254
|
+
try {
|
|
11255
|
+
const now = /* @__PURE__ */ new Date();
|
|
11256
|
+
utimesSync2(path, now, now);
|
|
11257
|
+
} catch {
|
|
11258
|
+
}
|
|
11259
|
+
}
|
|
11260
|
+
function evictBeyondRetainCount2(retain = getCacheRetainCount2()) {
|
|
11261
|
+
const dir = getCacheDir2();
|
|
11262
|
+
let entries;
|
|
11263
|
+
try {
|
|
11264
|
+
entries = readdirSync9(dir);
|
|
11265
|
+
} catch {
|
|
11266
|
+
return;
|
|
11267
|
+
}
|
|
11268
|
+
const candidates = [];
|
|
11269
|
+
for (const name of entries) {
|
|
11270
|
+
if (!name.endsWith(".wasm")) continue;
|
|
11271
|
+
const path = join9(dir, name);
|
|
11272
|
+
let stat;
|
|
11273
|
+
try {
|
|
11274
|
+
stat = lstatSync4(path);
|
|
11275
|
+
} catch {
|
|
11276
|
+
continue;
|
|
11277
|
+
}
|
|
11278
|
+
if (stat.isSymbolicLink() || !stat.isFile()) {
|
|
11279
|
+
console.error(
|
|
11280
|
+
`[tree-sitter-loader] cache eviction skipped non-regular file: ${path} (possible symlink attack \u2014 see Phase 3.5 finding F-008).`
|
|
11281
|
+
);
|
|
11282
|
+
continue;
|
|
11283
|
+
}
|
|
11284
|
+
candidates.push({ path, mtimeMs: stat.mtimeMs });
|
|
11285
|
+
}
|
|
11286
|
+
if (candidates.length <= retain) return;
|
|
11287
|
+
candidates.sort((a2, b2) => b2.mtimeMs - a2.mtimeMs);
|
|
11288
|
+
for (const victim of candidates.slice(retain)) {
|
|
11289
|
+
try {
|
|
11290
|
+
unlinkSync2(victim.path);
|
|
11291
|
+
} catch {
|
|
11292
|
+
}
|
|
11293
|
+
}
|
|
11294
|
+
}
|
|
11295
|
+
function sha2562(bytes) {
|
|
11296
|
+
return createHash3("sha256").update(bytes).digest("hex");
|
|
11297
|
+
}
|
|
11298
|
+
async function ensureParserInitialized2() {
|
|
11299
|
+
if (parserInitPromise2) return parserInitPromise2;
|
|
11300
|
+
parserInitPromise2 = Parser7.init();
|
|
11301
|
+
return parserInitPromise2;
|
|
11302
|
+
}
|
|
11303
|
+
async function loadGrammar2(language, options = {}) {
|
|
11304
|
+
await ensureParserInitialized2();
|
|
11305
|
+
const cached = loadedGrammars2.get(language);
|
|
11306
|
+
if (cached) return cached;
|
|
11307
|
+
const manifest = options.manifestOverride?.[language] ?? GRAMMAR_MANIFEST2[language];
|
|
11308
|
+
if (!manifest) {
|
|
11309
|
+
throw new GrammarUnavailableError2(
|
|
11310
|
+
language,
|
|
11311
|
+
new Error(`No manifest entry for language "${language}". v1 supports: ${Object.keys(GRAMMAR_MANIFEST2).join(", ")}.`)
|
|
11312
|
+
);
|
|
11313
|
+
}
|
|
11314
|
+
const cachePath = getCachedPath2(language, manifest.sha256);
|
|
11315
|
+
let cacheLstat;
|
|
11316
|
+
try {
|
|
11317
|
+
cacheLstat = lstatSync4(cachePath);
|
|
11318
|
+
} catch {
|
|
11319
|
+
cacheLstat = null;
|
|
11320
|
+
}
|
|
11321
|
+
if (cacheLstat) {
|
|
11322
|
+
if (cacheLstat.isSymbolicLink() || !cacheLstat.isFile()) {
|
|
11323
|
+
throw new GrammarCacheSymlinkError2(cachePath);
|
|
11324
|
+
}
|
|
11325
|
+
let bytes;
|
|
11326
|
+
try {
|
|
11327
|
+
bytes = readFileSync9(cachePath);
|
|
11328
|
+
} catch (e2) {
|
|
11329
|
+
bytes = new Uint8Array(0);
|
|
11330
|
+
}
|
|
11331
|
+
if (bytes.byteLength > 0) {
|
|
11332
|
+
const actualSha = sha2562(bytes);
|
|
11333
|
+
if (actualSha !== manifest.sha256) {
|
|
11334
|
+
throw new GrammarSHAMismatchError2(language, manifest.sha256, actualSha);
|
|
11335
|
+
}
|
|
11336
|
+
const lang2 = await Language2.load(bytes);
|
|
11337
|
+
loadedGrammars2.set(language, lang2);
|
|
11338
|
+
touchCacheFile2(cachePath);
|
|
11339
|
+
return lang2;
|
|
11340
|
+
}
|
|
11341
|
+
}
|
|
11342
|
+
if (!/^https:\/\//i.test(manifest.url)) {
|
|
11343
|
+
throw new GrammarUrlNotHttpsError2(manifest.url);
|
|
11344
|
+
}
|
|
11345
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
11346
|
+
if (!fetchImpl) {
|
|
11347
|
+
throw new GrammarUnavailableError2(
|
|
11348
|
+
language,
|
|
11349
|
+
new Error("No fetch implementation available (Node < 18?)")
|
|
11350
|
+
);
|
|
11351
|
+
}
|
|
11352
|
+
let body;
|
|
11353
|
+
try {
|
|
11354
|
+
const res = await fetchImpl(manifest.url);
|
|
11355
|
+
if (!res.ok) {
|
|
11356
|
+
throw new Error(`HTTP ${res.status ?? "unknown"} from ${manifest.url}`);
|
|
11357
|
+
}
|
|
11358
|
+
body = new Uint8Array(await res.arrayBuffer());
|
|
11359
|
+
} catch (e2) {
|
|
11360
|
+
throw new GrammarUnavailableError2(language, e2);
|
|
11361
|
+
}
|
|
11362
|
+
const downloadedSha = sha2562(body);
|
|
11363
|
+
if (downloadedSha !== manifest.sha256) {
|
|
11364
|
+
throw new GrammarSHAMismatchError2(language, manifest.sha256, downloadedSha);
|
|
11365
|
+
}
|
|
11366
|
+
try {
|
|
11367
|
+
mkdirSync4(dirname5(cachePath), { recursive: true, mode: 448 });
|
|
11368
|
+
try {
|
|
11369
|
+
chmodSync2(dirname5(cachePath), 448);
|
|
11370
|
+
} catch {
|
|
11371
|
+
}
|
|
11372
|
+
const tmpPath = `${cachePath}.tmp.${process.pid}`;
|
|
11373
|
+
writeFileSync2(tmpPath, body, { mode: 384 });
|
|
11374
|
+
try {
|
|
11375
|
+
chmodSync2(tmpPath, 384);
|
|
11376
|
+
} catch {
|
|
11377
|
+
}
|
|
11378
|
+
try {
|
|
11379
|
+
renameSync3(tmpPath, cachePath);
|
|
11380
|
+
try {
|
|
11381
|
+
chmodSync2(cachePath, 384);
|
|
11382
|
+
} catch {
|
|
11383
|
+
}
|
|
11384
|
+
} catch (e2) {
|
|
11385
|
+
try {
|
|
11386
|
+
unlinkSync2(tmpPath);
|
|
11387
|
+
} catch {
|
|
11388
|
+
}
|
|
11389
|
+
throw e2;
|
|
11390
|
+
}
|
|
11391
|
+
evictBeyondRetainCount2();
|
|
11392
|
+
} catch (e2) {
|
|
11393
|
+
console.error(
|
|
11394
|
+
`[tree-sitter-loader] cache write failed for ${language}: ${e2 instanceof Error ? e2.message : String(e2)} \u2014 loading directly from memory.`
|
|
11395
|
+
);
|
|
11396
|
+
}
|
|
11397
|
+
const lang = await Language2.load(body);
|
|
11398
|
+
loadedGrammars2.set(language, lang);
|
|
11399
|
+
return lang;
|
|
11400
|
+
}
|
|
11401
|
+
function isParsableSource2(source, sizeBytes) {
|
|
11402
|
+
const bytes = sizeBytes ?? Buffer.byteLength(source, "utf-8");
|
|
11403
|
+
if (bytes > MAX_AST_FILE_BYTES2) {
|
|
11404
|
+
return {
|
|
11405
|
+
reason: "size-cap",
|
|
11406
|
+
detail: `${bytes} bytes > ${MAX_AST_FILE_BYTES2} cap`
|
|
11407
|
+
};
|
|
11408
|
+
}
|
|
11409
|
+
let depth = 0;
|
|
11410
|
+
let maxDepth = 0;
|
|
11411
|
+
for (let i = 0; i < source.length; i++) {
|
|
11412
|
+
const c2 = source.charCodeAt(i);
|
|
11413
|
+
if (c2 === 0) {
|
|
11414
|
+
return { reason: "control-bytes", detail: "NUL byte at offset " + i };
|
|
11415
|
+
}
|
|
11416
|
+
if (c2 === 40 || c2 === 91 || c2 === 123) {
|
|
11417
|
+
depth++;
|
|
11418
|
+
if (depth > maxDepth) maxDepth = depth;
|
|
11419
|
+
if (depth > MAX_AST_PARSE_DEPTH2) {
|
|
11420
|
+
return {
|
|
11421
|
+
reason: "depth-cap",
|
|
11422
|
+
detail: `nesting depth exceeded ${MAX_AST_PARSE_DEPTH2}`
|
|
11423
|
+
};
|
|
11424
|
+
}
|
|
11425
|
+
} else if (c2 === 41 || c2 === 93 || c2 === 125) {
|
|
11426
|
+
depth = depth > 0 ? depth - 1 : 0;
|
|
11427
|
+
}
|
|
11428
|
+
}
|
|
11429
|
+
return null;
|
|
11430
|
+
}
|
|
11431
|
+
var InvalidQueryError2, queryCache2, GrammarSHAMismatchError2, GrammarUnavailableError2, GrammarCacheSymlinkError2, GrammarUrlNotHttpsError2, GRAMMAR_MANIFEST2, DEFAULT_CACHE_RETAIN_COUNT2, parserInitPromise2, loadedGrammars2, MAX_AST_FILE_BYTES2, MAX_AST_PARSE_DEPTH2;
|
|
11432
|
+
var init_adapter = __esm({
|
|
11433
|
+
"dist/adapter.js"() {
|
|
11434
|
+
"use strict";
|
|
11435
|
+
InvalidQueryError2 = class extends Error {
|
|
11436
|
+
queryName;
|
|
11437
|
+
querySource;
|
|
11438
|
+
cause;
|
|
11439
|
+
constructor(queryName, querySource, cause) {
|
|
11440
|
+
const causeMsg = cause instanceof Error ? cause.message : String(cause);
|
|
11441
|
+
super(
|
|
11442
|
+
`[query-helpers] Invalid Tree-sitter query "${queryName}": ${causeMsg}
|
|
11443
|
+
Query source:
|
|
11444
|
+
${querySource}`
|
|
11445
|
+
);
|
|
11446
|
+
this.name = "InvalidQueryError";
|
|
11447
|
+
this.queryName = queryName;
|
|
11448
|
+
this.querySource = querySource;
|
|
11449
|
+
this.cause = cause;
|
|
11450
|
+
}
|
|
11451
|
+
};
|
|
11452
|
+
queryCache2 = /* @__PURE__ */ new WeakMap();
|
|
11453
|
+
GrammarSHAMismatchError2 = class extends Error {
|
|
11454
|
+
language;
|
|
11455
|
+
expected;
|
|
11456
|
+
actual;
|
|
11457
|
+
constructor(language, expected, actual) {
|
|
11458
|
+
super(
|
|
11459
|
+
`[tree-sitter-loader] SHA-256 mismatch for grammar "${language}". Expected ${expected}, got ${actual}. REFUSING to load \u2014 see Phase 3.5 audit attack vector #3.`
|
|
11460
|
+
);
|
|
11461
|
+
this.name = "GrammarSHAMismatchError";
|
|
11462
|
+
this.language = language;
|
|
11463
|
+
this.expected = expected;
|
|
11464
|
+
this.actual = actual;
|
|
11465
|
+
}
|
|
11466
|
+
};
|
|
11467
|
+
GrammarUnavailableError2 = class extends Error {
|
|
11468
|
+
language;
|
|
11469
|
+
cause;
|
|
11470
|
+
constructor(language, cause) {
|
|
11471
|
+
const causeMsg = cause instanceof Error ? cause.message : cause ? String(cause) : "no cached grammar and download failed";
|
|
11472
|
+
super(
|
|
11473
|
+
`[tree-sitter-loader] Grammar for "${language}" is unavailable: ${causeMsg}. Falling back to regex introspection for files in ${language}.`
|
|
11474
|
+
);
|
|
11475
|
+
this.name = "GrammarUnavailableError";
|
|
11476
|
+
this.language = language;
|
|
11477
|
+
this.cause = cause;
|
|
11478
|
+
}
|
|
11479
|
+
};
|
|
11480
|
+
GrammarCacheSymlinkError2 = class extends Error {
|
|
11481
|
+
cachePath;
|
|
11482
|
+
constructor(cachePath) {
|
|
11483
|
+
super(
|
|
11484
|
+
`[tree-sitter-loader] Refusing to load grammar \u2014 cache path "${cachePath}" is a symlink or non-regular file. (Phase 3.5 finding #3 \u2014 symlink attack vector.)`
|
|
11485
|
+
);
|
|
11486
|
+
this.name = "GrammarCacheSymlinkError";
|
|
11487
|
+
this.cachePath = cachePath;
|
|
11488
|
+
}
|
|
11489
|
+
};
|
|
11490
|
+
GrammarUrlNotHttpsError2 = class extends Error {
|
|
11491
|
+
url;
|
|
11492
|
+
constructor(url) {
|
|
11493
|
+
super(
|
|
11494
|
+
`[tree-sitter-loader] Refusing to download grammar from non-HTTPS URL: ${url}. Only https:// URLs are accepted. (Phase 3.5 finding #3.)`
|
|
11495
|
+
);
|
|
11496
|
+
this.name = "GrammarUrlNotHttpsError";
|
|
11497
|
+
this.url = url;
|
|
11498
|
+
}
|
|
11499
|
+
};
|
|
11500
|
+
GRAMMAR_MANIFEST2 = {
|
|
11501
|
+
python: {
|
|
11502
|
+
url: "https://unpkg.com/tree-sitter-wasms@0.1.13/out/tree-sitter-python.wasm",
|
|
11503
|
+
sha256: "9056d0fb0c337810d019fae350e8167786119da98f0f282aceae7ab89ee8253b",
|
|
11504
|
+
version: "0.1.13"
|
|
11505
|
+
},
|
|
11506
|
+
typescript: {
|
|
11507
|
+
url: "https://unpkg.com/tree-sitter-wasms@0.1.13/out/tree-sitter-typescript.wasm",
|
|
11508
|
+
sha256: "8515404dceed38e1ed86aa34b09fcf3379fff1b4ff9dd3967bcd6d1eb5ac3d8f",
|
|
11509
|
+
version: "0.1.13"
|
|
11510
|
+
},
|
|
11511
|
+
javascript: {
|
|
11512
|
+
url: "https://unpkg.com/tree-sitter-wasms@0.1.13/out/tree-sitter-javascript.wasm",
|
|
11513
|
+
sha256: "63812b9e275d26851264734868d27a1656bd44a2ef6eb3e85e6b03728c595ab5",
|
|
11514
|
+
version: "0.1.13"
|
|
11515
|
+
},
|
|
11516
|
+
swift: {
|
|
11517
|
+
url: "https://unpkg.com/tree-sitter-wasms@0.1.13/out/tree-sitter-swift.wasm",
|
|
11518
|
+
sha256: "41c4fdb2249a3aa6d87eed0d383081ff09725c2248b4977043a43825980ffcc7",
|
|
11519
|
+
version: "0.1.13"
|
|
11520
|
+
},
|
|
11521
|
+
// ----------------------------------------------------------------
|
|
11522
|
+
// Plan 3c Phase 7 expansion (2026-05-07):
|
|
11523
|
+
//
|
|
11524
|
+
// Six additional grammars to support the registry-verified framework
|
|
11525
|
+
// adapters (go-chi, rails, aspnet, spring, ktor, phoenix) plus the
|
|
11526
|
+
// bundled adapters in the same language families (gin/echo/fiber,
|
|
11527
|
+
// sinatra, etc.). All entries use the SAME pinned tree-sitter-wasms
|
|
11528
|
+
// version (0.1.13) as the v1 four to keep the dependency surface
|
|
11529
|
+
// single-source.
|
|
11530
|
+
//
|
|
11531
|
+
// SHA-256s computed 2026-05-07 via:
|
|
11532
|
+
// curl -fsSL <url> | shasum -a 256
|
|
11533
|
+
//
|
|
11534
|
+
// The unpkg filename for C# uses an underscore (`c_sharp`) while the
|
|
11535
|
+
// TreeSitterLanguage identifier uses no separator (`csharp`); the map
|
|
11536
|
+
// key is the type identifier, the URL is the storage path — they do
|
|
11537
|
+
// NOT need to match, the same as how `python` maps to `tree-sitter-
|
|
11538
|
+
// python.wasm`. This is intentional and validated by the manifest
|
|
11539
|
+
// shape test in tree-sitter-loader-manifest.test.ts.
|
|
11540
|
+
// ----------------------------------------------------------------
|
|
11541
|
+
go: {
|
|
11542
|
+
url: "https://unpkg.com/tree-sitter-wasms@0.1.13/out/tree-sitter-go.wasm",
|
|
11543
|
+
sha256: "9963ca89b616eaf04b08a43bc1fb0f07b85395bec313330851f1f1ead2f755b6",
|
|
11544
|
+
version: "0.1.13"
|
|
11545
|
+
},
|
|
11546
|
+
ruby: {
|
|
11547
|
+
url: "https://unpkg.com/tree-sitter-wasms@0.1.13/out/tree-sitter-ruby.wasm",
|
|
11548
|
+
sha256: "93a5022855314cdb45458c7bb026a24a0ebc3a5ff6439e542e881f14dfa13a39",
|
|
11549
|
+
version: "0.1.13"
|
|
11550
|
+
},
|
|
11551
|
+
csharp: {
|
|
11552
|
+
url: "https://unpkg.com/tree-sitter-wasms@0.1.13/out/tree-sitter-c_sharp.wasm",
|
|
11553
|
+
sha256: "6266a7e32d68a3459104d994dc848df15d5672b0ea8e86d327274b694f8e6991",
|
|
11554
|
+
version: "0.1.13"
|
|
11555
|
+
},
|
|
11556
|
+
java: {
|
|
11557
|
+
url: "https://unpkg.com/tree-sitter-wasms@0.1.13/out/tree-sitter-java.wasm",
|
|
11558
|
+
sha256: "637aac4415fb39a211a4f4292d63c66b5ce9c32fa2cd35464af4f681d91b9a1f",
|
|
11559
|
+
version: "0.1.13"
|
|
11560
|
+
},
|
|
11561
|
+
kotlin: {
|
|
11562
|
+
url: "https://unpkg.com/tree-sitter-wasms@0.1.13/out/tree-sitter-kotlin.wasm",
|
|
11563
|
+
sha256: "b5cb00c8d06ed0f10f1dbe497205b437809d7e87db1f638721a8cfb30e044449",
|
|
11564
|
+
version: "0.1.13"
|
|
11565
|
+
},
|
|
11566
|
+
elixir: {
|
|
11567
|
+
url: "https://unpkg.com/tree-sitter-wasms@0.1.13/out/tree-sitter-elixir.wasm",
|
|
11568
|
+
sha256: "82e91b9759ddca30d8978ebbfa8e347b4451b64c931f9ae62112e6db9b8fac20",
|
|
11569
|
+
version: "0.1.13"
|
|
11570
|
+
}
|
|
11571
|
+
};
|
|
11572
|
+
DEFAULT_CACHE_RETAIN_COUNT2 = 16;
|
|
11573
|
+
parserInitPromise2 = null;
|
|
11574
|
+
loadedGrammars2 = /* @__PURE__ */ new Map();
|
|
11575
|
+
MAX_AST_FILE_BYTES2 = 1 * 1024 * 1024;
|
|
11576
|
+
MAX_AST_PARSE_DEPTH2 = 5e3;
|
|
11577
|
+
}
|
|
11578
|
+
});
|
|
11579
|
+
|
|
11580
|
+
// ../adapter-go-chi/dist/index.js
|
|
11581
|
+
import { Parser as Parser8 } from "web-tree-sitter";
|
|
11164
11582
|
function extractPrefixBase4(prefix3) {
|
|
11165
|
-
if (!prefix3.startsWith("/"))
|
|
11583
|
+
if (!prefix3.startsWith("/"))
|
|
11584
|
+
return null;
|
|
11166
11585
|
const stripped = prefix3.replace(/^\/+/, "");
|
|
11167
11586
|
const firstSeg = stripped.split("/")[0];
|
|
11168
|
-
if (!firstSeg)
|
|
11587
|
+
if (!firstSeg)
|
|
11588
|
+
return null;
|
|
11169
11589
|
return "/" + firstSeg;
|
|
11170
11590
|
}
|
|
11171
11591
|
var ROUTE_METHOD_QUERY, MOUNT_PREFIX_QUERY, MIDDLEWARE_USE_QUERY, goChiAdapter;
|
|
11172
|
-
var
|
|
11173
|
-
"
|
|
11592
|
+
var init_dist = __esm({
|
|
11593
|
+
"../adapter-go-chi/dist/index.js"() {
|
|
11174
11594
|
"use strict";
|
|
11175
|
-
|
|
11176
|
-
init_tree_sitter_loader();
|
|
11177
|
-
init_parse_guard();
|
|
11595
|
+
init_adapter();
|
|
11178
11596
|
ROUTE_METHOD_QUERY = `
|
|
11179
11597
|
(call_expression
|
|
11180
11598
|
function: (selector_expression
|
|
@@ -11205,8 +11623,10 @@ var init_go_chi = __esm({
|
|
|
11205
11623
|
id: "go-chi",
|
|
11206
11624
|
languages: ["go"],
|
|
11207
11625
|
matches(signals) {
|
|
11208
|
-
if (!signals.goMod)
|
|
11209
|
-
|
|
11626
|
+
if (!signals.goMod)
|
|
11627
|
+
return false;
|
|
11628
|
+
if (/github\.com\/go-chi\/chi/i.test(signals.goMod))
|
|
11629
|
+
return true;
|
|
11210
11630
|
return false;
|
|
11211
11631
|
},
|
|
11212
11632
|
async introspect(files, _rootDir) {
|
|
@@ -11215,49 +11635,48 @@ var init_go_chi = __esm({
|
|
|
11215
11635
|
}
|
|
11216
11636
|
let language;
|
|
11217
11637
|
try {
|
|
11218
|
-
language = await
|
|
11638
|
+
language = await loadGrammar2("go");
|
|
11219
11639
|
} catch (e2) {
|
|
11220
11640
|
return { conventions: {}, provenance: [], confidence: "none" };
|
|
11221
11641
|
}
|
|
11222
|
-
const parser = new
|
|
11642
|
+
const parser = new Parser8();
|
|
11223
11643
|
parser.setLanguage(language);
|
|
11224
11644
|
const routeMethods = /* @__PURE__ */ new Map();
|
|
11225
11645
|
const mountBases = /* @__PURE__ */ new Map();
|
|
11226
11646
|
const middlewareNames = /* @__PURE__ */ new Map();
|
|
11227
11647
|
try {
|
|
11228
11648
|
for (const file of files) {
|
|
11229
|
-
const skip =
|
|
11649
|
+
const skip = isParsableSource2(file.content, file.size);
|
|
11230
11650
|
if (skip) {
|
|
11231
|
-
process.stderr.write(
|
|
11232
|
-
|
|
11233
|
-
`
|
|
11234
|
-
);
|
|
11651
|
+
process.stderr.write(`[massu/ast] WARN: go-chi skipping ${file.path}: ${skip.reason} (${skip.detail}). Cap=${MAX_AST_FILE_BYTES2}. (Phase 3.5 mitigation)
|
|
11652
|
+
`);
|
|
11235
11653
|
continue;
|
|
11236
11654
|
}
|
|
11237
11655
|
try {
|
|
11238
|
-
for (const hit of
|
|
11656
|
+
for (const hit of runQuery2(parser, file.content, ROUTE_METHOD_QUERY, "chi-route-method", file.path)) {
|
|
11239
11657
|
const method = hit.captures.method;
|
|
11240
11658
|
if (method && !routeMethods.has(method)) {
|
|
11241
11659
|
routeMethods.set(method, { line: hit.line, file: file.path });
|
|
11242
11660
|
}
|
|
11243
11661
|
}
|
|
11244
|
-
for (const hit of
|
|
11662
|
+
for (const hit of runQuery2(parser, file.content, MOUNT_PREFIX_QUERY, "chi-mount-prefix", file.path)) {
|
|
11245
11663
|
const raw = hit.captures.mount_path;
|
|
11246
|
-
if (!raw)
|
|
11664
|
+
if (!raw)
|
|
11665
|
+
continue;
|
|
11247
11666
|
const literal = raw.replace(/^["`]/, "").replace(/["`]$/, "");
|
|
11248
11667
|
const base = extractPrefixBase4(literal);
|
|
11249
11668
|
if (base && !mountBases.has(base)) {
|
|
11250
11669
|
mountBases.set(base, { line: hit.line, file: file.path });
|
|
11251
11670
|
}
|
|
11252
11671
|
}
|
|
11253
|
-
for (const hit of
|
|
11672
|
+
for (const hit of runQuery2(parser, file.content, MIDDLEWARE_USE_QUERY, "chi-middleware-use", file.path)) {
|
|
11254
11673
|
const name = hit.captures.middleware_name;
|
|
11255
11674
|
if (name && !middlewareNames.has(name)) {
|
|
11256
11675
|
middlewareNames.set(name, { line: hit.line, file: file.path });
|
|
11257
11676
|
}
|
|
11258
11677
|
}
|
|
11259
11678
|
} catch (e2) {
|
|
11260
|
-
if (e2 instanceof
|
|
11679
|
+
if (e2 instanceof InvalidQueryError2) {
|
|
11261
11680
|
throw e2;
|
|
11262
11681
|
}
|
|
11263
11682
|
continue;
|
|
@@ -11306,21 +11725,28 @@ var init_go_chi = __esm({
|
|
|
11306
11725
|
}
|
|
11307
11726
|
});
|
|
11308
11727
|
|
|
11309
|
-
// src/detect/adapters/
|
|
11310
|
-
|
|
11728
|
+
// src/detect/adapters/go-chi.ts
|
|
11729
|
+
var init_go_chi = __esm({
|
|
11730
|
+
"src/detect/adapters/go-chi.ts"() {
|
|
11731
|
+
"use strict";
|
|
11732
|
+
init_dist();
|
|
11733
|
+
}
|
|
11734
|
+
});
|
|
11735
|
+
|
|
11736
|
+
// ../adapter-rails/dist/index.js
|
|
11737
|
+
import { Parser as Parser9 } from "web-tree-sitter";
|
|
11311
11738
|
function extractRootController(target) {
|
|
11312
11739
|
const idx = target.indexOf("#");
|
|
11313
|
-
if (idx <= 0)
|
|
11740
|
+
if (idx <= 0)
|
|
11741
|
+
return null;
|
|
11314
11742
|
const controller = target.slice(0, idx).trim();
|
|
11315
11743
|
return controller || null;
|
|
11316
11744
|
}
|
|
11317
11745
|
var ROUTE_METHOD_QUERY2, NAMESPACE_QUERY, ROOT_ROUTE_QUERY, railsAdapter;
|
|
11318
|
-
var
|
|
11319
|
-
"
|
|
11746
|
+
var init_dist2 = __esm({
|
|
11747
|
+
"../adapter-rails/dist/index.js"() {
|
|
11320
11748
|
"use strict";
|
|
11321
|
-
|
|
11322
|
-
init_tree_sitter_loader();
|
|
11323
|
-
init_parse_guard();
|
|
11749
|
+
init_adapter();
|
|
11324
11750
|
ROUTE_METHOD_QUERY2 = `
|
|
11325
11751
|
(call
|
|
11326
11752
|
method: (identifier) @method (#match? @method "^(get|post|put|patch|delete|options|head)$")
|
|
@@ -11356,7 +11782,8 @@ var init_rails = __esm({
|
|
|
11356
11782
|
id: "rails",
|
|
11357
11783
|
languages: ["ruby"],
|
|
11358
11784
|
matches(signals) {
|
|
11359
|
-
if (!signals.gemfile)
|
|
11785
|
+
if (!signals.gemfile)
|
|
11786
|
+
return false;
|
|
11360
11787
|
return /^\s*gem\s+['"]rails['"]/im.test(signals.gemfile);
|
|
11361
11788
|
},
|
|
11362
11789
|
async introspect(files, _rootDir) {
|
|
@@ -11365,45 +11792,45 @@ var init_rails = __esm({
|
|
|
11365
11792
|
}
|
|
11366
11793
|
let language;
|
|
11367
11794
|
try {
|
|
11368
|
-
language = await
|
|
11795
|
+
language = await loadGrammar2("ruby");
|
|
11369
11796
|
} catch (e2) {
|
|
11370
11797
|
return { conventions: {}, provenance: [], confidence: "none" };
|
|
11371
11798
|
}
|
|
11372
|
-
const parser = new
|
|
11799
|
+
const parser = new Parser9();
|
|
11373
11800
|
parser.setLanguage(language);
|
|
11374
11801
|
const routeMethods = /* @__PURE__ */ new Map();
|
|
11375
11802
|
const namespaces = /* @__PURE__ */ new Map();
|
|
11376
11803
|
const rootControllers = /* @__PURE__ */ new Map();
|
|
11377
11804
|
try {
|
|
11378
11805
|
for (const file of files) {
|
|
11379
|
-
const skip =
|
|
11806
|
+
const skip = isParsableSource2(file.content, file.size);
|
|
11380
11807
|
if (skip) {
|
|
11381
|
-
process.stderr.write(
|
|
11382
|
-
|
|
11383
|
-
`
|
|
11384
|
-
);
|
|
11808
|
+
process.stderr.write(`[massu/ast] WARN: rails skipping ${file.path}: ${skip.reason} (${skip.detail}). Cap=${MAX_AST_FILE_BYTES2}. (Phase 3.5 mitigation)
|
|
11809
|
+
`);
|
|
11385
11810
|
continue;
|
|
11386
11811
|
}
|
|
11387
11812
|
try {
|
|
11388
|
-
for (const hit of
|
|
11813
|
+
for (const hit of runQuery2(parser, file.content, ROUTE_METHOD_QUERY2, "rails-route-method", file.path)) {
|
|
11389
11814
|
const method = hit.captures.method;
|
|
11390
11815
|
if (method && !routeMethods.has(method)) {
|
|
11391
11816
|
routeMethods.set(method, { line: hit.line, file: file.path });
|
|
11392
11817
|
}
|
|
11393
11818
|
}
|
|
11394
|
-
for (const hit of
|
|
11819
|
+
for (const hit of runQuery2(parser, file.content, NAMESPACE_QUERY, "rails-namespace", file.path)) {
|
|
11395
11820
|
const symbolRaw = hit.captures.namespace_symbol;
|
|
11396
11821
|
const stringRaw = hit.captures.namespace_string;
|
|
11397
11822
|
const name = symbolRaw ? symbolRaw.replace(/^:/, "") : stringRaw ? stringRaw.replace(/^['"]/, "").replace(/['"]$/, "") : null;
|
|
11398
|
-
if (!name)
|
|
11823
|
+
if (!name)
|
|
11824
|
+
continue;
|
|
11399
11825
|
const path = "/" + name;
|
|
11400
11826
|
if (!namespaces.has(path)) {
|
|
11401
11827
|
namespaces.set(path, { line: hit.line, file: file.path });
|
|
11402
11828
|
}
|
|
11403
11829
|
}
|
|
11404
|
-
for (const hit of
|
|
11830
|
+
for (const hit of runQuery2(parser, file.content, ROOT_ROUTE_QUERY, "rails-root", file.path)) {
|
|
11405
11831
|
const raw = hit.captures.root_target;
|
|
11406
|
-
if (!raw)
|
|
11832
|
+
if (!raw)
|
|
11833
|
+
continue;
|
|
11407
11834
|
const literal = raw.replace(/^['"]/, "").replace(/['"]$/, "");
|
|
11408
11835
|
const controller = extractRootController(literal);
|
|
11409
11836
|
if (controller && !rootControllers.has(controller)) {
|
|
@@ -11411,7 +11838,7 @@ var init_rails = __esm({
|
|
|
11411
11838
|
}
|
|
11412
11839
|
}
|
|
11413
11840
|
} catch (e2) {
|
|
11414
|
-
if (e2 instanceof
|
|
11841
|
+
if (e2 instanceof InvalidQueryError2) {
|
|
11415
11842
|
throw e2;
|
|
11416
11843
|
}
|
|
11417
11844
|
continue;
|
|
@@ -11460,22 +11887,30 @@ var init_rails = __esm({
|
|
|
11460
11887
|
}
|
|
11461
11888
|
});
|
|
11462
11889
|
|
|
11463
|
-
// src/detect/adapters/
|
|
11464
|
-
|
|
11890
|
+
// src/detect/adapters/rails.ts
|
|
11891
|
+
var init_rails = __esm({
|
|
11892
|
+
"src/detect/adapters/rails.ts"() {
|
|
11893
|
+
"use strict";
|
|
11894
|
+
init_dist2();
|
|
11895
|
+
}
|
|
11896
|
+
});
|
|
11897
|
+
|
|
11898
|
+
// ../adapter-phoenix/dist/index.js
|
|
11899
|
+
import { Parser as Parser10 } from "web-tree-sitter";
|
|
11465
11900
|
function extractPrefixBase5(prefix3) {
|
|
11466
|
-
if (!prefix3.startsWith("/"))
|
|
11901
|
+
if (!prefix3.startsWith("/"))
|
|
11902
|
+
return null;
|
|
11467
11903
|
const stripped = prefix3.replace(/^\/+/, "");
|
|
11468
11904
|
const firstSeg = stripped.split("/")[0];
|
|
11469
|
-
if (!firstSeg)
|
|
11905
|
+
if (!firstSeg)
|
|
11906
|
+
return null;
|
|
11470
11907
|
return "/" + firstSeg;
|
|
11471
11908
|
}
|
|
11472
11909
|
var ROUTE_METHOD_QUERY3, SCOPE_PATH_QUERY, ROUTER_MODULE_QUERY, phoenixAdapter;
|
|
11473
|
-
var
|
|
11474
|
-
"
|
|
11910
|
+
var init_dist3 = __esm({
|
|
11911
|
+
"../adapter-phoenix/dist/index.js"() {
|
|
11475
11912
|
"use strict";
|
|
11476
|
-
|
|
11477
|
-
init_tree_sitter_loader();
|
|
11478
|
-
init_parse_guard();
|
|
11913
|
+
init_adapter();
|
|
11479
11914
|
ROUTE_METHOD_QUERY3 = `
|
|
11480
11915
|
(call
|
|
11481
11916
|
(identifier) @method (#match? @method "^(get|post|put|patch|delete|options|head)$")
|
|
@@ -11503,7 +11938,8 @@ var init_phoenix = __esm({
|
|
|
11503
11938
|
id: "phoenix",
|
|
11504
11939
|
languages: ["elixir"],
|
|
11505
11940
|
matches(signals) {
|
|
11506
|
-
if (!signals.mixExs)
|
|
11941
|
+
if (!signals.mixExs)
|
|
11942
|
+
return false;
|
|
11507
11943
|
return /\{\s*:phoenix\b(?!_)/.test(signals.mixExs);
|
|
11508
11944
|
},
|
|
11509
11945
|
async introspect(files, _rootDir) {
|
|
@@ -11512,49 +11948,48 @@ var init_phoenix = __esm({
|
|
|
11512
11948
|
}
|
|
11513
11949
|
let language;
|
|
11514
11950
|
try {
|
|
11515
|
-
language = await
|
|
11951
|
+
language = await loadGrammar2("elixir");
|
|
11516
11952
|
} catch (e2) {
|
|
11517
11953
|
return { conventions: {}, provenance: [], confidence: "none" };
|
|
11518
11954
|
}
|
|
11519
|
-
const parser = new
|
|
11955
|
+
const parser = new Parser10();
|
|
11520
11956
|
parser.setLanguage(language);
|
|
11521
11957
|
const routeMethods = /* @__PURE__ */ new Map();
|
|
11522
11958
|
const scopePaths = /* @__PURE__ */ new Map();
|
|
11523
11959
|
const routerModules = /* @__PURE__ */ new Map();
|
|
11524
11960
|
try {
|
|
11525
11961
|
for (const file of files) {
|
|
11526
|
-
const skip =
|
|
11962
|
+
const skip = isParsableSource2(file.content, file.size);
|
|
11527
11963
|
if (skip) {
|
|
11528
|
-
process.stderr.write(
|
|
11529
|
-
|
|
11530
|
-
`
|
|
11531
|
-
);
|
|
11964
|
+
process.stderr.write(`[massu/ast] WARN: phoenix skipping ${file.path}: ${skip.reason} (${skip.detail}). Cap=${MAX_AST_FILE_BYTES2}. (Phase 3.5 mitigation)
|
|
11965
|
+
`);
|
|
11532
11966
|
continue;
|
|
11533
11967
|
}
|
|
11534
11968
|
try {
|
|
11535
|
-
for (const hit of
|
|
11969
|
+
for (const hit of runQuery2(parser, file.content, ROUTE_METHOD_QUERY3, "phoenix-route-method", file.path)) {
|
|
11536
11970
|
const method = hit.captures.method;
|
|
11537
11971
|
if (method && !routeMethods.has(method)) {
|
|
11538
11972
|
routeMethods.set(method, { line: hit.line, file: file.path });
|
|
11539
11973
|
}
|
|
11540
11974
|
}
|
|
11541
|
-
for (const hit of
|
|
11975
|
+
for (const hit of runQuery2(parser, file.content, SCOPE_PATH_QUERY, "phoenix-scope-path", file.path)) {
|
|
11542
11976
|
const raw = hit.captures.scope_path;
|
|
11543
|
-
if (!raw)
|
|
11977
|
+
if (!raw)
|
|
11978
|
+
continue;
|
|
11544
11979
|
const literal = raw.replace(/^["']/, "").replace(/["']$/, "");
|
|
11545
11980
|
const base = extractPrefixBase5(literal);
|
|
11546
11981
|
if (base && !scopePaths.has(base)) {
|
|
11547
11982
|
scopePaths.set(base, { line: hit.line, file: file.path });
|
|
11548
11983
|
}
|
|
11549
11984
|
}
|
|
11550
|
-
for (const hit of
|
|
11985
|
+
for (const hit of runQuery2(parser, file.content, ROUTER_MODULE_QUERY, "phoenix-router-module", file.path)) {
|
|
11551
11986
|
const name = hit.captures.module_name;
|
|
11552
11987
|
if (name && !routerModules.has(name)) {
|
|
11553
11988
|
routerModules.set(name, { line: hit.line, file: file.path });
|
|
11554
11989
|
}
|
|
11555
11990
|
}
|
|
11556
11991
|
} catch (e2) {
|
|
11557
|
-
if (e2 instanceof
|
|
11992
|
+
if (e2 instanceof InvalidQueryError2) {
|
|
11558
11993
|
throw e2;
|
|
11559
11994
|
}
|
|
11560
11995
|
continue;
|
|
@@ -11603,21 +12038,28 @@ var init_phoenix = __esm({
|
|
|
11603
12038
|
}
|
|
11604
12039
|
});
|
|
11605
12040
|
|
|
11606
|
-
// src/detect/adapters/
|
|
11607
|
-
|
|
12041
|
+
// src/detect/adapters/phoenix.ts
|
|
12042
|
+
var init_phoenix = __esm({
|
|
12043
|
+
"src/detect/adapters/phoenix.ts"() {
|
|
12044
|
+
"use strict";
|
|
12045
|
+
init_dist3();
|
|
12046
|
+
}
|
|
12047
|
+
});
|
|
12048
|
+
|
|
12049
|
+
// ../adapter-aspnet/dist/index.js
|
|
12050
|
+
import { Parser as Parser11 } from "web-tree-sitter";
|
|
11608
12051
|
function extractPrefixBase6(prefix3) {
|
|
11609
12052
|
const stripped = prefix3.replace(/^\/+/, "");
|
|
11610
12053
|
const firstSeg = stripped.split("/")[0];
|
|
11611
|
-
if (!firstSeg)
|
|
12054
|
+
if (!firstSeg)
|
|
12055
|
+
return null;
|
|
11612
12056
|
return "/" + firstSeg;
|
|
11613
12057
|
}
|
|
11614
12058
|
var MAP_VERB_QUERY, HTTP_ATTR_QUERY, ROUTE_ATTR_QUERY, CONTROLLER_CLASS_QUERY, aspnetAdapter;
|
|
11615
|
-
var
|
|
11616
|
-
"
|
|
12059
|
+
var init_dist4 = __esm({
|
|
12060
|
+
"../adapter-aspnet/dist/index.js"() {
|
|
11617
12061
|
"use strict";
|
|
11618
|
-
|
|
11619
|
-
init_tree_sitter_loader();
|
|
11620
|
-
init_parse_guard();
|
|
12062
|
+
init_adapter();
|
|
11621
12063
|
MAP_VERB_QUERY = `
|
|
11622
12064
|
(invocation_expression
|
|
11623
12065
|
function: (member_access_expression
|
|
@@ -11644,9 +12086,12 @@ var init_aspnet = __esm({
|
|
|
11644
12086
|
id: "aspnet",
|
|
11645
12087
|
languages: ["csharp"],
|
|
11646
12088
|
matches(signals) {
|
|
11647
|
-
if (!signals.csproj)
|
|
11648
|
-
|
|
11649
|
-
if (/Microsoft\.
|
|
12089
|
+
if (!signals.csproj)
|
|
12090
|
+
return false;
|
|
12091
|
+
if (/Sdk\s*=\s*["']Microsoft\.NET\.Sdk\.Web["']/i.test(signals.csproj))
|
|
12092
|
+
return true;
|
|
12093
|
+
if (/Microsoft\.AspNetCore\.App/i.test(signals.csproj))
|
|
12094
|
+
return true;
|
|
11650
12095
|
return false;
|
|
11651
12096
|
},
|
|
11652
12097
|
async introspect(files, _rootDir) {
|
|
@@ -11655,29 +12100,28 @@ var init_aspnet = __esm({
|
|
|
11655
12100
|
}
|
|
11656
12101
|
let language;
|
|
11657
12102
|
try {
|
|
11658
|
-
language = await
|
|
12103
|
+
language = await loadGrammar2("csharp");
|
|
11659
12104
|
} catch (e2) {
|
|
11660
12105
|
return { conventions: {}, provenance: [], confidence: "none" };
|
|
11661
12106
|
}
|
|
11662
|
-
const parser = new
|
|
12107
|
+
const parser = new Parser11();
|
|
11663
12108
|
parser.setLanguage(language);
|
|
11664
12109
|
const routeMethods = /* @__PURE__ */ new Map();
|
|
11665
12110
|
const prefixBases = /* @__PURE__ */ new Map();
|
|
11666
12111
|
const controllerClasses = /* @__PURE__ */ new Map();
|
|
11667
12112
|
try {
|
|
11668
12113
|
for (const file of files) {
|
|
11669
|
-
const skip =
|
|
12114
|
+
const skip = isParsableSource2(file.content, file.size);
|
|
11670
12115
|
if (skip) {
|
|
11671
|
-
process.stderr.write(
|
|
11672
|
-
|
|
11673
|
-
`
|
|
11674
|
-
);
|
|
12116
|
+
process.stderr.write(`[massu/ast] WARN: aspnet skipping ${file.path}: ${skip.reason} (${skip.detail}). Cap=${MAX_AST_FILE_BYTES2}. (Phase 3.5 mitigation)
|
|
12117
|
+
`);
|
|
11675
12118
|
continue;
|
|
11676
12119
|
}
|
|
11677
12120
|
try {
|
|
11678
|
-
for (const hit of
|
|
12121
|
+
for (const hit of runQuery2(parser, file.content, MAP_VERB_QUERY, "aspnet-map-verb", file.path)) {
|
|
11679
12122
|
const methodRaw = hit.captures.method;
|
|
11680
|
-
if (!methodRaw)
|
|
12123
|
+
if (!methodRaw)
|
|
12124
|
+
continue;
|
|
11681
12125
|
const verb = methodRaw.replace(/^Map/, "");
|
|
11682
12126
|
if (!routeMethods.has(verb)) {
|
|
11683
12127
|
routeMethods.set(verb, { line: hit.line, file: file.path });
|
|
@@ -11691,31 +12135,33 @@ var init_aspnet = __esm({
|
|
|
11691
12135
|
}
|
|
11692
12136
|
}
|
|
11693
12137
|
}
|
|
11694
|
-
for (const hit of
|
|
12138
|
+
for (const hit of runQuery2(parser, file.content, HTTP_ATTR_QUERY, "aspnet-http-attr", file.path)) {
|
|
11695
12139
|
const attrRaw = hit.captures.attr_name;
|
|
11696
|
-
if (!attrRaw)
|
|
12140
|
+
if (!attrRaw)
|
|
12141
|
+
continue;
|
|
11697
12142
|
const verb = attrRaw.replace(/^Http/, "");
|
|
11698
12143
|
if (!routeMethods.has(verb)) {
|
|
11699
12144
|
routeMethods.set(verb, { line: hit.line, file: file.path });
|
|
11700
12145
|
}
|
|
11701
12146
|
}
|
|
11702
|
-
for (const hit of
|
|
12147
|
+
for (const hit of runQuery2(parser, file.content, ROUTE_ATTR_QUERY, "aspnet-route-attr", file.path)) {
|
|
11703
12148
|
const tplRaw = hit.captures.route_template;
|
|
11704
|
-
if (!tplRaw)
|
|
12149
|
+
if (!tplRaw)
|
|
12150
|
+
continue;
|
|
11705
12151
|
const literal = tplRaw.replace(/^["']/, "").replace(/["']$/, "");
|
|
11706
12152
|
const base = extractPrefixBase6(literal);
|
|
11707
12153
|
if (base && !prefixBases.has(base)) {
|
|
11708
12154
|
prefixBases.set(base, { line: hit.line, file: file.path });
|
|
11709
12155
|
}
|
|
11710
12156
|
}
|
|
11711
|
-
for (const hit of
|
|
12157
|
+
for (const hit of runQuery2(parser, file.content, CONTROLLER_CLASS_QUERY, "aspnet-controller-class", file.path)) {
|
|
11712
12158
|
const name = hit.captures.class_name;
|
|
11713
12159
|
if (name && !controllerClasses.has(name)) {
|
|
11714
12160
|
controllerClasses.set(name, { line: hit.line, file: file.path });
|
|
11715
12161
|
}
|
|
11716
12162
|
}
|
|
11717
12163
|
} catch (e2) {
|
|
11718
|
-
if (e2 instanceof
|
|
12164
|
+
if (e2 instanceof InvalidQueryError2) {
|
|
11719
12165
|
throw e2;
|
|
11720
12166
|
}
|
|
11721
12167
|
continue;
|
|
@@ -11764,21 +12210,28 @@ var init_aspnet = __esm({
|
|
|
11764
12210
|
}
|
|
11765
12211
|
});
|
|
11766
12212
|
|
|
11767
|
-
// src/detect/adapters/
|
|
11768
|
-
|
|
12213
|
+
// src/detect/adapters/aspnet.ts
|
|
12214
|
+
var init_aspnet = __esm({
|
|
12215
|
+
"src/detect/adapters/aspnet.ts"() {
|
|
12216
|
+
"use strict";
|
|
12217
|
+
init_dist4();
|
|
12218
|
+
}
|
|
12219
|
+
});
|
|
12220
|
+
|
|
12221
|
+
// ../adapter-spring/dist/index.js
|
|
12222
|
+
import { Parser as Parser12 } from "web-tree-sitter";
|
|
11769
12223
|
function extractPrefixBase7(prefix3) {
|
|
11770
12224
|
const stripped = prefix3.replace(/^\/+/, "");
|
|
11771
12225
|
const firstSeg = stripped.split("/")[0];
|
|
11772
|
-
if (!firstSeg)
|
|
12226
|
+
if (!firstSeg)
|
|
12227
|
+
return null;
|
|
11773
12228
|
return "/" + firstSeg;
|
|
11774
12229
|
}
|
|
11775
12230
|
var HTTP_MAPPING_QUERY, HTTP_MAPPING_NO_ARGS_QUERY, REQUEST_MAPPING_QUERY, CONTROLLER_CLASS_QUERY2, springAdapter;
|
|
11776
|
-
var
|
|
11777
|
-
"
|
|
12231
|
+
var init_dist5 = __esm({
|
|
12232
|
+
"../adapter-spring/dist/index.js"() {
|
|
11778
12233
|
"use strict";
|
|
11779
|
-
|
|
11780
|
-
init_tree_sitter_loader();
|
|
11781
|
-
init_parse_guard();
|
|
12234
|
+
init_adapter();
|
|
11782
12235
|
HTTP_MAPPING_QUERY = `
|
|
11783
12236
|
(annotation
|
|
11784
12237
|
name: (identifier) @method (#match? @method "^(Get|Post|Put|Patch|Delete|Head|Options)Mapping$")
|
|
@@ -11832,59 +12285,60 @@ var init_spring = __esm({
|
|
|
11832
12285
|
}
|
|
11833
12286
|
let language;
|
|
11834
12287
|
try {
|
|
11835
|
-
language = await
|
|
12288
|
+
language = await loadGrammar2("java");
|
|
11836
12289
|
} catch (e2) {
|
|
11837
12290
|
return { conventions: {}, provenance: [], confidence: "none" };
|
|
11838
12291
|
}
|
|
11839
|
-
const parser = new
|
|
12292
|
+
const parser = new Parser12();
|
|
11840
12293
|
parser.setLanguage(language);
|
|
11841
12294
|
const routeMethods = /* @__PURE__ */ new Map();
|
|
11842
12295
|
const prefixBases = /* @__PURE__ */ new Map();
|
|
11843
12296
|
const controllerClasses = /* @__PURE__ */ new Map();
|
|
11844
12297
|
try {
|
|
11845
12298
|
for (const file of files) {
|
|
11846
|
-
const skip =
|
|
12299
|
+
const skip = isParsableSource2(file.content, file.size);
|
|
11847
12300
|
if (skip) {
|
|
11848
|
-
process.stderr.write(
|
|
11849
|
-
|
|
11850
|
-
`
|
|
11851
|
-
);
|
|
12301
|
+
process.stderr.write(`[massu/ast] WARN: spring skipping ${file.path}: ${skip.reason} (${skip.detail}). Cap=${MAX_AST_FILE_BYTES2}. (Phase 3.5 mitigation)
|
|
12302
|
+
`);
|
|
11852
12303
|
continue;
|
|
11853
12304
|
}
|
|
11854
12305
|
try {
|
|
11855
|
-
for (const hit of
|
|
12306
|
+
for (const hit of runQuery2(parser, file.content, HTTP_MAPPING_QUERY, "spring-http-mapping", file.path)) {
|
|
11856
12307
|
const methodRaw = hit.captures.method;
|
|
11857
|
-
if (!methodRaw)
|
|
12308
|
+
if (!methodRaw)
|
|
12309
|
+
continue;
|
|
11858
12310
|
const verb = methodRaw.replace(/Mapping$/, "");
|
|
11859
12311
|
if (!routeMethods.has(verb)) {
|
|
11860
12312
|
routeMethods.set(verb, { line: hit.line, file: file.path });
|
|
11861
12313
|
}
|
|
11862
12314
|
}
|
|
11863
|
-
for (const hit of
|
|
12315
|
+
for (const hit of runQuery2(parser, file.content, HTTP_MAPPING_NO_ARGS_QUERY, "spring-http-mapping-marker", file.path)) {
|
|
11864
12316
|
const methodRaw = hit.captures.method;
|
|
11865
|
-
if (!methodRaw)
|
|
12317
|
+
if (!methodRaw)
|
|
12318
|
+
continue;
|
|
11866
12319
|
const verb = methodRaw.replace(/Mapping$/, "");
|
|
11867
12320
|
if (!routeMethods.has(verb)) {
|
|
11868
12321
|
routeMethods.set(verb, { line: hit.line, file: file.path });
|
|
11869
12322
|
}
|
|
11870
12323
|
}
|
|
11871
|
-
for (const hit of
|
|
12324
|
+
for (const hit of runQuery2(parser, file.content, REQUEST_MAPPING_QUERY, "spring-request-mapping", file.path)) {
|
|
11872
12325
|
const tplRaw = hit.captures.route_template;
|
|
11873
|
-
if (!tplRaw)
|
|
12326
|
+
if (!tplRaw)
|
|
12327
|
+
continue;
|
|
11874
12328
|
const literal = tplRaw.replace(/^["']/, "").replace(/["']$/, "");
|
|
11875
12329
|
const base = extractPrefixBase7(literal);
|
|
11876
12330
|
if (base && !prefixBases.has(base)) {
|
|
11877
12331
|
prefixBases.set(base, { line: hit.line, file: file.path });
|
|
11878
12332
|
}
|
|
11879
12333
|
}
|
|
11880
|
-
for (const hit of
|
|
12334
|
+
for (const hit of runQuery2(parser, file.content, CONTROLLER_CLASS_QUERY2, "spring-controller-class", file.path)) {
|
|
11881
12335
|
const name = hit.captures.class_name;
|
|
11882
12336
|
if (name && !controllerClasses.has(name)) {
|
|
11883
12337
|
controllerClasses.set(name, { line: hit.line, file: file.path });
|
|
11884
12338
|
}
|
|
11885
12339
|
}
|
|
11886
12340
|
} catch (e2) {
|
|
11887
|
-
if (e2 instanceof
|
|
12341
|
+
if (e2 instanceof InvalidQueryError2) {
|
|
11888
12342
|
throw e2;
|
|
11889
12343
|
}
|
|
11890
12344
|
continue;
|
|
@@ -11933,6 +12387,14 @@ var init_spring = __esm({
|
|
|
11933
12387
|
}
|
|
11934
12388
|
});
|
|
11935
12389
|
|
|
12390
|
+
// src/detect/adapters/spring.ts
|
|
12391
|
+
var init_spring = __esm({
|
|
12392
|
+
"src/detect/adapters/spring.ts"() {
|
|
12393
|
+
"use strict";
|
|
12394
|
+
init_dist5();
|
|
12395
|
+
}
|
|
12396
|
+
});
|
|
12397
|
+
|
|
11936
12398
|
// src/detect/adapters/file-sampler.ts
|
|
11937
12399
|
var file_sampler_exports = {};
|
|
11938
12400
|
__export(file_sampler_exports, {
|
|
@@ -11940,8 +12402,8 @@ __export(file_sampler_exports, {
|
|
|
11940
12402
|
SAMPLE_TEST_FILE_PATTERNS: () => SAMPLE_TEST_FILE_PATTERNS,
|
|
11941
12403
|
sampleFilesForAdapter: () => sampleFilesForAdapter
|
|
11942
12404
|
});
|
|
11943
|
-
import { readdirSync as
|
|
11944
|
-
import { join as
|
|
12405
|
+
import { readdirSync as readdirSync10, readFileSync as readFileSync10, lstatSync as lstatSync5 } from "node:fs";
|
|
12406
|
+
import { join as join10, extname } from "node:path";
|
|
11945
12407
|
function sampleFilesForAdapter(adapter, projectRoot, detection, options = {}) {
|
|
11946
12408
|
const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
11947
12409
|
const maxFiles = options.maxFilesPerAdapter ?? DEFAULT_MAX_FILES;
|
|
@@ -11956,7 +12418,7 @@ function sampleFilesForAdapter(adapter, projectRoot, detection, options = {}) {
|
|
|
11956
12418
|
const langDetection = detection.sourceDirs[langKey];
|
|
11957
12419
|
const candidateDirs = [];
|
|
11958
12420
|
if (langDetection?.source_dirs && langDetection.source_dirs.length > 0) {
|
|
11959
|
-
candidateDirs.push(...langDetection.source_dirs.map((d2) =>
|
|
12421
|
+
candidateDirs.push(...langDetection.source_dirs.map((d2) => join10(projectRoot, d2)));
|
|
11960
12422
|
} else {
|
|
11961
12423
|
candidateDirs.push(projectRoot);
|
|
11962
12424
|
}
|
|
@@ -11972,7 +12434,7 @@ function walkDir(dir, exts, testPatterns, lang, maxDepth, curDepth, out, seen, m
|
|
|
11972
12434
|
if (out.length >= maxFiles) return;
|
|
11973
12435
|
let entries;
|
|
11974
12436
|
try {
|
|
11975
|
-
entries =
|
|
12437
|
+
entries = readdirSync10(dir);
|
|
11976
12438
|
} catch {
|
|
11977
12439
|
return;
|
|
11978
12440
|
}
|
|
@@ -11980,10 +12442,10 @@ function walkDir(dir, exts, testPatterns, lang, maxDepth, curDepth, out, seen, m
|
|
|
11980
12442
|
if (out.length >= maxFiles) return;
|
|
11981
12443
|
if (entry.startsWith(".")) continue;
|
|
11982
12444
|
if (IGNORED_DIRS3.has(entry)) continue;
|
|
11983
|
-
const fullPath =
|
|
12445
|
+
const fullPath = join10(dir, entry);
|
|
11984
12446
|
let st;
|
|
11985
12447
|
try {
|
|
11986
|
-
st =
|
|
12448
|
+
st = lstatSync5(fullPath);
|
|
11987
12449
|
} catch {
|
|
11988
12450
|
continue;
|
|
11989
12451
|
}
|
|
@@ -12001,7 +12463,7 @@ function walkDir(dir, exts, testPatterns, lang, maxDepth, curDepth, out, seen, m
|
|
|
12001
12463
|
seen.add(fullPath);
|
|
12002
12464
|
let content;
|
|
12003
12465
|
try {
|
|
12004
|
-
content =
|
|
12466
|
+
content = readFileSync10(fullPath, "utf-8");
|
|
12005
12467
|
} catch {
|
|
12006
12468
|
continue;
|
|
12007
12469
|
}
|
|
@@ -12239,7 +12701,7 @@ var init_detect = __esm({
|
|
|
12239
12701
|
});
|
|
12240
12702
|
|
|
12241
12703
|
// src/detect/drift.ts
|
|
12242
|
-
import { createHash as
|
|
12704
|
+
import { createHash as createHash4 } from "crypto";
|
|
12243
12705
|
function summarizeDetection(det) {
|
|
12244
12706
|
const languages = Array.from(new Set(det.manifests.map((m3) => m3.language))).sort();
|
|
12245
12707
|
const frameworks = {};
|
|
@@ -12270,7 +12732,7 @@ function summarizeDetection(det) {
|
|
|
12270
12732
|
function computeFingerprint(det) {
|
|
12271
12733
|
const data = summarizeDetection(det);
|
|
12272
12734
|
const stable = JSON.stringify(data, Object.keys(data).sort());
|
|
12273
|
-
return
|
|
12735
|
+
return createHash4("sha256").update(stable).digest("hex");
|
|
12274
12736
|
}
|
|
12275
12737
|
function stringOf(v3) {
|
|
12276
12738
|
if (typeof v3 === "string") return v3;
|
|
@@ -12620,7 +13082,7 @@ function cD({ input: t = $, output: u2 = j, overwrite: F = true, hideCursor: e2
|
|
|
12620
13082
|
};
|
|
12621
13083
|
}
|
|
12622
13084
|
var import_sisteransi, import_picocolors, Q, P, X, DD, uD, FD, m, L, N, I, r, tD, eD, iD, v, CD, w, W, rD, R, y, V, z2, ED, _, nD, oD, aD, c, xD, S, AD, pD, h, x, fD, gD, vD, K, dD, bD, mD, Y, wD, yD, _D, Z, kD, SD, $D, q, jD, MD, TD, H, OD, PD;
|
|
12623
|
-
var
|
|
13085
|
+
var init_dist6 = __esm({
|
|
12624
13086
|
"../../node_modules/@clack/core/dist/index.mjs"() {
|
|
12625
13087
|
import_sisteransi = __toESM(require_src(), 1);
|
|
12626
13088
|
import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -13038,10 +13500,10 @@ function X2() {
|
|
|
13038
13500
|
return p.platform !== "win32" ? p.env.TERM !== "linux" : !!p.env.CI || !!p.env.WT_SESSION || !!p.env.TERMINUS_SUBLIME || p.env.ConEmuTask === "{cmd::Cmder}" || p.env.TERM_PROGRAM === "Terminus-Sublime" || p.env.TERM_PROGRAM === "vscode" || p.env.TERM === "xterm-256color" || p.env.TERM === "alacritty" || p.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
13039
13501
|
}
|
|
13040
13502
|
var import_picocolors2, import_sisteransi2, E, u, ee, A2, B, S2, te, a, m2, j2, R2, V2, M2, G2, se, N2, re, ie, ne, ae, oe, ce, le, y2, k2, ue, $e, me, de, he, pe, ge, ye, ve, we, fe, v2, L2, be, xe;
|
|
13041
|
-
var
|
|
13503
|
+
var init_dist7 = __esm({
|
|
13042
13504
|
"../../node_modules/@clack/prompts/dist/index.mjs"() {
|
|
13043
|
-
|
|
13044
|
-
|
|
13505
|
+
init_dist6();
|
|
13506
|
+
init_dist6();
|
|
13045
13507
|
import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
13046
13508
|
import_sisteransi2 = __toESM(require_src(), 1);
|
|
13047
13509
|
E = X2();
|
|
@@ -13429,10 +13891,10 @@ __export(init_exports, {
|
|
|
13429
13891
|
validateWrittenConfig: () => validateWrittenConfig,
|
|
13430
13892
|
writeConfigAtomic: () => writeConfigAtomic
|
|
13431
13893
|
});
|
|
13432
|
-
import { closeSync as closeSync2, existsSync as existsSync10, fsyncSync as fsyncSync2, openSync as openSync2, readFileSync as
|
|
13433
|
-
import { resolve as resolve6, basename as basename4, dirname as
|
|
13894
|
+
import { closeSync as closeSync2, existsSync as existsSync10, fsyncSync as fsyncSync2, openSync as openSync2, readFileSync as readFileSync11, writeFileSync as writeFileSync3, writeSync as writeSync2, mkdirSync as mkdirSync5, readdirSync as readdirSync11, renameSync as renameSync4, rmSync as rmSync2, statSync as statSync7, chmodSync as chmodSync3 } from "fs";
|
|
13895
|
+
import { resolve as resolve6, basename as basename4, dirname as dirname6 } from "path";
|
|
13434
13896
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
13435
|
-
import { homedir as
|
|
13897
|
+
import { homedir as homedir4 } from "os";
|
|
13436
13898
|
import { stringify as yamlStringify, parse as yamlParse } from "yaml";
|
|
13437
13899
|
function detectFramework(projectRoot) {
|
|
13438
13900
|
const result = {
|
|
@@ -13444,7 +13906,7 @@ function detectFramework(projectRoot) {
|
|
|
13444
13906
|
const pkgPath = resolve6(projectRoot, "package.json");
|
|
13445
13907
|
if (!existsSync10(pkgPath)) return result;
|
|
13446
13908
|
try {
|
|
13447
|
-
const pkg = JSON.parse(
|
|
13909
|
+
const pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
|
|
13448
13910
|
const allDeps = {
|
|
13449
13911
|
...pkg.dependencies,
|
|
13450
13912
|
...pkg.devDependencies
|
|
@@ -13491,7 +13953,7 @@ function detectPython(projectRoot) {
|
|
|
13491
13953
|
const filePath = resolve6(projectRoot, file);
|
|
13492
13954
|
if (existsSync10(filePath)) {
|
|
13493
13955
|
try {
|
|
13494
|
-
const content =
|
|
13956
|
+
const content = readFileSync11(filePath, "utf-8").toLowerCase();
|
|
13495
13957
|
if (content.includes("fastapi")) result.hasFastapi = true;
|
|
13496
13958
|
if (content.includes("sqlalchemy")) result.hasSqlalchemy = true;
|
|
13497
13959
|
} catch {
|
|
@@ -13516,7 +13978,7 @@ function detectPython(projectRoot) {
|
|
|
13516
13978
|
}
|
|
13517
13979
|
if (existsSync10(candidatePath)) {
|
|
13518
13980
|
try {
|
|
13519
|
-
const files =
|
|
13981
|
+
const files = readdirSync11(candidatePath);
|
|
13520
13982
|
if (files.some((f2) => f2.endsWith(".py"))) {
|
|
13521
13983
|
result.root = candidate;
|
|
13522
13984
|
break;
|
|
@@ -13581,7 +14043,7 @@ function generateConfig(projectRoot, framework) {
|
|
|
13581
14043
|
# Documentation: https://massu.ai/docs/getting-started/configuration
|
|
13582
14044
|
|
|
13583
14045
|
${yamlStringify(config)}`;
|
|
13584
|
-
|
|
14046
|
+
writeFileSync3(configPath, yamlContent, "utf-8");
|
|
13585
14047
|
return true;
|
|
13586
14048
|
}
|
|
13587
14049
|
function monorepoCommonRoot(packages) {
|
|
@@ -13752,7 +14214,7 @@ function applyVariantTemplate(config, templatesDir) {
|
|
|
13752
14214
|
if (!existsSync10(templatePath)) return config;
|
|
13753
14215
|
let template;
|
|
13754
14216
|
try {
|
|
13755
|
-
template = yamlParse(
|
|
14217
|
+
template = yamlParse(readFileSync11(templatePath, "utf-8"));
|
|
13756
14218
|
} catch {
|
|
13757
14219
|
return config;
|
|
13758
14220
|
}
|
|
@@ -13819,7 +14281,7 @@ function writeConfigAtomic(configPath, content) {
|
|
|
13819
14281
|
}
|
|
13820
14282
|
}
|
|
13821
14283
|
try {
|
|
13822
|
-
|
|
14284
|
+
mkdirSync5(dirname6(configPath), { recursive: true });
|
|
13823
14285
|
const fd = openSync2(tmpPath, "w", 420);
|
|
13824
14286
|
try {
|
|
13825
14287
|
const buf = Buffer.from(content, "utf-8");
|
|
@@ -13832,10 +14294,10 @@ function writeConfigAtomic(configPath, content) {
|
|
|
13832
14294
|
if (parsed === null || typeof parsed !== "object") {
|
|
13833
14295
|
throw new Error("Generated config is not a valid YAML object");
|
|
13834
14296
|
}
|
|
13835
|
-
|
|
14297
|
+
renameSync4(tmpPath, configPath);
|
|
13836
14298
|
if (existingMode !== void 0) {
|
|
13837
14299
|
try {
|
|
13838
|
-
|
|
14300
|
+
chmodSync3(configPath, existingMode);
|
|
13839
14301
|
} catch {
|
|
13840
14302
|
}
|
|
13841
14303
|
}
|
|
@@ -13853,7 +14315,7 @@ function writeConfigAtomic(configPath, content) {
|
|
|
13853
14315
|
function validateWrittenConfig(configPath, projectRoot, checkPaths = true) {
|
|
13854
14316
|
try {
|
|
13855
14317
|
if (!existsSync10(configPath)) return "Config file does not exist after write";
|
|
13856
|
-
const content =
|
|
14318
|
+
const content = readFileSync11(configPath, "utf-8");
|
|
13857
14319
|
const parsed = yamlParse(content);
|
|
13858
14320
|
if (parsed === null || typeof parsed !== "object") {
|
|
13859
14321
|
return "Config is not a valid YAML object";
|
|
@@ -13954,9 +14416,9 @@ function copyTemplateConfig(templateName, targetPath, projectName) {
|
|
|
13954
14416
|
return { success: false, error: `Template '${templateName}' not found at ${srcPath}` };
|
|
13955
14417
|
}
|
|
13956
14418
|
try {
|
|
13957
|
-
let content =
|
|
14419
|
+
let content = readFileSync11(srcPath, "utf-8");
|
|
13958
14420
|
content = content.replace(/\{\{PROJECT_NAME\}\}/g, projectName);
|
|
13959
|
-
|
|
14421
|
+
writeFileSync3(targetPath, content, "utf-8");
|
|
13960
14422
|
return { success: true };
|
|
13961
14423
|
} catch (err) {
|
|
13962
14424
|
return { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
@@ -13967,7 +14429,7 @@ function registerMcpServer(projectRoot) {
|
|
|
13967
14429
|
let existing = {};
|
|
13968
14430
|
if (existsSync10(mcpPath)) {
|
|
13969
14431
|
try {
|
|
13970
|
-
existing = JSON.parse(
|
|
14432
|
+
existing = JSON.parse(readFileSync11(mcpPath, "utf-8"));
|
|
13971
14433
|
} catch {
|
|
13972
14434
|
existing = {};
|
|
13973
14435
|
}
|
|
@@ -13982,7 +14444,7 @@ function registerMcpServer(projectRoot) {
|
|
|
13982
14444
|
args: ["-y", "@massu/core"]
|
|
13983
14445
|
};
|
|
13984
14446
|
existing.mcpServers = servers;
|
|
13985
|
-
|
|
14447
|
+
writeFileSync3(mcpPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
13986
14448
|
return true;
|
|
13987
14449
|
}
|
|
13988
14450
|
function resolveHooksDir() {
|
|
@@ -14087,12 +14549,12 @@ function installHooks(projectRoot) {
|
|
|
14087
14549
|
const claudeDir = resolve6(projectRoot, claudeDirName);
|
|
14088
14550
|
const settingsPath = resolve6(claudeDir, "settings.local.json");
|
|
14089
14551
|
if (!existsSync10(claudeDir)) {
|
|
14090
|
-
|
|
14552
|
+
mkdirSync5(claudeDir, { recursive: true });
|
|
14091
14553
|
}
|
|
14092
14554
|
let settings = {};
|
|
14093
14555
|
if (existsSync10(settingsPath)) {
|
|
14094
14556
|
try {
|
|
14095
|
-
settings = JSON.parse(
|
|
14557
|
+
settings = JSON.parse(readFileSync11(settingsPath, "utf-8"));
|
|
14096
14558
|
} catch {
|
|
14097
14559
|
settings = {};
|
|
14098
14560
|
}
|
|
@@ -14106,15 +14568,15 @@ function installHooks(projectRoot) {
|
|
|
14106
14568
|
}
|
|
14107
14569
|
}
|
|
14108
14570
|
settings.hooks = hooksConfig;
|
|
14109
|
-
|
|
14571
|
+
writeFileSync3(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
14110
14572
|
return { installed: true, count: hookCount };
|
|
14111
14573
|
}
|
|
14112
14574
|
function initMemoryDir(projectRoot) {
|
|
14113
14575
|
const encodedRoot = "-" + projectRoot.replace(/\//g, "-");
|
|
14114
|
-
const memoryDir = resolve6(
|
|
14576
|
+
const memoryDir = resolve6(homedir4(), `.claude/projects/${encodedRoot}/memory`);
|
|
14115
14577
|
let created = false;
|
|
14116
14578
|
if (!existsSync10(memoryDir)) {
|
|
14117
|
-
|
|
14579
|
+
mkdirSync5(memoryDir, { recursive: true });
|
|
14118
14580
|
created = true;
|
|
14119
14581
|
}
|
|
14120
14582
|
const memoryMdPath = resolve6(memoryDir, "MEMORY.md");
|
|
@@ -14135,7 +14597,7 @@ function initMemoryDir(projectRoot) {
|
|
|
14135
14597
|
## File Index
|
|
14136
14598
|
<!-- Significant files and directories -->
|
|
14137
14599
|
`;
|
|
14138
|
-
|
|
14600
|
+
writeFileSync3(memoryMdPath, memoryContent, "utf-8");
|
|
14139
14601
|
memoryMdCreated = true;
|
|
14140
14602
|
}
|
|
14141
14603
|
return { created, memoryMdCreated };
|
|
@@ -14387,8 +14849,8 @@ function installSideEffects(projectRoot, log, skipCommands = false, emptyStack =
|
|
|
14387
14849
|
"\u2014 Massu"
|
|
14388
14850
|
].join("\n");
|
|
14389
14851
|
try {
|
|
14390
|
-
|
|
14391
|
-
|
|
14852
|
+
mkdirSync5(resolve6(cmdResult.claudeDir, "commands"), { recursive: true });
|
|
14853
|
+
writeFileSync3(placeholderPath, placeholderBody, "utf-8");
|
|
14392
14854
|
log(" Wrote _massu-needs-stack.md placeholder (no stack detected yet)");
|
|
14393
14855
|
} catch {
|
|
14394
14856
|
}
|
|
@@ -14407,8 +14869,8 @@ function installSideEffects(projectRoot, log, skipCommands = false, emptyStack =
|
|
|
14407
14869
|
(async () => {
|
|
14408
14870
|
try {
|
|
14409
14871
|
const encodedRoot = projectRoot.replace(/\//g, "-");
|
|
14410
|
-
const memoryDir = resolve6(
|
|
14411
|
-
const memFiles = existsSync10(memoryDir) ?
|
|
14872
|
+
const memoryDir = resolve6(homedir4(), ".claude", "projects", encodedRoot, "memory");
|
|
14873
|
+
const memFiles = existsSync10(memoryDir) ? readdirSync11(memoryDir).filter((f2) => f2.endsWith(".md") && f2 !== "MEMORY.md") : [];
|
|
14412
14874
|
if (memFiles.length > 0) {
|
|
14413
14875
|
const { getMemoryDb: getMemoryDb2 } = await Promise.resolve().then(() => (init_memory_db(), memory_db_exports));
|
|
14414
14876
|
const db = getMemoryDb2();
|
|
@@ -14431,7 +14893,7 @@ function installSideEffects(projectRoot, log, skipCommands = false, emptyStack =
|
|
|
14431
14893
|
}
|
|
14432
14894
|
async function promptOverwrite(configPath) {
|
|
14433
14895
|
try {
|
|
14434
|
-
const { confirm, isCancel } = await Promise.resolve().then(() => (
|
|
14896
|
+
const { confirm, isCancel } = await Promise.resolve().then(() => (init_dist7(), dist_exports));
|
|
14435
14897
|
const res = await confirm({
|
|
14436
14898
|
message: `massu.config.yaml already exists at ${configPath}. Overwrite?`,
|
|
14437
14899
|
initialValue: false
|
|
@@ -14444,7 +14906,7 @@ async function promptOverwrite(configPath) {
|
|
|
14444
14906
|
}
|
|
14445
14907
|
async function promptStackConfirm() {
|
|
14446
14908
|
try {
|
|
14447
|
-
const { confirm, isCancel } = await Promise.resolve().then(() => (
|
|
14909
|
+
const { confirm, isCancel } = await Promise.resolve().then(() => (init_dist7(), dist_exports));
|
|
14448
14910
|
const res = await confirm({
|
|
14449
14911
|
message: "Generate massu.config.yaml from detected stack?",
|
|
14450
14912
|
initialValue: true
|
|
@@ -14468,7 +14930,7 @@ var init_init = __esm({
|
|
|
14468
14930
|
init_detect();
|
|
14469
14931
|
init_drift();
|
|
14470
14932
|
__filename2 = fileURLToPath2(import.meta.url);
|
|
14471
|
-
__dirname2 =
|
|
14933
|
+
__dirname2 = dirname6(__filename2);
|
|
14472
14934
|
FRAMEWORK_TO_TEMPLATE_ID = {
|
|
14473
14935
|
rails: "rails",
|
|
14474
14936
|
phoenix: "phoenix",
|
|
@@ -14490,7 +14952,7 @@ var init_init = __esm({
|
|
|
14490
14952
|
});
|
|
14491
14953
|
|
|
14492
14954
|
// src/license.ts
|
|
14493
|
-
import { createHash as
|
|
14955
|
+
import { createHash as createHash5 } from "crypto";
|
|
14494
14956
|
function tierLevel(tier) {
|
|
14495
14957
|
return TIER_LEVELS[tier] ?? 0;
|
|
14496
14958
|
}
|
|
@@ -14515,7 +14977,7 @@ function annotateToolDefinitions(defs) {
|
|
|
14515
14977
|
});
|
|
14516
14978
|
}
|
|
14517
14979
|
async function validateLicense(apiKey) {
|
|
14518
|
-
const keyHash =
|
|
14980
|
+
const keyHash = createHash5("sha256").update(apiKey).digest("hex");
|
|
14519
14981
|
const memDb = getMemoryDb();
|
|
14520
14982
|
try {
|
|
14521
14983
|
const cached = memDb.prepare(
|
|
@@ -14576,7 +15038,7 @@ async function validateLicense(apiKey) {
|
|
|
14576
15038
|
}
|
|
14577
15039
|
}
|
|
14578
15040
|
function updateLicenseCache(apiKey, tier, validUntil, features = []) {
|
|
14579
|
-
const keyHash =
|
|
15041
|
+
const keyHash = createHash5("sha256").update(apiKey).digest("hex");
|
|
14580
15042
|
const memDb = getMemoryDb();
|
|
14581
15043
|
try {
|
|
14582
15044
|
memDb.prepare(`
|
|
@@ -14784,8 +15246,8 @@ __export(doctor_exports, {
|
|
|
14784
15246
|
runDoctor: () => runDoctor,
|
|
14785
15247
|
runValidateConfig: () => runValidateConfig
|
|
14786
15248
|
});
|
|
14787
|
-
import { existsSync as existsSync11, readFileSync as
|
|
14788
|
-
import { resolve as resolve7, dirname as
|
|
15249
|
+
import { existsSync as existsSync11, readFileSync as readFileSync12, readdirSync as readdirSync12 } from "fs";
|
|
15250
|
+
import { resolve as resolve7, dirname as dirname7 } from "path";
|
|
14789
15251
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
14790
15252
|
import { parse as parseYaml4 } from "yaml";
|
|
14791
15253
|
function checkConfig(projectRoot) {
|
|
@@ -14794,7 +15256,7 @@ function checkConfig(projectRoot) {
|
|
|
14794
15256
|
return { name: "Configuration", status: "fail", detail: "massu.config.yaml not found. Run: npx massu init" };
|
|
14795
15257
|
}
|
|
14796
15258
|
try {
|
|
14797
|
-
const content =
|
|
15259
|
+
const content = readFileSync12(configPath, "utf-8");
|
|
14798
15260
|
const parsed = parseYaml4(content);
|
|
14799
15261
|
if (!parsed || typeof parsed !== "object") {
|
|
14800
15262
|
return { name: "Configuration", status: "fail", detail: "massu.config.yaml is empty or invalid YAML" };
|
|
@@ -14810,7 +15272,7 @@ function checkMcpServer(projectRoot) {
|
|
|
14810
15272
|
return { name: "MCP Server", status: "fail", detail: ".mcp.json not found. Run: npx massu init" };
|
|
14811
15273
|
}
|
|
14812
15274
|
try {
|
|
14813
|
-
const content = JSON.parse(
|
|
15275
|
+
const content = JSON.parse(readFileSync12(mcpPath, "utf-8"));
|
|
14814
15276
|
const servers = content.mcpServers ?? {};
|
|
14815
15277
|
if (!servers.massu) {
|
|
14816
15278
|
return { name: "MCP Server", status: "fail", detail: "massu not registered in .mcp.json. Run: npx massu init" };
|
|
@@ -14826,7 +15288,7 @@ function checkHooksConfig(projectRoot) {
|
|
|
14826
15288
|
return { name: "Hooks Config", status: "fail", detail: ".claude/settings.local.json not found. Run: npx massu init" };
|
|
14827
15289
|
}
|
|
14828
15290
|
try {
|
|
14829
|
-
const content = JSON.parse(
|
|
15291
|
+
const content = JSON.parse(readFileSync12(settingsPath, "utf-8"));
|
|
14830
15292
|
if (!content.hooks) {
|
|
14831
15293
|
return { name: "Hooks Config", status: "fail", detail: "No hooks configured. Run: npx massu install-hooks" };
|
|
14832
15294
|
}
|
|
@@ -14937,7 +15399,7 @@ function checkShellHooksWired(_projectRoot2) {
|
|
|
14937
15399
|
};
|
|
14938
15400
|
}
|
|
14939
15401
|
try {
|
|
14940
|
-
const content = JSON.parse(
|
|
15402
|
+
const content = JSON.parse(readFileSync12(settingsPath, "utf-8"));
|
|
14941
15403
|
const hooks = content.hooks ?? {};
|
|
14942
15404
|
const hasSessionStart = Array.isArray(hooks.SessionStart) && hooks.SessionStart.length > 0;
|
|
14943
15405
|
const hasPreToolUse = Array.isArray(hooks.PreToolUse) && hooks.PreToolUse.length > 0;
|
|
@@ -15003,7 +15465,7 @@ function checkPythonHealth(projectRoot) {
|
|
|
15003
15465
|
function scanDir(dir, depth) {
|
|
15004
15466
|
if (depth > 5) return;
|
|
15005
15467
|
try {
|
|
15006
|
-
const entries =
|
|
15468
|
+
const entries = readdirSync12(dir, { withFileTypes: true });
|
|
15007
15469
|
for (const entry of entries) {
|
|
15008
15470
|
if (entry.isDirectory()) {
|
|
15009
15471
|
const excludeDirs = config.python?.exclude_dirs || ["__pycache__", ".venv", "venv", ".mypy_cache", ".pytest_cache"];
|
|
@@ -15011,7 +15473,7 @@ function checkPythonHealth(projectRoot) {
|
|
|
15011
15473
|
const subdir = resolve7(dir, entry.name);
|
|
15012
15474
|
if (depth <= 2 && !existsSync11(resolve7(subdir, "__init__.py"))) {
|
|
15013
15475
|
try {
|
|
15014
|
-
const subEntries =
|
|
15476
|
+
const subEntries = readdirSync12(subdir);
|
|
15015
15477
|
if (subEntries.some((f2) => f2.endsWith(".py") && f2 !== "__init__.py")) {
|
|
15016
15478
|
initPyMissing.push(entry.name);
|
|
15017
15479
|
}
|
|
@@ -15112,7 +15574,7 @@ async function runValidateConfig() {
|
|
|
15112
15574
|
return;
|
|
15113
15575
|
}
|
|
15114
15576
|
try {
|
|
15115
|
-
const content =
|
|
15577
|
+
const content = readFileSync12(configPath, "utf-8");
|
|
15116
15578
|
const parsed = parseYaml4(content);
|
|
15117
15579
|
if (!parsed || typeof parsed !== "object") {
|
|
15118
15580
|
console.error("Error: massu.config.yaml is empty or not a valid YAML object");
|
|
@@ -15151,7 +15613,7 @@ var init_doctor = __esm({
|
|
|
15151
15613
|
init_config();
|
|
15152
15614
|
init_license();
|
|
15153
15615
|
__filename3 = fileURLToPath3(import.meta.url);
|
|
15154
|
-
__dirname3 =
|
|
15616
|
+
__dirname3 = dirname7(__filename3);
|
|
15155
15617
|
EXPECTED_HOOKS = [
|
|
15156
15618
|
"session-start.js",
|
|
15157
15619
|
"session-end.js",
|
|
@@ -15197,7 +15659,7 @@ var show_template_exports = {};
|
|
|
15197
15659
|
__export(show_template_exports, {
|
|
15198
15660
|
runShowTemplate: () => runShowTemplate
|
|
15199
15661
|
});
|
|
15200
|
-
import { existsSync as existsSync12, readFileSync as
|
|
15662
|
+
import { existsSync as existsSync12, readFileSync as readFileSync13 } from "fs";
|
|
15201
15663
|
import { resolve as resolve8 } from "path";
|
|
15202
15664
|
function normalizeBaseName(input) {
|
|
15203
15665
|
return input.endsWith(".md") ? input.slice(0, -".md".length) : input;
|
|
@@ -15233,7 +15695,7 @@ async function runShowTemplate(args2) {
|
|
|
15233
15695
|
process.exit(1);
|
|
15234
15696
|
return;
|
|
15235
15697
|
}
|
|
15236
|
-
process.stdout.write(
|
|
15698
|
+
process.stdout.write(readFileSync13(file, "utf-8"));
|
|
15237
15699
|
}
|
|
15238
15700
|
var init_show_template = __esm({
|
|
15239
15701
|
"src/commands/show-template.ts"() {
|
|
@@ -15286,12 +15748,12 @@ var init_passthrough = __esm({
|
|
|
15286
15748
|
});
|
|
15287
15749
|
|
|
15288
15750
|
// src/lib/fileLock.ts
|
|
15289
|
-
import { mkdirSync as
|
|
15290
|
-
import { dirname as
|
|
15751
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync14, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
15752
|
+
import { dirname as dirname8 } from "path";
|
|
15291
15753
|
import * as lockfile from "proper-lockfile";
|
|
15292
15754
|
function readLockHolderPid(lockPath) {
|
|
15293
15755
|
try {
|
|
15294
|
-
const raw =
|
|
15756
|
+
const raw = readFileSync14(`${lockPath}.pid`, "utf-8").trim();
|
|
15295
15757
|
const pid = Number.parseInt(raw, 10);
|
|
15296
15758
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
15297
15759
|
return pid;
|
|
@@ -15310,7 +15772,7 @@ function busyWaitSync(ms) {
|
|
|
15310
15772
|
Atomics.wait(view, 0, 0, ms);
|
|
15311
15773
|
}
|
|
15312
15774
|
function withFileLockSync(lockPath, fn, opts = {}) {
|
|
15313
|
-
|
|
15775
|
+
mkdirSync6(dirname8(lockPath), { recursive: true });
|
|
15314
15776
|
const staleMs = opts.staleMs ?? 3e4;
|
|
15315
15777
|
const blockMs = opts.retries === 0 ? 0 : opts.blockMs ?? 3e4;
|
|
15316
15778
|
const pollIntervalMs = opts.pollIntervalMs ?? 100;
|
|
@@ -15327,7 +15789,7 @@ function withFileLockSync(lockPath, fn, opts = {}) {
|
|
|
15327
15789
|
realpath: false
|
|
15328
15790
|
});
|
|
15329
15791
|
try {
|
|
15330
|
-
|
|
15792
|
+
writeFileSync4(`${lockPath}.pid`, String(process.pid), "utf-8");
|
|
15331
15793
|
} catch {
|
|
15332
15794
|
}
|
|
15333
15795
|
break;
|
|
@@ -15416,7 +15878,7 @@ __export(config_refresh_exports, {
|
|
|
15416
15878
|
mergeRefresh: () => mergeRefresh,
|
|
15417
15879
|
runConfigRefresh: () => runConfigRefresh
|
|
15418
15880
|
});
|
|
15419
|
-
import { existsSync as existsSync13, readFileSync as
|
|
15881
|
+
import { existsSync as existsSync13, readFileSync as readFileSync15, rmSync as rmSync4 } from "fs";
|
|
15420
15882
|
import { resolve as resolve10 } from "path";
|
|
15421
15883
|
import { parse as parseYaml5 } from "yaml";
|
|
15422
15884
|
function flatten(obj, prefix3 = "") {
|
|
@@ -15555,7 +16017,7 @@ async function runConfigRefresh(opts = {}) {
|
|
|
15555
16017
|
}
|
|
15556
16018
|
let existing;
|
|
15557
16019
|
try {
|
|
15558
|
-
const content =
|
|
16020
|
+
const content = readFileSync15(configPath, "utf-8");
|
|
15559
16021
|
const parsed = parseYaml5(content);
|
|
15560
16022
|
if (!parsed || typeof parsed !== "object") {
|
|
15561
16023
|
throw new Error("config is not a YAML object");
|
|
@@ -15600,7 +16062,7 @@ async function runConfigRefresh(opts = {}) {
|
|
|
15600
16062
|
}
|
|
15601
16063
|
log("Config diff:\n");
|
|
15602
16064
|
log(renderDiff(diff));
|
|
15603
|
-
const { confirm } = await Promise.resolve().then(() => (
|
|
16065
|
+
const { confirm } = await Promise.resolve().then(() => (init_dist7(), dist_exports));
|
|
15604
16066
|
const apply = await confirm({ message: "Apply these changes to massu.config.yaml?" });
|
|
15605
16067
|
if (apply !== true) {
|
|
15606
16068
|
log("Aborted; no changes written.\n");
|
|
@@ -15953,8 +16415,8 @@ var init_paths = __esm({
|
|
|
15953
16415
|
});
|
|
15954
16416
|
|
|
15955
16417
|
// src/watch/state.ts
|
|
15956
|
-
import { closeSync as closeSync3, existsSync as existsSync15, fsyncSync as fsyncSync3, mkdirSync as
|
|
15957
|
-
import { dirname as
|
|
16418
|
+
import { closeSync as closeSync3, existsSync as existsSync15, fsyncSync as fsyncSync3, mkdirSync as mkdirSync7, openSync as openSync3, readFileSync as readFileSync16, renameSync as renameSync5, rmSync as rmSync5, writeFileSync as writeFileSync5, writeSync as writeSync3 } from "fs";
|
|
16419
|
+
import { dirname as dirname9, resolve as resolve12 } from "path";
|
|
15958
16420
|
function watchStatePath(projectRoot) {
|
|
15959
16421
|
return resolve12(projectRoot, ".massu", "watch-state.json");
|
|
15960
16422
|
}
|
|
@@ -15964,7 +16426,7 @@ function backupStatePath(projectRoot) {
|
|
|
15964
16426
|
function readState(projectRoot) {
|
|
15965
16427
|
const path = watchStatePath(projectRoot);
|
|
15966
16428
|
if (!existsSync15(path)) return { ...DEFAULT_STATE };
|
|
15967
|
-
const content =
|
|
16429
|
+
const content = readFileSync16(path, "utf-8");
|
|
15968
16430
|
let raw;
|
|
15969
16431
|
try {
|
|
15970
16432
|
raw = JSON.parse(content);
|
|
@@ -16006,14 +16468,14 @@ function readState(projectRoot) {
|
|
|
16006
16468
|
}
|
|
16007
16469
|
function archiveCorrupt(projectRoot, content) {
|
|
16008
16470
|
const bak = backupStatePath(projectRoot);
|
|
16009
|
-
|
|
16010
|
-
|
|
16471
|
+
mkdirSync7(dirname9(bak), { recursive: true });
|
|
16472
|
+
writeFileSync5(bak, content, "utf-8");
|
|
16011
16473
|
}
|
|
16012
16474
|
function writeStateAtomic(projectRoot, state) {
|
|
16013
16475
|
const path = watchStatePath(projectRoot);
|
|
16014
16476
|
writeStateAtomicCounter = writeStateAtomicCounter + 1 >>> 0;
|
|
16015
16477
|
const tmp = `${path}.${process.pid}.${writeStateAtomicCounter}.tmp`;
|
|
16016
|
-
|
|
16478
|
+
mkdirSync7(dirname9(path), { recursive: true });
|
|
16017
16479
|
let renamed = false;
|
|
16018
16480
|
try {
|
|
16019
16481
|
const fd = openSync3(tmp, "w");
|
|
@@ -16024,7 +16486,7 @@ function writeStateAtomic(projectRoot, state) {
|
|
|
16024
16486
|
} finally {
|
|
16025
16487
|
closeSync3(fd);
|
|
16026
16488
|
}
|
|
16027
|
-
|
|
16489
|
+
renameSync5(tmp, path);
|
|
16028
16490
|
renamed = true;
|
|
16029
16491
|
} finally {
|
|
16030
16492
|
if (!renamed && existsSync15(tmp)) {
|
|
@@ -16307,8 +16769,8 @@ __export(watch_exports, {
|
|
|
16307
16769
|
runWatch: () => runWatch
|
|
16308
16770
|
});
|
|
16309
16771
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
16310
|
-
import { basename as basename5, dirname as
|
|
16311
|
-
import { appendFileSync, existsSync as existsSync16, mkdirSync as
|
|
16772
|
+
import { basename as basename5, dirname as dirname10, resolve as resolve13 } from "path";
|
|
16773
|
+
import { appendFileSync, existsSync as existsSync16, mkdirSync as mkdirSync8, readFileSync as readFileSync17 } from "fs";
|
|
16312
16774
|
function parseFlags(args2) {
|
|
16313
16775
|
const out = {
|
|
16314
16776
|
foreground: false,
|
|
@@ -16553,7 +17015,7 @@ function refreshLogPath(projectRoot) {
|
|
|
16553
17015
|
function appendRefreshLog(projectRoot, event) {
|
|
16554
17016
|
const path = refreshLogPath(projectRoot);
|
|
16555
17017
|
try {
|
|
16556
|
-
|
|
17018
|
+
mkdirSync8(dirname10(path), { recursive: true });
|
|
16557
17019
|
appendFileSync(path, JSON.stringify(event) + "\n", "utf-8");
|
|
16558
17020
|
} catch {
|
|
16559
17021
|
}
|
|
@@ -16564,7 +17026,7 @@ function readRefreshLog(projectRoot, limit = 10, opts = {}) {
|
|
|
16564
17026
|
const warn = opts.warn ?? ((s) => {
|
|
16565
17027
|
process.stderr.write(s);
|
|
16566
17028
|
});
|
|
16567
|
-
const lines =
|
|
17029
|
+
const lines = readFileSync17(path, "utf-8").split("\n").filter(Boolean);
|
|
16568
17030
|
const tail = lines.slice(-limit);
|
|
16569
17031
|
const out = [];
|
|
16570
17032
|
let corrupt = 0;
|
|
@@ -16635,28 +17097,28 @@ var init_refresh_log = __esm({
|
|
|
16635
17097
|
|
|
16636
17098
|
// src/security/atomic-write.ts
|
|
16637
17099
|
import {
|
|
16638
|
-
chmodSync as
|
|
17100
|
+
chmodSync as chmodSync4,
|
|
16639
17101
|
closeSync as closeSync4,
|
|
16640
17102
|
existsSync as existsSync17,
|
|
16641
17103
|
fsyncSync as fsyncSync4,
|
|
16642
|
-
mkdirSync as
|
|
17104
|
+
mkdirSync as mkdirSync9,
|
|
16643
17105
|
openSync as openSync4,
|
|
16644
|
-
renameSync as
|
|
17106
|
+
renameSync as renameSync6,
|
|
16645
17107
|
rmSync as rmSync6,
|
|
16646
17108
|
statSync as statSync9,
|
|
16647
17109
|
writeSync as writeSync4
|
|
16648
17110
|
} from "node:fs";
|
|
16649
|
-
import { dirname as
|
|
17111
|
+
import { dirname as dirname11 } from "node:path";
|
|
16650
17112
|
function atomicWrite(path, content, opts = {}) {
|
|
16651
17113
|
const tmpPath = `${path}.tmp`;
|
|
16652
|
-
const parentDir =
|
|
17114
|
+
const parentDir = dirname11(path);
|
|
16653
17115
|
try {
|
|
16654
17116
|
if (!existsSync17(parentDir)) {
|
|
16655
17117
|
const mkdirOpts = { recursive: true };
|
|
16656
17118
|
if (opts.ensureParentDirMode !== void 0) {
|
|
16657
17119
|
mkdirOpts.mode = opts.ensureParentDirMode;
|
|
16658
17120
|
}
|
|
16659
|
-
|
|
17121
|
+
mkdirSync9(parentDir, mkdirOpts);
|
|
16660
17122
|
}
|
|
16661
17123
|
const buf = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
|
|
16662
17124
|
const openMode = opts.mode ?? 420;
|
|
@@ -16668,9 +17130,9 @@ function atomicWrite(path, content, opts = {}) {
|
|
|
16668
17130
|
closeSync4(fd);
|
|
16669
17131
|
}
|
|
16670
17132
|
if (opts.mode !== void 0) {
|
|
16671
|
-
|
|
17133
|
+
chmodSync4(tmpPath, opts.mode);
|
|
16672
17134
|
}
|
|
16673
|
-
|
|
17135
|
+
renameSync6(tmpPath, path);
|
|
16674
17136
|
return { written: true };
|
|
16675
17137
|
} catch (err) {
|
|
16676
17138
|
if (existsSync17(tmpPath)) {
|
|
@@ -16753,10 +17215,10 @@ var init_registry_pubkey_generated = __esm({
|
|
|
16753
17215
|
});
|
|
16754
17216
|
|
|
16755
17217
|
// src/security/adapter-verifier.ts
|
|
16756
|
-
import { createHash as
|
|
17218
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
16757
17219
|
import nacl from "tweetnacl";
|
|
16758
17220
|
function sha256Hex(bytes) {
|
|
16759
|
-
return
|
|
17221
|
+
return createHash6("sha256").update(bytes).digest("hex");
|
|
16760
17222
|
}
|
|
16761
17223
|
function reviver(key, value) {
|
|
16762
17224
|
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
@@ -17016,12 +17478,12 @@ var init_fetcher = __esm({
|
|
|
17016
17478
|
});
|
|
17017
17479
|
|
|
17018
17480
|
// src/security/manifest-cache.ts
|
|
17019
|
-
import { existsSync as existsSync18, readFileSync as
|
|
17020
|
-
import { homedir as
|
|
17481
|
+
import { existsSync as existsSync18, readFileSync as readFileSync18, statSync as statSync10 } from "node:fs";
|
|
17482
|
+
import { homedir as homedir5 } from "node:os";
|
|
17021
17483
|
import { resolve as resolve14 } from "node:path";
|
|
17022
17484
|
import { z as z4 } from "zod";
|
|
17023
17485
|
function defaultCachePaths() {
|
|
17024
|
-
const dir = resolve14(
|
|
17486
|
+
const dir = resolve14(homedir5(), ".massu");
|
|
17025
17487
|
return {
|
|
17026
17488
|
cachePath: resolve14(dir, "adapter-manifest.json"),
|
|
17027
17489
|
lockPath: resolve14(dir, ".adapter-manifest.lock")
|
|
@@ -17033,7 +17495,7 @@ function loadCachedManifest(paths = defaultCachePaths()) {
|
|
|
17033
17495
|
}
|
|
17034
17496
|
let raw;
|
|
17035
17497
|
try {
|
|
17036
|
-
const content =
|
|
17498
|
+
const content = readFileSync18(paths.cachePath, "utf-8");
|
|
17037
17499
|
raw = JSON.parse(content);
|
|
17038
17500
|
} catch (err) {
|
|
17039
17501
|
return {
|
|
@@ -17222,10 +17684,10 @@ var init_adapter_origin = __esm({
|
|
|
17222
17684
|
});
|
|
17223
17685
|
|
|
17224
17686
|
// src/security/local-fingerprint.ts
|
|
17225
|
-
import { existsSync as existsSync19, readFileSync as
|
|
17226
|
-
import { homedir as
|
|
17687
|
+
import { existsSync as existsSync19, readFileSync as readFileSync19, lstatSync as lstatSync6 } from "node:fs";
|
|
17688
|
+
import { homedir as homedir6 } from "node:os";
|
|
17227
17689
|
import { resolve as resolve15, isAbsolute } from "node:path";
|
|
17228
|
-
import { createHash as
|
|
17690
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
17229
17691
|
import { z as z5 } from "zod";
|
|
17230
17692
|
function computeLocalFingerprint(localPaths, projectRoot) {
|
|
17231
17693
|
const tuples = [];
|
|
@@ -17233,13 +17695,13 @@ function computeLocalFingerprint(localPaths, projectRoot) {
|
|
|
17233
17695
|
const abs = isAbsolute(p19) ? p19 : resolve15(projectRoot, p19);
|
|
17234
17696
|
let contentTag;
|
|
17235
17697
|
try {
|
|
17236
|
-
const lst =
|
|
17698
|
+
const lst = lstatSync6(abs);
|
|
17237
17699
|
if (lst.isSymbolicLink()) {
|
|
17238
17700
|
contentTag = "<symlink>";
|
|
17239
17701
|
} else if (!lst.isFile()) {
|
|
17240
17702
|
contentTag = "<not-a-file>";
|
|
17241
17703
|
} else {
|
|
17242
|
-
contentTag =
|
|
17704
|
+
contentTag = createHash7("sha256").update(readFileSync19(abs)).digest("hex");
|
|
17243
17705
|
}
|
|
17244
17706
|
} catch {
|
|
17245
17707
|
contentTag = "<missing>";
|
|
@@ -17248,13 +17710,13 @@ function computeLocalFingerprint(localPaths, projectRoot) {
|
|
|
17248
17710
|
}
|
|
17249
17711
|
tuples.sort((a2, b2) => a2.path < b2.path ? -1 : a2.path > b2.path ? 1 : 0);
|
|
17250
17712
|
const canonical = JSON.stringify(tuples);
|
|
17251
|
-
return
|
|
17713
|
+
return createHash7("sha256").update(canonical).digest("hex");
|
|
17252
17714
|
}
|
|
17253
17715
|
function readFingerprintSentinel(path = FINGERPRINT_PATH) {
|
|
17254
17716
|
if (!existsSync19(path)) return null;
|
|
17255
17717
|
let raw;
|
|
17256
17718
|
try {
|
|
17257
|
-
raw = JSON.parse(
|
|
17719
|
+
raw = JSON.parse(readFileSync19(path, "utf-8"));
|
|
17258
17720
|
} catch {
|
|
17259
17721
|
return null;
|
|
17260
17722
|
}
|
|
@@ -17302,7 +17764,7 @@ var init_local_fingerprint = __esm({
|
|
|
17302
17764
|
"use strict";
|
|
17303
17765
|
init_atomic_write();
|
|
17304
17766
|
init_manifest_schema();
|
|
17305
|
-
FINGERPRINT_PATH = resolve15(
|
|
17767
|
+
FINGERPRINT_PATH = resolve15(homedir6(), ".massu", "adapters-local-fingerprint.json");
|
|
17306
17768
|
FingerprintSentinelSchema = z5.object({
|
|
17307
17769
|
fingerprint: z5.string().regex(/^[0-9a-f]{64}$/),
|
|
17308
17770
|
source: z5.enum(["cli", "cli-resync"]),
|
|
@@ -17318,11 +17780,11 @@ var init_local_fingerprint = __esm({
|
|
|
17318
17780
|
});
|
|
17319
17781
|
|
|
17320
17782
|
// src/security/install-tracking.ts
|
|
17321
|
-
import { readFileSync as
|
|
17322
|
-
import { join as
|
|
17323
|
-
import { homedir as
|
|
17783
|
+
import { readFileSync as readFileSync20, readdirSync as readdirSync13, lstatSync as lstatSync7, existsSync as existsSync20 } from "node:fs";
|
|
17784
|
+
import { join as join11, relative as relative5, sep } from "node:path";
|
|
17785
|
+
import { homedir as homedir7 } from "node:os";
|
|
17324
17786
|
import { resolve as resolve16 } from "node:path";
|
|
17325
|
-
import { createHash as
|
|
17787
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
17326
17788
|
import { z as z6 } from "zod";
|
|
17327
17789
|
function containsHiddenDirs(packageDir) {
|
|
17328
17790
|
for (const hidden of EXCLUDED_DIR_NAMES) {
|
|
@@ -17338,15 +17800,15 @@ function sha256OfDir(dir, opts = {}) {
|
|
|
17338
17800
|
function walk(currentDir) {
|
|
17339
17801
|
let entries;
|
|
17340
17802
|
try {
|
|
17341
|
-
entries =
|
|
17803
|
+
entries = readdirSync13(currentDir);
|
|
17342
17804
|
} catch {
|
|
17343
17805
|
return;
|
|
17344
17806
|
}
|
|
17345
17807
|
for (const entry of entries.sort()) {
|
|
17346
|
-
const absPath =
|
|
17808
|
+
const absPath = join11(currentDir, entry);
|
|
17347
17809
|
let lst;
|
|
17348
17810
|
try {
|
|
17349
|
-
lst =
|
|
17811
|
+
lst = lstatSync7(absPath);
|
|
17350
17812
|
} catch {
|
|
17351
17813
|
continue;
|
|
17352
17814
|
}
|
|
@@ -17370,9 +17832,9 @@ function sha256OfDir(dir, opts = {}) {
|
|
|
17370
17832
|
}
|
|
17371
17833
|
walk(dir);
|
|
17372
17834
|
files.sort((a2, b2) => a2.relativePath < b2.relativePath ? -1 : a2.relativePath > b2.relativePath ? 1 : 0);
|
|
17373
|
-
const top =
|
|
17835
|
+
const top = createHash8("sha256");
|
|
17374
17836
|
for (const f2 of files) {
|
|
17375
|
-
const fileHash =
|
|
17837
|
+
const fileHash = createHash8("sha256").update(readFileSync20(f2.absPath)).digest("hex");
|
|
17376
17838
|
top.update(f2.relativePath, "utf-8");
|
|
17377
17839
|
top.update("\0", "utf-8");
|
|
17378
17840
|
top.update(fileHash, "utf-8");
|
|
@@ -17384,7 +17846,7 @@ function readInstalledManifest(path = INSTALLED_MANIFEST_PATH) {
|
|
|
17384
17846
|
if (!existsSync20(path)) return {};
|
|
17385
17847
|
let raw;
|
|
17386
17848
|
try {
|
|
17387
|
-
raw = JSON.parse(
|
|
17849
|
+
raw = JSON.parse(readFileSync20(path, "utf-8"));
|
|
17388
17850
|
} catch {
|
|
17389
17851
|
return {};
|
|
17390
17852
|
}
|
|
@@ -17448,7 +17910,7 @@ var init_install_tracking = __esm({
|
|
|
17448
17910
|
"src/security/install-tracking.ts"() {
|
|
17449
17911
|
"use strict";
|
|
17450
17912
|
init_atomic_write();
|
|
17451
|
-
INSTALLED_MANIFEST_PATH = resolve16(
|
|
17913
|
+
INSTALLED_MANIFEST_PATH = resolve16(homedir7(), ".massu", "adapter-manifest-installed.json");
|
|
17452
17914
|
DEFAULT_MAX_FILE_BYTES = 64 * 1024 * 1024;
|
|
17453
17915
|
EXCLUDED_DIR_NAMES = /* @__PURE__ */ new Set([".git", "node_modules", ".cache", ".tmp"]);
|
|
17454
17916
|
InstallEntrySchema = z6.object({
|
|
@@ -17471,7 +17933,7 @@ var init_install_tracking = __esm({
|
|
|
17471
17933
|
});
|
|
17472
17934
|
|
|
17473
17935
|
// src/detect/adapters/discover.ts
|
|
17474
|
-
import { existsSync as existsSync21, readdirSync as
|
|
17936
|
+
import { existsSync as existsSync21, readdirSync as readdirSync14, readFileSync as readFileSync21, lstatSync as lstatSync8 } from "node:fs";
|
|
17475
17937
|
import { resolve as resolve17, isAbsolute as isAbsolute2 } from "node:path";
|
|
17476
17938
|
import { z as z7 } from "zod";
|
|
17477
17939
|
function walkNodeModules(projectRoot, warnings) {
|
|
@@ -17482,7 +17944,7 @@ function walkNodeModules(projectRoot, warnings) {
|
|
|
17482
17944
|
const candidates = [];
|
|
17483
17945
|
let topLevelEntries;
|
|
17484
17946
|
try {
|
|
17485
|
-
topLevelEntries =
|
|
17947
|
+
topLevelEntries = readdirSync14(nodeModulesDir);
|
|
17486
17948
|
} catch (err) {
|
|
17487
17949
|
warnings.push(`failed to read node_modules: ${err instanceof Error ? err.message : String(err)}`);
|
|
17488
17950
|
return [];
|
|
@@ -17492,7 +17954,7 @@ function walkNodeModules(projectRoot, warnings) {
|
|
|
17492
17954
|
const entryPath = resolve17(nodeModulesDir, entry);
|
|
17493
17955
|
let entryStat;
|
|
17494
17956
|
try {
|
|
17495
|
-
entryStat =
|
|
17957
|
+
entryStat = lstatSync8(entryPath);
|
|
17496
17958
|
} catch {
|
|
17497
17959
|
continue;
|
|
17498
17960
|
}
|
|
@@ -17506,7 +17968,7 @@ function walkNodeModules(projectRoot, warnings) {
|
|
|
17506
17968
|
if (entry.startsWith("@")) {
|
|
17507
17969
|
let scopedEntries;
|
|
17508
17970
|
try {
|
|
17509
|
-
scopedEntries =
|
|
17971
|
+
scopedEntries = readdirSync14(entryPath);
|
|
17510
17972
|
} catch {
|
|
17511
17973
|
continue;
|
|
17512
17974
|
}
|
|
@@ -17514,7 +17976,7 @@ function walkNodeModules(projectRoot, warnings) {
|
|
|
17514
17976
|
const subPath = resolve17(entryPath, sub);
|
|
17515
17977
|
let subStat;
|
|
17516
17978
|
try {
|
|
17517
|
-
subStat =
|
|
17979
|
+
subStat = lstatSync8(subPath);
|
|
17518
17980
|
} catch {
|
|
17519
17981
|
continue;
|
|
17520
17982
|
}
|
|
@@ -17534,7 +17996,7 @@ function tryReadAdapterPackage(packageDir, warnings) {
|
|
|
17534
17996
|
if (!existsSync21(pkgJsonPath)) return null;
|
|
17535
17997
|
let raw;
|
|
17536
17998
|
try {
|
|
17537
|
-
raw = JSON.parse(
|
|
17999
|
+
raw = JSON.parse(readFileSync21(pkgJsonPath, "utf-8"));
|
|
17538
18000
|
} catch (err) {
|
|
17539
18001
|
warnings.push(
|
|
17540
18002
|
`skipping ${packageDir}: package.json parse failed (${err instanceof Error ? err.message : String(err)})`
|
|
@@ -17750,7 +18212,7 @@ __export(adapters_exports, {
|
|
|
17750
18212
|
runAdaptersResyncLocalFingerprint: () => runAdaptersResyncLocalFingerprint,
|
|
17751
18213
|
runAdaptersSearch: () => runAdaptersSearch
|
|
17752
18214
|
});
|
|
17753
|
-
import { existsSync as existsSync22, readFileSync as
|
|
18215
|
+
import { existsSync as existsSync22, readFileSync as readFileSync22 } from "node:fs";
|
|
17754
18216
|
import { resolve as resolve18 } from "node:path";
|
|
17755
18217
|
import { parseDocument } from "yaml";
|
|
17756
18218
|
async function handleAdaptersSubcommand(args2) {
|
|
@@ -18028,7 +18490,7 @@ function mutateLocalArray(mutator, command) {
|
|
|
18028
18490
|
}
|
|
18029
18491
|
let yamlText;
|
|
18030
18492
|
try {
|
|
18031
|
-
yamlText =
|
|
18493
|
+
yamlText = readFileSync22(yamlPath, "utf-8");
|
|
18032
18494
|
} catch (err) {
|
|
18033
18495
|
process.stderr.write(`${command}: failed to read ${yamlPath}: ${err instanceof Error ? err.message : String(err)}
|
|
18034
18496
|
`);
|
|
@@ -18134,7 +18596,7 @@ async function runAdaptersInstall(args2) {
|
|
|
18134
18596
|
}
|
|
18135
18597
|
let pkgJson;
|
|
18136
18598
|
try {
|
|
18137
|
-
pkgJson = JSON.parse(
|
|
18599
|
+
pkgJson = JSON.parse(readFileSync22(pkgJsonPath, "utf-8"));
|
|
18138
18600
|
} catch (err) {
|
|
18139
18601
|
process.stderr.write(`install: ${packageName} has malformed package.json: ${err instanceof Error ? err.message : String(err)}
|
|
18140
18602
|
`);
|
|
@@ -18341,8 +18803,8 @@ var init_adapters2 = __esm({
|
|
|
18341
18803
|
|
|
18342
18804
|
// src/db.ts
|
|
18343
18805
|
import Database2 from "better-sqlite3";
|
|
18344
|
-
import { dirname as
|
|
18345
|
-
import { existsSync as existsSync23, mkdirSync as
|
|
18806
|
+
import { dirname as dirname12, join as join12 } from "path";
|
|
18807
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync10, readdirSync as readdirSync15, statSync as statSync11 } from "fs";
|
|
18346
18808
|
function getCodeGraphDb() {
|
|
18347
18809
|
const dbPath = getResolvedPaths().codegraphDbPath;
|
|
18348
18810
|
if (!existsSync23(dbPath)) {
|
|
@@ -18354,9 +18816,9 @@ function getCodeGraphDb() {
|
|
|
18354
18816
|
}
|
|
18355
18817
|
function getDataDb() {
|
|
18356
18818
|
const dbPath = getResolvedPaths().dataDbPath;
|
|
18357
|
-
const dir =
|
|
18819
|
+
const dir = dirname12(dbPath);
|
|
18358
18820
|
if (!existsSync23(dir)) {
|
|
18359
|
-
|
|
18821
|
+
mkdirSync10(dir, { recursive: true });
|
|
18360
18822
|
}
|
|
18361
18823
|
const db = new Database2(dbPath);
|
|
18362
18824
|
db.pragma("journal_mode = WAL");
|
|
@@ -18626,9 +19088,9 @@ function isPythonDataStale(dataDb2, pythonRoot) {
|
|
|
18626
19088
|
const lastBuildTime = new Date(lastBuild.value).getTime();
|
|
18627
19089
|
function checkDir(dir) {
|
|
18628
19090
|
try {
|
|
18629
|
-
const entries =
|
|
19091
|
+
const entries = readdirSync15(dir, { withFileTypes: true });
|
|
18630
19092
|
for (const entry of entries) {
|
|
18631
|
-
const fullPath =
|
|
19093
|
+
const fullPath = join12(dir, entry.name);
|
|
18632
19094
|
if (entry.isDirectory()) {
|
|
18633
19095
|
if (["__pycache__", ".venv", "venv", "node_modules", ".mypy_cache", ".pytest_cache"].includes(entry.name)) continue;
|
|
18634
19096
|
if (checkDir(fullPath)) return true;
|
|
@@ -18729,8 +19191,8 @@ var init_rules = __esm({
|
|
|
18729
19191
|
});
|
|
18730
19192
|
|
|
18731
19193
|
// src/import-resolver.ts
|
|
18732
|
-
import { readFileSync as
|
|
18733
|
-
import { resolve as resolve20, dirname as
|
|
19194
|
+
import { readFileSync as readFileSync23, existsSync as existsSync24, statSync as statSync12 } from "fs";
|
|
19195
|
+
import { resolve as resolve20, dirname as dirname13, join as join13 } from "path";
|
|
18734
19196
|
function parseImports(source) {
|
|
18735
19197
|
const imports = [];
|
|
18736
19198
|
const lines = source.split("\n");
|
|
@@ -18788,7 +19250,7 @@ function resolveImportPath(specifier, fromFile) {
|
|
|
18788
19250
|
const paths = getResolvedPaths();
|
|
18789
19251
|
basePath = resolve20(paths.pathAlias["@"] ?? paths.srcDir, specifier.slice(2));
|
|
18790
19252
|
} else {
|
|
18791
|
-
basePath = resolve20(
|
|
19253
|
+
basePath = resolve20(dirname13(fromFile), specifier);
|
|
18792
19254
|
}
|
|
18793
19255
|
if (existsSync24(basePath) && !isDirectory(basePath)) {
|
|
18794
19256
|
return toRelative(basePath);
|
|
@@ -18801,7 +19263,7 @@ function resolveImportPath(specifier, fromFile) {
|
|
|
18801
19263
|
}
|
|
18802
19264
|
}
|
|
18803
19265
|
for (const indexFile of resolvedPaths.indexFiles) {
|
|
18804
|
-
const indexPath =
|
|
19266
|
+
const indexPath = join13(basePath, indexFile);
|
|
18805
19267
|
if (existsSync24(indexPath)) {
|
|
18806
19268
|
return toRelative(indexPath);
|
|
18807
19269
|
}
|
|
@@ -18842,7 +19304,7 @@ function buildImportIndex(dataDb2, codegraphDb2) {
|
|
|
18842
19304
|
if (!existsSync24(absPath)) continue;
|
|
18843
19305
|
let source;
|
|
18844
19306
|
try {
|
|
18845
|
-
source =
|
|
19307
|
+
source = readFileSync23(absPath, "utf-8");
|
|
18846
19308
|
} catch {
|
|
18847
19309
|
continue;
|
|
18848
19310
|
}
|
|
@@ -18878,15 +19340,15 @@ var init_import_resolver = __esm({
|
|
|
18878
19340
|
});
|
|
18879
19341
|
|
|
18880
19342
|
// src/trpc-index.ts
|
|
18881
|
-
import { readFileSync as
|
|
18882
|
-
import { resolve as resolve21, join as
|
|
19343
|
+
import { readFileSync as readFileSync24, existsSync as existsSync25, readdirSync as readdirSync16 } from "fs";
|
|
19344
|
+
import { resolve as resolve21, join as join14 } from "path";
|
|
18883
19345
|
function parseRootRouter() {
|
|
18884
19346
|
const paths = getResolvedPaths();
|
|
18885
19347
|
const rootPath = paths.rootRouterPath;
|
|
18886
19348
|
if (!existsSync25(rootPath)) {
|
|
18887
19349
|
throw new Error(`Root router not found at ${rootPath}`);
|
|
18888
19350
|
}
|
|
18889
|
-
const source =
|
|
19351
|
+
const source = readFileSync24(rootPath, "utf-8");
|
|
18890
19352
|
const mappings = [];
|
|
18891
19353
|
const importMap = /* @__PURE__ */ new Map();
|
|
18892
19354
|
const importRegex = /import\s+\{[^}]*?(\w+Router)[^}]*\}\s+from\s+['"]\.\/routers\/([^'"]+)['"]/g;
|
|
@@ -18902,7 +19364,7 @@ function parseRootRouter() {
|
|
|
18902
19364
|
filePath = routersRelPath + "/" + filePath + ext;
|
|
18903
19365
|
break;
|
|
18904
19366
|
}
|
|
18905
|
-
const indexCandidate =
|
|
19367
|
+
const indexCandidate = join14(fullPath, "index.ts");
|
|
18906
19368
|
if (existsSync25(indexCandidate)) {
|
|
18907
19369
|
filePath = routersRelPath + "/" + filePath + "/index.ts";
|
|
18908
19370
|
break;
|
|
@@ -18924,7 +19386,7 @@ function parseRootRouter() {
|
|
|
18924
19386
|
function extractProcedures(routerFilePath) {
|
|
18925
19387
|
const absPath = resolve21(getProjectRoot(), routerFilePath);
|
|
18926
19388
|
if (!existsSync25(absPath)) return [];
|
|
18927
|
-
const source =
|
|
19389
|
+
const source = readFileSync24(absPath, "utf-8");
|
|
18928
19390
|
const procedures = [];
|
|
18929
19391
|
const seen = /* @__PURE__ */ new Set();
|
|
18930
19392
|
const procRegex = /(\w+)\s*:\s*(protected|public)Procedure/g;
|
|
@@ -18959,15 +19421,15 @@ function findUICallSites(routerKey, procedureName) {
|
|
|
18959
19421
|
return callSites;
|
|
18960
19422
|
}
|
|
18961
19423
|
function searchDirectory(dir, pattern, results) {
|
|
18962
|
-
const entries =
|
|
19424
|
+
const entries = readdirSync16(dir, { withFileTypes: true });
|
|
18963
19425
|
for (const entry of entries) {
|
|
18964
|
-
const fullPath =
|
|
19426
|
+
const fullPath = join14(dir, entry.name);
|
|
18965
19427
|
if (entry.isDirectory()) {
|
|
18966
19428
|
if (entry.name === "node_modules" || entry.name === ".next") continue;
|
|
18967
19429
|
searchDirectory(fullPath, pattern, results);
|
|
18968
19430
|
} else if (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx")) {
|
|
18969
19431
|
try {
|
|
18970
|
-
const source =
|
|
19432
|
+
const source = readFileSync24(fullPath, "utf-8");
|
|
18971
19433
|
const lines = source.split("\n");
|
|
18972
19434
|
for (let i = 0; i < lines.length; i++) {
|
|
18973
19435
|
if (lines[i].includes(pattern)) {
|
|
@@ -19030,7 +19492,7 @@ var init_trpc_index = __esm({
|
|
|
19030
19492
|
});
|
|
19031
19493
|
|
|
19032
19494
|
// src/page-deps.ts
|
|
19033
|
-
import { readFileSync as
|
|
19495
|
+
import { readFileSync as readFileSync25, existsSync as existsSync26 } from "fs";
|
|
19034
19496
|
import { resolve as resolve22 } from "path";
|
|
19035
19497
|
function deriveRoute(pageFile) {
|
|
19036
19498
|
let route = pageFile.replace(/^src\/app/, "").replace(/\/page\.tsx?$/, "").replace(/\/page\.jsx?$/, "");
|
|
@@ -19072,7 +19534,7 @@ function findRouterCalls(files) {
|
|
|
19072
19534
|
const absPath = ensureWithinRoot(resolve22(projectRoot, file), projectRoot);
|
|
19073
19535
|
if (!existsSync26(absPath)) continue;
|
|
19074
19536
|
try {
|
|
19075
|
-
const source =
|
|
19537
|
+
const source = readFileSync25(absPath, "utf-8");
|
|
19076
19538
|
const apiCallRegex = /api\.(\w+)\.\w+/g;
|
|
19077
19539
|
let match;
|
|
19078
19540
|
while ((match = apiCallRegex.exec(source)) !== null) {
|
|
@@ -19093,7 +19555,7 @@ function findTablesFromRouters(routerNames, dataDb2) {
|
|
|
19093
19555
|
const absPath = ensureWithinRoot(resolve22(getProjectRoot(), proc.router_file), getProjectRoot());
|
|
19094
19556
|
if (!existsSync26(absPath)) continue;
|
|
19095
19557
|
try {
|
|
19096
|
-
const source =
|
|
19558
|
+
const source = readFileSync25(absPath, "utf-8");
|
|
19097
19559
|
const dbPattern = getConfig().dbAccessPattern ?? "ctx.db.{table}";
|
|
19098
19560
|
const regexStr = dbPattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace("\\{table\\}", "(\\w+)");
|
|
19099
19561
|
const tableRegex = new RegExp(regexStr + "\\.", "g");
|
|
@@ -19362,14 +19824,14 @@ var init_domains = __esm({
|
|
|
19362
19824
|
});
|
|
19363
19825
|
|
|
19364
19826
|
// src/schema-mapper.ts
|
|
19365
|
-
import { readFileSync as
|
|
19366
|
-
import { join as
|
|
19827
|
+
import { readFileSync as readFileSync26, existsSync as existsSync27, readdirSync as readdirSync17 } from "fs";
|
|
19828
|
+
import { join as join15 } from "path";
|
|
19367
19829
|
function parsePrismaSchema() {
|
|
19368
19830
|
const schemaPath = getResolvedPaths().prismaSchemaPath;
|
|
19369
19831
|
if (!existsSync27(schemaPath)) {
|
|
19370
19832
|
throw new Error(`Prisma schema not found at ${schemaPath}`);
|
|
19371
19833
|
}
|
|
19372
|
-
const source =
|
|
19834
|
+
const source = readFileSync26(schemaPath, "utf-8");
|
|
19373
19835
|
const models = [];
|
|
19374
19836
|
const sourceLines = source.split("\n");
|
|
19375
19837
|
let i = 0;
|
|
@@ -19432,9 +19894,9 @@ function findColumnUsageInRouters(tableName) {
|
|
|
19432
19894
|
return usage;
|
|
19433
19895
|
}
|
|
19434
19896
|
function scanDirectory(dir, tableName, usage) {
|
|
19435
|
-
const entries =
|
|
19897
|
+
const entries = readdirSync17(dir, { withFileTypes: true });
|
|
19436
19898
|
for (const entry of entries) {
|
|
19437
|
-
const fullPath =
|
|
19899
|
+
const fullPath = join15(dir, entry.name);
|
|
19438
19900
|
if (entry.isDirectory()) {
|
|
19439
19901
|
scanDirectory(fullPath, tableName, usage);
|
|
19440
19902
|
} else if (entry.name.endsWith(".ts")) {
|
|
@@ -19444,7 +19906,7 @@ function scanDirectory(dir, tableName, usage) {
|
|
|
19444
19906
|
}
|
|
19445
19907
|
function scanFile(absPath, tableName, usage) {
|
|
19446
19908
|
try {
|
|
19447
|
-
const source =
|
|
19909
|
+
const source = readFileSync26(absPath, "utf-8");
|
|
19448
19910
|
if (!source.includes(tableName)) return;
|
|
19449
19911
|
const relPath = absPath.slice(getProjectRoot().length + 1);
|
|
19450
19912
|
const lines = source.split("\n");
|
|
@@ -19490,14 +19952,14 @@ function detectMismatches(models) {
|
|
|
19490
19952
|
function findFilesUsingColumn(dir, column, tableName) {
|
|
19491
19953
|
const result = [];
|
|
19492
19954
|
if (!existsSync27(dir)) return result;
|
|
19493
|
-
const entries =
|
|
19955
|
+
const entries = readdirSync17(dir, { withFileTypes: true });
|
|
19494
19956
|
for (const entry of entries) {
|
|
19495
|
-
const fullPath =
|
|
19957
|
+
const fullPath = join15(dir, entry.name);
|
|
19496
19958
|
if (entry.isDirectory()) {
|
|
19497
19959
|
result.push(...findFilesUsingColumn(fullPath, column, tableName));
|
|
19498
19960
|
} else if (entry.name.endsWith(".ts")) {
|
|
19499
19961
|
try {
|
|
19500
|
-
const source =
|
|
19962
|
+
const source = readFileSync26(fullPath, "utf-8");
|
|
19501
19963
|
if (source.includes(tableName) && source.includes(column)) {
|
|
19502
19964
|
result.push(fullPath.slice(getProjectRoot().length + 1));
|
|
19503
19965
|
}
|
|
@@ -19642,32 +20104,32 @@ var init_import_parser = __esm({
|
|
|
19642
20104
|
});
|
|
19643
20105
|
|
|
19644
20106
|
// src/python/import-resolver.ts
|
|
19645
|
-
import { readFileSync as
|
|
19646
|
-
import { resolve as resolve24, join as
|
|
20107
|
+
import { readFileSync as readFileSync27, existsSync as existsSync28, readdirSync as readdirSync18 } from "fs";
|
|
20108
|
+
import { resolve as resolve24, join as join16, relative as relative6, dirname as dirname14 } from "path";
|
|
19647
20109
|
function resolvePythonModulePath(module, fromFile, pythonRoot, level) {
|
|
19648
20110
|
const projectRoot = getProjectRoot();
|
|
19649
20111
|
if (level > 0) {
|
|
19650
|
-
let baseDir =
|
|
20112
|
+
let baseDir = dirname14(resolve24(projectRoot, fromFile));
|
|
19651
20113
|
for (let i = 1; i < level; i++) {
|
|
19652
|
-
baseDir =
|
|
20114
|
+
baseDir = dirname14(baseDir);
|
|
19653
20115
|
}
|
|
19654
20116
|
const modulePart = module.replace(/^\.+/, "");
|
|
19655
20117
|
if (modulePart) {
|
|
19656
20118
|
const parts2 = modulePart.split(".");
|
|
19657
|
-
return tryResolvePythonPath(
|
|
20119
|
+
return tryResolvePythonPath(join16(baseDir, ...parts2), projectRoot);
|
|
19658
20120
|
}
|
|
19659
20121
|
return tryResolvePythonPath(baseDir, projectRoot);
|
|
19660
20122
|
}
|
|
19661
20123
|
const parts = module.split(".");
|
|
19662
|
-
const candidate =
|
|
20124
|
+
const candidate = join16(resolve24(projectRoot, pythonRoot), ...parts);
|
|
19663
20125
|
return tryResolvePythonPath(candidate, projectRoot);
|
|
19664
20126
|
}
|
|
19665
20127
|
function tryResolvePythonPath(basePath, projectRoot) {
|
|
19666
20128
|
if (existsSync28(basePath + ".py")) {
|
|
19667
20129
|
return relative6(projectRoot, basePath + ".py");
|
|
19668
20130
|
}
|
|
19669
|
-
if (existsSync28(
|
|
19670
|
-
return relative6(projectRoot,
|
|
20131
|
+
if (existsSync28(join16(basePath, "__init__.py"))) {
|
|
20132
|
+
return relative6(projectRoot, join16(basePath, "__init__.py"));
|
|
19671
20133
|
}
|
|
19672
20134
|
if (basePath.endsWith(".py") && existsSync28(basePath)) {
|
|
19673
20135
|
return relative6(projectRoot, basePath);
|
|
@@ -19677,13 +20139,13 @@ function tryResolvePythonPath(basePath, projectRoot) {
|
|
|
19677
20139
|
function walkPythonFiles(dir, excludeDirs) {
|
|
19678
20140
|
const files = [];
|
|
19679
20141
|
try {
|
|
19680
|
-
const entries =
|
|
20142
|
+
const entries = readdirSync18(dir, { withFileTypes: true });
|
|
19681
20143
|
for (const entry of entries) {
|
|
19682
20144
|
if (entry.isDirectory()) {
|
|
19683
20145
|
if (excludeDirs.includes(entry.name)) continue;
|
|
19684
|
-
files.push(...walkPythonFiles(
|
|
20146
|
+
files.push(...walkPythonFiles(join16(dir, entry.name), excludeDirs));
|
|
19685
20147
|
} else if (entry.name.endsWith(".py")) {
|
|
19686
|
-
files.push(
|
|
20148
|
+
files.push(join16(dir, entry.name));
|
|
19687
20149
|
}
|
|
19688
20150
|
}
|
|
19689
20151
|
} catch {
|
|
@@ -19709,7 +20171,7 @@ function buildPythonImportIndex(dataDb2, pythonRoot, excludeDirs = ["__pycache__
|
|
|
19709
20171
|
const relFile = relative6(projectRoot, absFile);
|
|
19710
20172
|
let source;
|
|
19711
20173
|
try {
|
|
19712
|
-
source =
|
|
20174
|
+
source = readFileSync27(absFile, "utf-8");
|
|
19713
20175
|
} catch {
|
|
19714
20176
|
continue;
|
|
19715
20177
|
}
|
|
@@ -19975,18 +20437,18 @@ var init_route_parser = __esm({
|
|
|
19975
20437
|
});
|
|
19976
20438
|
|
|
19977
20439
|
// src/python/route-indexer.ts
|
|
19978
|
-
import { readFileSync as
|
|
19979
|
-
import { join as
|
|
20440
|
+
import { readFileSync as readFileSync28, readdirSync as readdirSync19 } from "fs";
|
|
20441
|
+
import { join as join17, relative as relative7 } from "path";
|
|
19980
20442
|
function walkPyFiles(dir, excludeDirs) {
|
|
19981
20443
|
const files = [];
|
|
19982
20444
|
try {
|
|
19983
|
-
const entries =
|
|
20445
|
+
const entries = readdirSync19(dir, { withFileTypes: true });
|
|
19984
20446
|
for (const entry of entries) {
|
|
19985
20447
|
if (entry.isDirectory()) {
|
|
19986
20448
|
if (excludeDirs.includes(entry.name)) continue;
|
|
19987
|
-
files.push(...walkPyFiles(
|
|
20449
|
+
files.push(...walkPyFiles(join17(dir, entry.name), excludeDirs));
|
|
19988
20450
|
} else if (entry.name.endsWith(".py")) {
|
|
19989
|
-
files.push(
|
|
20451
|
+
files.push(join17(dir, entry.name));
|
|
19990
20452
|
}
|
|
19991
20453
|
}
|
|
19992
20454
|
} catch {
|
|
@@ -19995,7 +20457,7 @@ function walkPyFiles(dir, excludeDirs) {
|
|
|
19995
20457
|
}
|
|
19996
20458
|
function buildPythonRouteIndex(dataDb2, pythonRoot, excludeDirs = ["__pycache__", ".venv", "venv", ".mypy_cache", ".pytest_cache"]) {
|
|
19997
20459
|
const projectRoot = getProjectRoot();
|
|
19998
|
-
const absRoot =
|
|
20460
|
+
const absRoot = join17(projectRoot, pythonRoot);
|
|
19999
20461
|
dataDb2.exec("DELETE FROM massu_py_routes");
|
|
20000
20462
|
dataDb2.exec("DELETE FROM massu_py_route_callers");
|
|
20001
20463
|
const insertStmt = dataDb2.prepare(
|
|
@@ -20008,7 +20470,7 @@ function buildPythonRouteIndex(dataDb2, pythonRoot, excludeDirs = ["__pycache__"
|
|
|
20008
20470
|
const relFile = relative7(projectRoot, absFile);
|
|
20009
20471
|
let source;
|
|
20010
20472
|
try {
|
|
20011
|
-
source =
|
|
20473
|
+
source = readFileSync28(absFile, "utf-8");
|
|
20012
20474
|
} catch {
|
|
20013
20475
|
continue;
|
|
20014
20476
|
}
|
|
@@ -20219,18 +20681,18 @@ var init_model_parser = __esm({
|
|
|
20219
20681
|
});
|
|
20220
20682
|
|
|
20221
20683
|
// src/python/model-indexer.ts
|
|
20222
|
-
import { readFileSync as
|
|
20223
|
-
import { join as
|
|
20684
|
+
import { readFileSync as readFileSync29, readdirSync as readdirSync20 } from "fs";
|
|
20685
|
+
import { join as join18, relative as relative8 } from "path";
|
|
20224
20686
|
function walkPyFiles2(dir, excludeDirs) {
|
|
20225
20687
|
const files = [];
|
|
20226
20688
|
try {
|
|
20227
|
-
const entries =
|
|
20689
|
+
const entries = readdirSync20(dir, { withFileTypes: true });
|
|
20228
20690
|
for (const entry of entries) {
|
|
20229
20691
|
if (entry.isDirectory()) {
|
|
20230
20692
|
if (excludeDirs.includes(entry.name)) continue;
|
|
20231
|
-
files.push(...walkPyFiles2(
|
|
20693
|
+
files.push(...walkPyFiles2(join18(dir, entry.name), excludeDirs));
|
|
20232
20694
|
} else if (entry.name.endsWith(".py")) {
|
|
20233
|
-
files.push(
|
|
20695
|
+
files.push(join18(dir, entry.name));
|
|
20234
20696
|
}
|
|
20235
20697
|
}
|
|
20236
20698
|
} catch {
|
|
@@ -20239,7 +20701,7 @@ function walkPyFiles2(dir, excludeDirs) {
|
|
|
20239
20701
|
}
|
|
20240
20702
|
function buildPythonModelIndex(dataDb2, pythonRoot, excludeDirs = ["__pycache__", ".venv", "venv", ".mypy_cache", ".pytest_cache"]) {
|
|
20241
20703
|
const projectRoot = getProjectRoot();
|
|
20242
|
-
const absRoot =
|
|
20704
|
+
const absRoot = join18(projectRoot, pythonRoot);
|
|
20243
20705
|
dataDb2.exec("DELETE FROM massu_py_models");
|
|
20244
20706
|
dataDb2.exec("DELETE FROM massu_py_fk_edges");
|
|
20245
20707
|
const insertModel = dataDb2.prepare(
|
|
@@ -20255,7 +20717,7 @@ function buildPythonModelIndex(dataDb2, pythonRoot, excludeDirs = ["__pycache__"
|
|
|
20255
20717
|
const relFile = relative8(projectRoot, absFile);
|
|
20256
20718
|
let source;
|
|
20257
20719
|
try {
|
|
20258
|
-
source =
|
|
20720
|
+
source = readFileSync29(absFile, "utf-8");
|
|
20259
20721
|
} catch {
|
|
20260
20722
|
continue;
|
|
20261
20723
|
}
|
|
@@ -20515,19 +20977,19 @@ var init_migration_parser = __esm({
|
|
|
20515
20977
|
});
|
|
20516
20978
|
|
|
20517
20979
|
// src/python/migration-indexer.ts
|
|
20518
|
-
import { readFileSync as
|
|
20519
|
-
import { join as
|
|
20980
|
+
import { readFileSync as readFileSync30, readdirSync as readdirSync21 } from "fs";
|
|
20981
|
+
import { join as join19, relative as relative9 } from "path";
|
|
20520
20982
|
function buildPythonMigrationIndex(dataDb2, alembicDir) {
|
|
20521
20983
|
const projectRoot = getProjectRoot();
|
|
20522
|
-
const absDir =
|
|
20984
|
+
const absDir = join19(projectRoot, alembicDir);
|
|
20523
20985
|
dataDb2.exec("DELETE FROM massu_py_migrations");
|
|
20524
|
-
const versionsDir =
|
|
20986
|
+
const versionsDir = join19(absDir, "versions");
|
|
20525
20987
|
let files = [];
|
|
20526
20988
|
try {
|
|
20527
|
-
files =
|
|
20989
|
+
files = readdirSync21(versionsDir).filter((f2) => f2.endsWith(".py")).map((f2) => join19(versionsDir, f2));
|
|
20528
20990
|
} catch {
|
|
20529
20991
|
try {
|
|
20530
|
-
files =
|
|
20992
|
+
files = readdirSync21(absDir).filter((f2) => f2.endsWith(".py") && f2 !== "env.py").map((f2) => join19(absDir, f2));
|
|
20531
20993
|
} catch {
|
|
20532
20994
|
}
|
|
20533
20995
|
}
|
|
@@ -20541,7 +21003,7 @@ function buildPythonMigrationIndex(dataDb2, alembicDir) {
|
|
|
20541
21003
|
for (const absFile of files) {
|
|
20542
21004
|
let source;
|
|
20543
21005
|
try {
|
|
20544
|
-
source =
|
|
21006
|
+
source = readFileSync30(absFile, "utf-8");
|
|
20545
21007
|
} catch {
|
|
20546
21008
|
continue;
|
|
20547
21009
|
}
|
|
@@ -20575,12 +21037,12 @@ var init_migration_indexer = __esm({
|
|
|
20575
21037
|
});
|
|
20576
21038
|
|
|
20577
21039
|
// src/python/coupling-detector.ts
|
|
20578
|
-
import { readFileSync as
|
|
20579
|
-
import { join as
|
|
21040
|
+
import { readFileSync as readFileSync31, readdirSync as readdirSync22 } from "fs";
|
|
21041
|
+
import { join as join20, relative as relative10 } from "path";
|
|
20580
21042
|
function buildPythonCouplingIndex(dataDb2) {
|
|
20581
21043
|
const projectRoot = getProjectRoot();
|
|
20582
21044
|
const config = getConfig();
|
|
20583
|
-
const srcDir =
|
|
21045
|
+
const srcDir = join20(projectRoot, config.paths.source);
|
|
20584
21046
|
const routes = dataDb2.prepare("SELECT id, method, path FROM massu_py_routes").all();
|
|
20585
21047
|
if (routes.length === 0) return 0;
|
|
20586
21048
|
dataDb2.exec("DELETE FROM massu_py_route_callers");
|
|
@@ -20612,7 +21074,7 @@ function buildPythonCouplingIndex(dataDb2) {
|
|
|
20612
21074
|
const relFile = relative10(projectRoot, absFile);
|
|
20613
21075
|
let source;
|
|
20614
21076
|
try {
|
|
20615
|
-
source =
|
|
21077
|
+
source = readFileSync31(absFile, "utf-8");
|
|
20616
21078
|
} catch {
|
|
20617
21079
|
continue;
|
|
20618
21080
|
}
|
|
@@ -20640,13 +21102,13 @@ function walkFrontendFiles(dir) {
|
|
|
20640
21102
|
const files = [];
|
|
20641
21103
|
const exclude = ["node_modules", ".next", "dist", ".git", "__pycache__", ".venv", "venv"];
|
|
20642
21104
|
try {
|
|
20643
|
-
const entries =
|
|
21105
|
+
const entries = readdirSync22(dir, { withFileTypes: true });
|
|
20644
21106
|
for (const entry of entries) {
|
|
20645
21107
|
if (entry.isDirectory()) {
|
|
20646
21108
|
if (exclude.includes(entry.name)) continue;
|
|
20647
|
-
files.push(...walkFrontendFiles(
|
|
21109
|
+
files.push(...walkFrontendFiles(join20(dir, entry.name)));
|
|
20648
21110
|
} else if (/\.(tsx?|jsx?)$/.test(entry.name)) {
|
|
20649
|
-
files.push(
|
|
21111
|
+
files.push(join20(dir, entry.name));
|
|
20650
21112
|
}
|
|
20651
21113
|
}
|
|
20652
21114
|
} catch {
|
|
@@ -21017,7 +21479,7 @@ var init_memory_tools = __esm({
|
|
|
21017
21479
|
});
|
|
21018
21480
|
|
|
21019
21481
|
// src/docs-tools.ts
|
|
21020
|
-
import { readFileSync as
|
|
21482
|
+
import { readFileSync as readFileSync32, existsSync as existsSync29 } from "fs";
|
|
21021
21483
|
import { resolve as resolve25, basename as basename6 } from "path";
|
|
21022
21484
|
function p3(baseName) {
|
|
21023
21485
|
return `${getConfig().toolPrefix}_${baseName}`;
|
|
@@ -21076,7 +21538,7 @@ function loadDocsMap() {
|
|
|
21076
21538
|
if (!existsSync29(mapPath)) {
|
|
21077
21539
|
throw new Error(`docs-map.json not found at ${mapPath}`);
|
|
21078
21540
|
}
|
|
21079
|
-
return JSON.parse(
|
|
21541
|
+
return JSON.parse(readFileSync32(mapPath, "utf-8"));
|
|
21080
21542
|
}
|
|
21081
21543
|
function matchesPattern(filePath, pattern) {
|
|
21082
21544
|
const regexStr = pattern.replace(/\./g, "\\.").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/\{\{GLOBSTAR\}\}/g, ".*");
|
|
@@ -21150,9 +21612,9 @@ function extractProcedureNames(routerPath) {
|
|
|
21150
21612
|
if (!existsSync29(absPath)) {
|
|
21151
21613
|
const altPath = ensureWithinRoot(resolve25(getResolvedPaths().srcDir, "../server/api/routers", basename6(routerPath)), root);
|
|
21152
21614
|
if (!existsSync29(altPath)) return [];
|
|
21153
|
-
return extractProcedureNamesFromContent(
|
|
21615
|
+
return extractProcedureNamesFromContent(readFileSync32(altPath, "utf-8"));
|
|
21154
21616
|
}
|
|
21155
|
-
return extractProcedureNamesFromContent(
|
|
21617
|
+
return extractProcedureNamesFromContent(readFileSync32(absPath, "utf-8"));
|
|
21156
21618
|
}
|
|
21157
21619
|
function extractProcedureNamesFromContent(content) {
|
|
21158
21620
|
const procRegex = /\.(?:query|mutation)\s*\(/g;
|
|
@@ -21205,7 +21667,7 @@ function handleDocsAudit(args2) {
|
|
|
21205
21667
|
});
|
|
21206
21668
|
continue;
|
|
21207
21669
|
}
|
|
21208
|
-
const content =
|
|
21670
|
+
const content = readFileSync32(helpPagePath, "utf-8");
|
|
21209
21671
|
const sections = extractSections(content);
|
|
21210
21672
|
const frontmatter = extractFrontmatter(content);
|
|
21211
21673
|
const staleReasons = [];
|
|
@@ -21247,7 +21709,7 @@ function handleDocsAudit(args2) {
|
|
|
21247
21709
|
if (parentId === mappingId) {
|
|
21248
21710
|
const guidePath = ensureWithinRoot(resolve25(getResolvedPaths().helpSitePath, `pages/user-guides/${guideName}/index.mdx`), getProjectRoot());
|
|
21249
21711
|
if (existsSync29(guidePath)) {
|
|
21250
|
-
const guideContent =
|
|
21712
|
+
const guideContent = readFileSync32(guidePath, "utf-8");
|
|
21251
21713
|
const guideFrontmatter = extractFrontmatter(guideContent);
|
|
21252
21714
|
if (!guideFrontmatter?.lastVerified || status === "STALE") {
|
|
21253
21715
|
results.push({
|
|
@@ -21287,7 +21749,7 @@ function handleDocsCoverage(args2) {
|
|
|
21287
21749
|
let lastVerified = null;
|
|
21288
21750
|
let status = null;
|
|
21289
21751
|
if (exists) {
|
|
21290
|
-
const content =
|
|
21752
|
+
const content = readFileSync32(helpPagePath, "utf-8");
|
|
21291
21753
|
lineCount = content.split("\n").length;
|
|
21292
21754
|
hasContent = lineCount > 10;
|
|
21293
21755
|
const frontmatter = extractFrontmatter(content);
|
|
@@ -22405,8 +22867,8 @@ var init_sentinel_tools = __esm({
|
|
|
22405
22867
|
});
|
|
22406
22868
|
|
|
22407
22869
|
// src/sentinel-scanner.ts
|
|
22408
|
-
import { readFileSync as
|
|
22409
|
-
import { resolve as resolve27, join as
|
|
22870
|
+
import { readFileSync as readFileSync33, existsSync as existsSync31, readdirSync as readdirSync23, statSync as statSync13 } from "fs";
|
|
22871
|
+
import { resolve as resolve27, join as join21, basename as basename7, dirname as dirname15, relative as relative11 } from "path";
|
|
22410
22872
|
function inferDomain(filePath) {
|
|
22411
22873
|
const domains = getConfig().domains;
|
|
22412
22874
|
const path = filePath.toLowerCase();
|
|
@@ -22538,7 +23000,7 @@ function scanComponentExports(dataDb2) {
|
|
|
22538
23000
|
const basePath = resolve27(projectRoot, componentsBase);
|
|
22539
23001
|
if (existsSync31(basePath)) {
|
|
22540
23002
|
try {
|
|
22541
|
-
const entries =
|
|
23003
|
+
const entries = readdirSync23(basePath, { withFileTypes: true });
|
|
22542
23004
|
for (const entry of entries) {
|
|
22543
23005
|
if (entry.isDirectory()) {
|
|
22544
23006
|
componentDirs.push(componentsBase + "/" + entry.name);
|
|
@@ -22553,7 +23015,7 @@ function scanComponentExports(dataDb2) {
|
|
|
22553
23015
|
const files = walkDir2(absDir).filter((f2) => f2.endsWith(".tsx") || f2.endsWith(".ts"));
|
|
22554
23016
|
for (const file of files) {
|
|
22555
23017
|
const relPath = relative11(projectRoot, file);
|
|
22556
|
-
const source =
|
|
23018
|
+
const source = readFileSync33(file, "utf-8");
|
|
22557
23019
|
const annotations = parseFeatureAnnotations(source);
|
|
22558
23020
|
if (annotations.length > 0) {
|
|
22559
23021
|
for (const ann of annotations) {
|
|
@@ -22579,7 +23041,7 @@ function scanComponentExports(dataDb2) {
|
|
|
22579
23041
|
if (hasHandlers && exportMatch) {
|
|
22580
23042
|
const componentName = exportMatch[1];
|
|
22581
23043
|
const domain = inferDomain(relPath);
|
|
22582
|
-
const subdomain = basename7(
|
|
23044
|
+
const subdomain = basename7(dirname15(relPath));
|
|
22583
23045
|
const featureKey = `component.${subdomain}.${componentName.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "")}`;
|
|
22584
23046
|
if (!annotations.some((a2) => a2.featureKey === featureKey)) {
|
|
22585
23047
|
features.push({
|
|
@@ -22602,9 +23064,9 @@ function scanComponentExports(dataDb2) {
|
|
|
22602
23064
|
function walkDir2(dir) {
|
|
22603
23065
|
const results = [];
|
|
22604
23066
|
try {
|
|
22605
|
-
const entries =
|
|
23067
|
+
const entries = readdirSync23(dir);
|
|
22606
23068
|
for (const entry of entries) {
|
|
22607
|
-
const fullPath =
|
|
23069
|
+
const fullPath = join21(dir, entry);
|
|
22608
23070
|
try {
|
|
22609
23071
|
const stat = statSync13(fullPath);
|
|
22610
23072
|
if (stat.isDirectory()) {
|
|
@@ -23592,7 +24054,7 @@ var init_audit_trail = __esm({
|
|
|
23592
24054
|
});
|
|
23593
24055
|
|
|
23594
24056
|
// src/validation-engine.ts
|
|
23595
|
-
import { existsSync as existsSync32, readFileSync as
|
|
24057
|
+
import { existsSync as existsSync32, readFileSync as readFileSync34 } from "fs";
|
|
23596
24058
|
function p10(baseName) {
|
|
23597
24059
|
return `${getConfig().toolPrefix}_${baseName}`;
|
|
23598
24060
|
}
|
|
@@ -23632,7 +24094,7 @@ function validateFile(filePath, projectRoot) {
|
|
|
23632
24094
|
});
|
|
23633
24095
|
return checks;
|
|
23634
24096
|
}
|
|
23635
|
-
const source =
|
|
24097
|
+
const source = readFileSync34(absPath, "utf-8");
|
|
23636
24098
|
const lines = source.split("\n");
|
|
23637
24099
|
if (activeChecks.rule_compliance !== false) {
|
|
23638
24100
|
for (const ruleSet of config.rules) {
|
|
@@ -24077,7 +24539,7 @@ var init_adr_generator = __esm({
|
|
|
24077
24539
|
});
|
|
24078
24540
|
|
|
24079
24541
|
// src/security-scorer.ts
|
|
24080
|
-
import { existsSync as existsSync33, readFileSync as
|
|
24542
|
+
import { existsSync as existsSync33, readFileSync as readFileSync35 } from "fs";
|
|
24081
24543
|
function p12(baseName) {
|
|
24082
24544
|
return `${getConfig().toolPrefix}_${baseName}`;
|
|
24083
24545
|
}
|
|
@@ -24106,7 +24568,7 @@ function scoreFileSecurity(filePath, projectRoot) {
|
|
|
24106
24568
|
}
|
|
24107
24569
|
let source;
|
|
24108
24570
|
try {
|
|
24109
|
-
source =
|
|
24571
|
+
source = readFileSync35(absPath, "utf-8");
|
|
24110
24572
|
} catch {
|
|
24111
24573
|
return { riskScore: 0, findings: [] };
|
|
24112
24574
|
}
|
|
@@ -24395,7 +24857,7 @@ var init_security_scorer = __esm({
|
|
|
24395
24857
|
});
|
|
24396
24858
|
|
|
24397
24859
|
// src/dependency-scorer.ts
|
|
24398
|
-
import { existsSync as existsSync34, readFileSync as
|
|
24860
|
+
import { existsSync as existsSync34, readFileSync as readFileSync36 } from "fs";
|
|
24399
24861
|
import { resolve as resolve28 } from "path";
|
|
24400
24862
|
function p13(baseName) {
|
|
24401
24863
|
return `${getConfig().toolPrefix}_${baseName}`;
|
|
@@ -24431,7 +24893,7 @@ function getInstalledPackages(projectRoot) {
|
|
|
24431
24893
|
const pkgPath = resolve28(projectRoot, "package.json");
|
|
24432
24894
|
if (!existsSync34(pkgPath)) return /* @__PURE__ */ new Map();
|
|
24433
24895
|
try {
|
|
24434
|
-
const pkg = JSON.parse(
|
|
24896
|
+
const pkg = JSON.parse(readFileSync36(pkgPath, "utf-8"));
|
|
24435
24897
|
const packages = /* @__PURE__ */ new Map();
|
|
24436
24898
|
for (const [name, version] of Object.entries(pkg.dependencies ?? {})) {
|
|
24437
24899
|
packages.set(name, version);
|
|
@@ -25033,8 +25495,8 @@ var init_regression_detector = __esm({
|
|
|
25033
25495
|
});
|
|
25034
25496
|
|
|
25035
25497
|
// src/knowledge-indexer.ts
|
|
25036
|
-
import { createHash as
|
|
25037
|
-
import { readFileSync as
|
|
25498
|
+
import { createHash as createHash9 } from "crypto";
|
|
25499
|
+
import { readFileSync as readFileSync37, readdirSync as readdirSync24, statSync as statSync14, existsSync as existsSync35 } from "fs";
|
|
25038
25500
|
import { resolve as resolve29, relative as relative12, basename as basename8, extname as extname2 } from "path";
|
|
25039
25501
|
function getKnowledgePaths() {
|
|
25040
25502
|
const resolved = getResolvedPaths();
|
|
@@ -25061,7 +25523,7 @@ function discoverMarkdownFiles(baseDir) {
|
|
|
25061
25523
|
const files = [];
|
|
25062
25524
|
function walk(dir) {
|
|
25063
25525
|
try {
|
|
25064
|
-
const entries =
|
|
25526
|
+
const entries = readdirSync24(dir, { withFileTypes: true });
|
|
25065
25527
|
for (const entry of entries) {
|
|
25066
25528
|
const fullPath = resolve29(dir, entry.name);
|
|
25067
25529
|
if (entry.isDirectory()) {
|
|
@@ -25121,7 +25583,7 @@ function categorizeFile(filePath) {
|
|
|
25121
25583
|
return "root";
|
|
25122
25584
|
}
|
|
25123
25585
|
function hashContent2(content) {
|
|
25124
|
-
return
|
|
25586
|
+
return createHash9("sha256").update(content).digest("hex");
|
|
25125
25587
|
}
|
|
25126
25588
|
function parseCRTable(content) {
|
|
25127
25589
|
const rules = [];
|
|
@@ -25389,7 +25851,7 @@ function indexAllKnowledge(db) {
|
|
|
25389
25851
|
}
|
|
25390
25852
|
for (const filePath of files) {
|
|
25391
25853
|
if (!existsSync35(filePath)) continue;
|
|
25392
|
-
const content =
|
|
25854
|
+
const content = readFileSync37(filePath, "utf-8");
|
|
25393
25855
|
const hash = hashContent2(content);
|
|
25394
25856
|
const relPath = filePath.startsWith(paths.claudeDir) ? relative12(paths.claudeDir, filePath) : filePath.startsWith(paths.plansDir) ? "plans/" + relative12(paths.plansDir, filePath) : filePath.startsWith(paths.docsDir) ? "docs/" + relative12(paths.docsDir, filePath) : filePath.startsWith(paths.memoryDir) ? `memory/${relative12(paths.memoryDir, filePath)}` : basename8(filePath);
|
|
25395
25857
|
const category = categorizeFile(filePath);
|
|
@@ -25541,7 +26003,7 @@ var init_knowledge_indexer = __esm({
|
|
|
25541
26003
|
});
|
|
25542
26004
|
|
|
25543
26005
|
// src/knowledge-tools.ts
|
|
25544
|
-
import { readFileSync as
|
|
26006
|
+
import { readFileSync as readFileSync38, writeFileSync as writeFileSync6, appendFileSync as appendFileSync2, readdirSync as readdirSync25 } from "fs";
|
|
25545
26007
|
import { resolve as resolve30, basename as basename9 } from "path";
|
|
25546
26008
|
function p16(baseName) {
|
|
25547
26009
|
return `${getConfig().toolPrefix}_${baseName}`;
|
|
@@ -26292,14 +26754,14 @@ ${crRule ? `- **CR**: ${crRule}
|
|
|
26292
26754
|
`;
|
|
26293
26755
|
let existing = "";
|
|
26294
26756
|
try {
|
|
26295
|
-
existing =
|
|
26757
|
+
existing = readFileSync38(correctionsPath, "utf-8");
|
|
26296
26758
|
} catch {
|
|
26297
26759
|
}
|
|
26298
26760
|
const archiveIdx = existing.indexOf("## Archived");
|
|
26299
26761
|
if (archiveIdx > 0) {
|
|
26300
26762
|
const before = existing.slice(0, archiveIdx);
|
|
26301
26763
|
const after = existing.slice(archiveIdx);
|
|
26302
|
-
|
|
26764
|
+
writeFileSync6(correctionsPath, before + entry + after);
|
|
26303
26765
|
} else {
|
|
26304
26766
|
appendFileSync2(correctionsPath, entry);
|
|
26305
26767
|
}
|
|
@@ -26474,7 +26936,7 @@ function handleGaps(db, args2) {
|
|
|
26474
26936
|
} else if (checkType === "routers") {
|
|
26475
26937
|
try {
|
|
26476
26938
|
const routersDir = getResolvedPaths().routersDir;
|
|
26477
|
-
const routerFiles =
|
|
26939
|
+
const routerFiles = readdirSync25(routersDir).filter((f2) => f2.endsWith(".ts") && !f2.startsWith("_"));
|
|
26478
26940
|
lines.push(`| Router | Knowledge Hits | Status |`);
|
|
26479
26941
|
lines.push(`|--------|----------------|--------|`);
|
|
26480
26942
|
for (const file of routerFiles) {
|
|
@@ -26630,13 +27092,13 @@ var init_knowledge_tools = __esm({
|
|
|
26630
27092
|
|
|
26631
27093
|
// src/knowledge-db.ts
|
|
26632
27094
|
import Database3 from "better-sqlite3";
|
|
26633
|
-
import { dirname as
|
|
26634
|
-
import { existsSync as existsSync37, mkdirSync as
|
|
27095
|
+
import { dirname as dirname16 } from "path";
|
|
27096
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync11 } from "fs";
|
|
26635
27097
|
function getKnowledgeDb() {
|
|
26636
27098
|
const dbPath = getResolvedPaths().knowledgeDbPath;
|
|
26637
|
-
const dir =
|
|
27099
|
+
const dir = dirname16(dbPath);
|
|
26638
27100
|
if (!existsSync37(dir)) {
|
|
26639
|
-
|
|
27101
|
+
mkdirSync11(dir, { recursive: true });
|
|
26640
27102
|
}
|
|
26641
27103
|
const db = new Database3(dbPath);
|
|
26642
27104
|
db.pragma("journal_mode = WAL");
|
|
@@ -27369,7 +27831,7 @@ var init_python_tools = __esm({
|
|
|
27369
27831
|
});
|
|
27370
27832
|
|
|
27371
27833
|
// src/tools.ts
|
|
27372
|
-
import { readFileSync as
|
|
27834
|
+
import { readFileSync as readFileSync39, existsSync as existsSync38 } from "fs";
|
|
27373
27835
|
import { resolve as resolve31, basename as basename10 } from "path";
|
|
27374
27836
|
function prefix2() {
|
|
27375
27837
|
return getConfig().toolPrefix;
|
|
@@ -27806,7 +28268,7 @@ function handleContext(file, dataDb2, codegraphDb2) {
|
|
|
27806
28268
|
const root = getProjectRoot();
|
|
27807
28269
|
const absFilePath = ensureWithinRoot(resolve31(resolvedPaths.srcDir, "..", file), root);
|
|
27808
28270
|
if (existsSync38(absFilePath)) {
|
|
27809
|
-
const fileContent =
|
|
28271
|
+
const fileContent = readFileSync39(absFilePath, "utf-8").slice(0, 3e3);
|
|
27810
28272
|
const keywords = [];
|
|
27811
28273
|
if (fileContent.includes("ctx.db")) keywords.push("database", "schema");
|
|
27812
28274
|
if (fileContent.includes("BigInt") || fileContent.includes("Decimal")) keywords.push("BigInt", "serialization");
|
|
@@ -28234,7 +28696,7 @@ function handleSchema(args2) {
|
|
|
28234
28696
|
if (!existsSync38(absPath)) {
|
|
28235
28697
|
return text17(`File not found: ${file}`);
|
|
28236
28698
|
}
|
|
28237
|
-
const source =
|
|
28699
|
+
const source = readFileSync39(absPath, "utf-8");
|
|
28238
28700
|
const config = getConfig();
|
|
28239
28701
|
const dbPattern = config.dbAccessPattern ?? "ctx.db.{table}";
|
|
28240
28702
|
const regexStr = dbPattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace("\\{table\\}", "(\\w+)");
|
|
@@ -28312,8 +28774,8 @@ var init_tools = __esm({
|
|
|
28312
28774
|
|
|
28313
28775
|
// src/server.ts
|
|
28314
28776
|
var server_exports = {};
|
|
28315
|
-
import { readFileSync as
|
|
28316
|
-
import { resolve as resolve32, dirname as
|
|
28777
|
+
import { readFileSync as readFileSync40 } from "fs";
|
|
28778
|
+
import { resolve as resolve32, dirname as dirname17 } from "path";
|
|
28317
28779
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
28318
28780
|
function getDb() {
|
|
28319
28781
|
if (!codegraphDb) codegraphDb = getCodeGraphDb();
|
|
@@ -28405,10 +28867,10 @@ var init_server = __esm({
|
|
|
28405
28867
|
init_tools();
|
|
28406
28868
|
init_memory_db();
|
|
28407
28869
|
init_license();
|
|
28408
|
-
__dirname4 =
|
|
28870
|
+
__dirname4 = dirname17(fileURLToPath4(import.meta.url));
|
|
28409
28871
|
PKG_VERSION = (() => {
|
|
28410
28872
|
try {
|
|
28411
|
-
const pkg = JSON.parse(
|
|
28873
|
+
const pkg = JSON.parse(readFileSync40(resolve32(__dirname4, "..", "package.json"), "utf-8"));
|
|
28412
28874
|
return pkg.version ?? "0.0.0";
|
|
28413
28875
|
} catch {
|
|
28414
28876
|
return "0.0.0";
|
|
@@ -28711,7 +29173,7 @@ var config_upgrade_exports = {};
|
|
|
28711
29173
|
__export(config_upgrade_exports, {
|
|
28712
29174
|
runConfigUpgrade: () => runConfigUpgrade
|
|
28713
29175
|
});
|
|
28714
|
-
import { existsSync as existsSync39, readFileSync as
|
|
29176
|
+
import { existsSync as existsSync39, readFileSync as readFileSync41, writeFileSync as writeFileSync7, copyFileSync, unlinkSync as unlinkSync3 } from "fs";
|
|
28715
29177
|
import { resolve as resolve33 } from "path";
|
|
28716
29178
|
import { parse as parseYaml6 } from "yaml";
|
|
28717
29179
|
async function runConfigUpgrade(opts = {}) {
|
|
@@ -28730,7 +29192,7 @@ async function runConfigUpgrade(opts = {}) {
|
|
|
28730
29192
|
}
|
|
28731
29193
|
try {
|
|
28732
29194
|
copyFileSync(bakPath, configPath);
|
|
28733
|
-
|
|
29195
|
+
unlinkSync3(bakPath);
|
|
28734
29196
|
log("Config restored from backup.\n");
|
|
28735
29197
|
return { exitCode: 0, action: "rolled-back" };
|
|
28736
29198
|
} catch (e2) {
|
|
@@ -28746,7 +29208,7 @@ async function runConfigUpgrade(opts = {}) {
|
|
|
28746
29208
|
}
|
|
28747
29209
|
let existing;
|
|
28748
29210
|
try {
|
|
28749
|
-
const content =
|
|
29211
|
+
const content = readFileSync41(configPath, "utf-8");
|
|
28750
29212
|
const parsed = parseYaml6(content);
|
|
28751
29213
|
if (!parsed || typeof parsed !== "object") {
|
|
28752
29214
|
throw new Error("config is not a YAML object");
|
|
@@ -28769,8 +29231,8 @@ async function runConfigUpgrade(opts = {}) {
|
|
|
28769
29231
|
fingerprint: computeFingerprint(detection)
|
|
28770
29232
|
};
|
|
28771
29233
|
try {
|
|
28772
|
-
const original =
|
|
28773
|
-
|
|
29234
|
+
const original = readFileSync41(configPath, "utf-8");
|
|
29235
|
+
writeFileSync7(bakPath, original, "utf-8");
|
|
28774
29236
|
} catch (e2) {
|
|
28775
29237
|
const message = `Failed to write backup: ${e2 instanceof Error ? e2.message : String(e2)}`;
|
|
28776
29238
|
err(message + "\n");
|
|
@@ -28803,7 +29265,7 @@ var config_check_drift_exports = {};
|
|
|
28803
29265
|
__export(config_check_drift_exports, {
|
|
28804
29266
|
runConfigCheckDrift: () => runConfigCheckDrift
|
|
28805
29267
|
});
|
|
28806
|
-
import { existsSync as existsSync40, readFileSync as
|
|
29268
|
+
import { existsSync as existsSync40, readFileSync as readFileSync42 } from "fs";
|
|
28807
29269
|
import { resolve as resolve34 } from "path";
|
|
28808
29270
|
import { parse as parseYaml7 } from "yaml";
|
|
28809
29271
|
function renderChanges(changes) {
|
|
@@ -28831,7 +29293,7 @@ async function runConfigCheckDrift(opts = {}) {
|
|
|
28831
29293
|
}
|
|
28832
29294
|
let config;
|
|
28833
29295
|
try {
|
|
28834
|
-
const content =
|
|
29296
|
+
const content = readFileSync42(configPath, "utf-8");
|
|
28835
29297
|
const parsed = parseYaml7(content);
|
|
28836
29298
|
if (!parsed || typeof parsed !== "object") {
|
|
28837
29299
|
throw new Error("config is not a YAML object");
|
|
@@ -28898,11 +29360,11 @@ var init_config_check_drift = __esm({
|
|
|
28898
29360
|
});
|
|
28899
29361
|
|
|
28900
29362
|
// src/cli.ts
|
|
28901
|
-
import { readFileSync as
|
|
28902
|
-
import { resolve as resolve35, dirname as
|
|
29363
|
+
import { readFileSync as readFileSync43 } from "fs";
|
|
29364
|
+
import { resolve as resolve35, dirname as dirname18 } from "path";
|
|
28903
29365
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
28904
29366
|
var __filename4 = fileURLToPath5(import.meta.url);
|
|
28905
|
-
var __dirname5 =
|
|
29367
|
+
var __dirname5 = dirname18(__filename4);
|
|
28906
29368
|
var args = process.argv.slice(2);
|
|
28907
29369
|
var subcommand = args[0];
|
|
28908
29370
|
async function main() {
|
|
@@ -29084,7 +29546,7 @@ Examples:
|
|
|
29084
29546
|
}
|
|
29085
29547
|
function printVersion() {
|
|
29086
29548
|
try {
|
|
29087
|
-
const pkg = JSON.parse(
|
|
29549
|
+
const pkg = JSON.parse(readFileSync43(resolve35(__dirname5, "../package.json"), "utf-8"));
|
|
29088
29550
|
console.log(`massu v${pkg.version}`);
|
|
29089
29551
|
} catch {
|
|
29090
29552
|
console.log("massu v0.1.0");
|