@massu/core 2.3.1 → 2.5.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.
@@ -454,6 +454,12 @@ import { join as join2 } from "path";
454
454
  function resolveDbEngine() {
455
455
  return process.env[DB_ENGINE_ENV] === "better-sqlite3" ? "better-sqlite3" : DEFAULT_DB_ENGINE;
456
456
  }
457
+ function resolveBusyTimeoutMs() {
458
+ const raw = process.env[DB_BUSY_TIMEOUT_ENV];
459
+ if (raw === void 0 || raw === "") return DEFAULT_BUSY_TIMEOUT_MS;
460
+ const n = Number(raw);
461
+ return Number.isFinite(n) && n >= 0 ? Math.floor(n) : DEFAULT_BUSY_TIMEOUT_MS;
462
+ }
457
463
  function nodeSqliteCtor() {
458
464
  if (!_nodeCtor) _nodeCtor = req2("node:sqlite").DatabaseSync;
459
465
  return _nodeCtor;
@@ -475,6 +481,7 @@ function openNodeSqlite(dbPath, opts) {
475
481
  enableForeignKeyConstraints: true,
476
482
  allowExtension: false
477
483
  });
484
+ raw.exec(`PRAGMA busy_timeout = ${resolveBusyTimeoutMs()}`);
478
485
  let savepointSeq = 0;
479
486
  const wrapStmt = (sql) => {
480
487
  const st = raw.prepare(sql);
@@ -558,12 +565,14 @@ function openNodeSqlite(dbPath, opts) {
558
565
  return handle;
559
566
  }
560
567
  function openBetterSqlite3(dbPath, opts) {
561
- return openDatabase(dbPath, opts);
568
+ const db = openDatabase(dbPath, opts);
569
+ db.exec(`PRAGMA busy_timeout = ${resolveBusyTimeoutMs()}`);
570
+ return db;
562
571
  }
563
572
  function openDatabase2(dbPath, opts = {}) {
564
573
  return resolveDbEngine() === "better-sqlite3" ? openBetterSqlite3(dbPath, opts) : openNodeSqlite(dbPath, opts);
565
574
  }
566
- var req2, DEFAULT_DB_ENGINE, DB_ENGINE_ENV, _nodeCtor;
575
+ var req2, DEFAULT_DB_ENGINE, DB_ENGINE_ENV, DEFAULT_BUSY_TIMEOUT_MS, DB_BUSY_TIMEOUT_ENV, _nodeCtor;
567
576
  var init_db_driver = __esm({
568
577
  "src/db-driver.ts"() {
569
578
  "use strict";
@@ -572,6 +581,8 @@ var init_db_driver = __esm({
572
581
  req2 = createRequire2(import.meta.url);
573
582
  DEFAULT_DB_ENGINE = "node-sqlite";
574
583
  DB_ENGINE_ENV = "MASSU_DB_ENGINE";
584
+ DEFAULT_BUSY_TIMEOUT_MS = 5e3;
585
+ DB_BUSY_TIMEOUT_ENV = "MASSU_DB_BUSY_TIMEOUT_MS";
575
586
  _nodeCtor = null;
576
587
  }
577
588
  });
@@ -12646,23 +12657,23 @@ function introspectPython(detection, projectRoot) {
12646
12657
  for (const path of candidates) {
12647
12658
  const body = readSafe(path);
12648
12659
  if (body === null) continue;
12649
- const authRegex = /\bDepends\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)/gu;
12660
+ const authRegex = new RegExp(PY_AUTH_DEP_PATTERN, "gu");
12650
12661
  forEachMatch(authRegex, body, (m) => {
12651
12662
  const name = m[1];
12652
12663
  if (!authDeps.has(name)) authDeps.set(name, path);
12653
12664
  });
12654
- const djangoAuthRegex = /^@\s*([a-z_][a-z0-9_]*(?:_required|_login))\b/gmu;
12665
+ const djangoAuthRegex = new RegExp(PY_DJANGO_AUTH_PATTERN, "gmu");
12655
12666
  forEachMatch(djangoAuthRegex, body, (m) => {
12656
12667
  const name = m[1];
12657
12668
  if (!authDeps.has(name)) authDeps.set(name, path);
12658
12669
  });
12659
- const prefixRegex = /\bAPIRouter\s*\(\s*[^)]*?prefix\s*=\s*["']([^"']+)["']/gu;
12670
+ const prefixRegex = new RegExp(PY_API_PREFIX_PATTERN, "gu");
12660
12671
  forEachMatch(prefixRegex, body, (m) => {
12661
12672
  const fullPrefix = m[1];
12662
12673
  const base = extractPrefixBase(fullPrefix);
12663
12674
  if (base && !prefixBases.has(base)) prefixBases.set(base, path);
12664
12675
  });
12665
- const asyncRegex = /^(@pytest\.mark\.asyncio(?:\s*\([^)]*\))?)/gmu;
12676
+ const asyncRegex = new RegExp(PY_TEST_ASYNC_PATTERN, "gmu");
12666
12677
  forEachMatch(asyncRegex, body, (m) => {
12667
12678
  const pat = m[1].trim();
12668
12679
  if (!testAsyncPatterns.has(pat)) testAsyncPatterns.set(pat, path);
@@ -12867,10 +12878,14 @@ function relativeTo(projectRoot, absPath) {
12867
12878
  }
12868
12879
  return basename4(absPath);
12869
12880
  }
12870
- var MAX_FILE_BYTES, MAX_SAMPLES_PER_ADAPTER, MAX_DIR_DEPTH;
12881
+ var PY_AUTH_DEP_PATTERN, PY_DJANGO_AUTH_PATTERN, PY_API_PREFIX_PATTERN, PY_TEST_ASYNC_PATTERN, MAX_FILE_BYTES, MAX_SAMPLES_PER_ADAPTER, MAX_DIR_DEPTH;
12871
12882
  var init_regex_fallback = __esm({
12872
12883
  "src/detect/regex-fallback.ts"() {
12873
12884
  "use strict";
12885
+ PY_AUTH_DEP_PATTERN = String.raw`\bDepends\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)`;
12886
+ PY_DJANGO_AUTH_PATTERN = String.raw`^@\s*([a-z_][a-z0-9_]*(?:_required|_login))\b`;
12887
+ PY_API_PREFIX_PATTERN = String.raw`\bAPIRouter\s*\(\s*[^)]*?prefix\s*=\s*["']([^"']+)["']`;
12888
+ PY_TEST_ASYNC_PATTERN = String.raw`^(@pytest\.mark\.asyncio(?:\s*\([^)]*\))?)`;
12874
12889
  MAX_FILE_BYTES = 256 * 1024;
12875
12890
  MAX_SAMPLES_PER_ADAPTER = 3;
12876
12891
  MAX_DIR_DEPTH = 6;
@@ -431,6 +431,12 @@ import { join as join2 } from "path";
431
431
  function resolveDbEngine() {
432
432
  return process.env[DB_ENGINE_ENV] === "better-sqlite3" ? "better-sqlite3" : DEFAULT_DB_ENGINE;
433
433
  }
434
+ function resolveBusyTimeoutMs() {
435
+ const raw = process.env[DB_BUSY_TIMEOUT_ENV];
436
+ if (raw === void 0 || raw === "") return DEFAULT_BUSY_TIMEOUT_MS;
437
+ const n = Number(raw);
438
+ return Number.isFinite(n) && n >= 0 ? Math.floor(n) : DEFAULT_BUSY_TIMEOUT_MS;
439
+ }
434
440
  function nodeSqliteCtor() {
435
441
  if (!_nodeCtor) _nodeCtor = req2("node:sqlite").DatabaseSync;
436
442
  return _nodeCtor;
@@ -452,6 +458,7 @@ function openNodeSqlite(dbPath, opts) {
452
458
  enableForeignKeyConstraints: true,
453
459
  allowExtension: false
454
460
  });
461
+ raw.exec(`PRAGMA busy_timeout = ${resolveBusyTimeoutMs()}`);
455
462
  let savepointSeq = 0;
456
463
  const wrapStmt = (sql) => {
457
464
  const st = raw.prepare(sql);
@@ -535,12 +542,14 @@ function openNodeSqlite(dbPath, opts) {
535
542
  return handle;
536
543
  }
537
544
  function openBetterSqlite3(dbPath, opts) {
538
- return openDatabase(dbPath, opts);
545
+ const db = openDatabase(dbPath, opts);
546
+ db.exec(`PRAGMA busy_timeout = ${resolveBusyTimeoutMs()}`);
547
+ return db;
539
548
  }
540
549
  function openDatabase2(dbPath, opts = {}) {
541
550
  return resolveDbEngine() === "better-sqlite3" ? openBetterSqlite3(dbPath, opts) : openNodeSqlite(dbPath, opts);
542
551
  }
543
- var req2, DEFAULT_DB_ENGINE, DB_ENGINE_ENV, _nodeCtor;
552
+ var req2, DEFAULT_DB_ENGINE, DB_ENGINE_ENV, DEFAULT_BUSY_TIMEOUT_MS, DB_BUSY_TIMEOUT_ENV, _nodeCtor;
544
553
  var init_db_driver = __esm({
545
554
  "src/db-driver.ts"() {
546
555
  "use strict";
@@ -549,6 +558,8 @@ var init_db_driver = __esm({
549
558
  req2 = createRequire2(import.meta.url);
550
559
  DEFAULT_DB_ENGINE = "node-sqlite";
551
560
  DB_ENGINE_ENV = "MASSU_DB_ENGINE";
561
+ DEFAULT_BUSY_TIMEOUT_MS = 5e3;
562
+ DB_BUSY_TIMEOUT_ENV = "MASSU_DB_BUSY_TIMEOUT_MS";
552
563
  _nodeCtor = null;
553
564
  }
554
565
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massu/core",
3
- "version": "2.3.1",
3
+ "version": "2.5.0",
4
4
  "type": "module",
5
5
  "description": "AI Engineering Governance MCP Server - Session memory, knowledge system, feature registry, code intelligence, rule enforcement, tiered tooling (12 free / 73 total), 56 workflow commands, 11 agents, 20+ patterns",
6
6
  "main": "./dist/cli.js",
@@ -28,8 +28,8 @@
28
28
  "build:adapter-types": "tsc -p tsconfig.adapter-types.json",
29
29
  "build:adapter-subpath": "tsx scripts/bundle-adapters.ts --subpath-only",
30
30
  "build:bundle-adapters": "tsx scripts/bundle-adapters.ts",
31
- "build:cli": "esbuild --bundle --platform=node --format=esm --outfile=dist/cli.js src/cli.ts --external:better-sqlite3 --external:yaml --external:zod --external:chokidar --external:proper-lockfile --external:fsevents --external:web-tree-sitter --external:tweetnacl --external:tar --external:smol-toml --external:vscode-languageserver-protocol --external:onnxruntime-web --external:@massu/adapter-rails --external:@massu/adapter-spring --banner:js='#!/usr/bin/env node\nimport{createRequire as __cr}from\"module\";const require=__cr(import.meta.url);'",
32
- "build:hooks": "esbuild --bundle --platform=node --format=esm --outdir=dist/hooks src/hooks/*.ts --external:better-sqlite3 --external:yaml --external:zod --external:chokidar --external:proper-lockfile --external:fsevents --external:web-tree-sitter --external:tweetnacl --external:tar --external:smol-toml --external:vscode-languageserver-protocol --external:onnxruntime-web --external:@massu/adapter-rails --external:@massu/adapter-spring --banner:js='import{createRequire as __cr}from\"module\";const require=__cr(import.meta.url);'",
31
+ "build:cli": "node scripts/build-bundles.mjs --cli",
32
+ "build:hooks": "node scripts/build-bundles.mjs --hooks",
33
33
  "prepublishOnly": "bash ../../scripts/prepublish-check.sh && node ../../scripts/bundle-pubkey.mjs && node ../../scripts/bundle-license-pubkey.mjs && node ../../scripts/bundle-promotion-pubkey.mjs && node ../../scripts/bundle-audit-export-pubkey.mjs && cp ../../CHANGELOG.md ./CHANGELOG.md && npm run build && bash ../../scripts/npm-publish-guard.sh",
34
34
  "bench:watch": "tsx test/perf/watch-benchmark.ts",
35
35
  "build:owned-sidecars": "node scripts/gen-owned-sidecars.mjs"