@cortexkit/magic-context 0.44.2 → 0.44.3

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.
Files changed (2) hide show
  1. package/dist/index.js +60 -27
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1688,7 +1688,10 @@ function installTransactionRouting(db, readonly) {
1688
1688
  writable: true,
1689
1689
  value: (sql) => {
1690
1690
  if (/^\s*BEGIN\s+(?:IMMEDIATE|EXCLUSIVE)(?:\s+TRANSACTION)?\s*;?\s*$/i.test(sql)) {
1691
- retryAcquisition(() => nativeExec(sql), sql.trim());
1691
+ if (transformPassScope.getStore()?.active || backgroundWriterScope.getStore())
1692
+ acquireShort(db, () => nativeExec(sql), sql.trim());
1693
+ else
1694
+ nativeExec(sql);
1692
1695
  return db;
1693
1696
  }
1694
1697
  return nativeExec(sql);
@@ -1784,29 +1787,45 @@ function buildNodeSqliteDatabaseClass(DatabaseSync) {
1784
1787
  }
1785
1788
  return NodeSqliteDatabase;
1786
1789
  }
1790
+ function pragmaValue(db, name) {
1791
+ const row = db.prepare(`PRAGMA ${name}`).get();
1792
+ if (!row)
1793
+ return;
1794
+ return row[name] ?? Object.values(row)[0];
1795
+ }
1796
+ function pragmaNumber(db, name) {
1797
+ try {
1798
+ const value = pragmaValue(db, name);
1799
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
1800
+ } catch {
1801
+ return null;
1802
+ }
1803
+ }
1787
1804
  function isTransientSqliteError(error) {
1788
1805
  if (!error || typeof error !== "object")
1789
1806
  return false;
1790
1807
  const value = error;
1791
1808
  return typeof value.code === "string" && /^(SQLITE_BUSY|SQLITE_LOCKED)(_|$)/.test(value.code) || typeof value.errcode === "number" && [5, 6].includes(value.errcode & 255);
1792
1809
  }
1793
- function retryAcquisition(acquire, stage) {
1794
- if (!transformPassScope.getStore()?.active) {
1810
+ function acquireShort(db, acquire, site) {
1811
+ const started = performance.now();
1812
+ const previous = pragmaNumber(db, "busy_timeout");
1813
+ let acquired = false;
1814
+ try {
1815
+ const timeout = transformPassScope.getStore()?.active && !admissionScope.getStore() && !backgroundWriterScope.getStore() ? FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS : SHORT_BUSY_TIMEOUT_MS;
1816
+ db.exec(`PRAGMA busy_timeout=${timeout}`);
1795
1817
  acquire();
1796
- return;
1797
- }
1798
- const delays = [500, 1000];
1799
- for (let attempt = 0;; attempt++) {
1800
- try {
1801
- acquire();
1802
- return;
1803
- } catch (error) {
1804
- if (error instanceof SqliteAcquisitionBusyError || !isTransientSqliteError(error))
1805
- throw error;
1806
- if (attempt === delays.length)
1807
- throw new SqliteAcquisitionBusyError(error, stage);
1808
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, delays[attempt]);
1809
- }
1818
+ acquired = true;
1819
+ } catch (error) {
1820
+ if (transformPassScope.getStore()?.active && isTransientSqliteError(error))
1821
+ throw new SqliteAcquisitionBusyError(error, site);
1822
+ throw error;
1823
+ } finally {
1824
+ if (previous !== null)
1825
+ db.exec(`PRAGMA busy_timeout=${previous}`);
1826
+ const elapsed = performance.now() - started;
1827
+ if (elapsed >= 250)
1828
+ console.warn(`[${new Date().toISOString()}] [magic-context] sqlite acquisition site=${site} lane=${transformPassScope.getStore()?.active ? "foreground" : "background"} elapsed=${Math.round(elapsed)}ms attempts=1 outcome=${acquired ? "acquired" : "busy"}`);
1810
1829
  }
1811
1830
  }
1812
1831
  function isInTransaction(db) {
@@ -1821,7 +1840,13 @@ function withPrivilegedWriter(db, operation) {
1821
1840
  if (nested) {
1822
1841
  db.exec(`SAVEPOINT ${savepoint}`);
1823
1842
  } else {
1824
- retryAcquisition(() => db.exec("BEGIN IMMEDIATE"), "BEGIN IMMEDIATE");
1843
+ try {
1844
+ db.exec("BEGIN IMMEDIATE");
1845
+ } catch (error) {
1846
+ if (transformPassScope.getStore()?.active && isTransientSqliteError(error))
1847
+ throw new SqliteAcquisitionBusyError(error);
1848
+ throw error;
1849
+ }
1825
1850
  }
1826
1851
  privilegeDepth.set(db, previousDepth + 1);
1827
1852
  try {
@@ -1860,7 +1885,7 @@ function withPrivilegedWriter(db, operation) {
1860
1885
  throw error;
1861
1886
  }
1862
1887
  }
1863
- var reportSlowPrivilegedWrite, bunSpec, nodeSpec, SqliteRuntimeUnavailableError, detectedRuntime, isBun, sqliteModule, DatabaseImpl, trackedSqliteConnections, nextSqliteConnectionSequence = 1, TrackedDatabase, Database, privilegeDepth, transformPassScope, SqliteAcquisitionBusyError;
1888
+ var reportSlowPrivilegedWrite, bunSpec, nodeSpec, SqliteRuntimeUnavailableError, detectedRuntime, isBun, sqliteModule, DatabaseImpl, trackedSqliteConnections, nextSqliteConnectionSequence = 1, TrackedDatabase, Database, privilegeDepth, transformPassScope, admissionScope, backgroundWriterScope, SqliteAcquisitionBusyError, SHORT_BUSY_TIMEOUT_MS = 25, FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS = 250;
1864
1889
  var init_sqlite = __esm(async () => {
1865
1890
  bunSpec = "bun:" + "sqlite";
1866
1891
  nodeSpec = "node:" + "sqlite";
@@ -1889,11 +1914,13 @@ var init_sqlite = __esm(async () => {
1889
1914
  Database = TrackedDatabase;
1890
1915
  privilegeDepth = new WeakMap;
1891
1916
  transformPassScope = new AsyncLocalStorage;
1917
+ admissionScope = new AsyncLocalStorage;
1918
+ backgroundWriterScope = new AsyncLocalStorage;
1892
1919
  SqliteAcquisitionBusyError = class SqliteAcquisitionBusyError extends Error {
1893
1920
  code = "SQLITE_BUSY";
1894
1921
  stage;
1895
1922
  constructor(cause, stage = "BEGIN IMMEDIATE") {
1896
- super("SQLite writer acquisition remained busy after 3 attempts", { cause });
1923
+ super("SQLite writer acquisition remained busy", { cause });
1897
1924
  this.name = "SqliteAcquisitionBusyError";
1898
1925
  this.stage = stage;
1899
1926
  }
@@ -25141,7 +25168,7 @@ function classifyGitError(error, rawDirectory) {
25141
25168
  }
25142
25169
  return new ProjectIdentityError("unknown", rawDirectory, "git rev-list failed while resolving project identity", asError(error));
25143
25170
  }
25144
- function resolveProjectIdentityStrict(directory, allowHomeProject = false) {
25171
+ function resolveProjectIdentityStrict(directory, allowHomeProject = homeProjectPermission) {
25145
25172
  assertProjectAllowed(directory, allowHomeProject);
25146
25173
  const canonical = path4.resolve(directory);
25147
25174
  const cached = identityCache.get(canonical);
@@ -25269,7 +25296,7 @@ function assertProjectAllowed(directory, allowHomeProject) {
25269
25296
  throw new ProjectIdentityError("home_project_disabled", directory, "Home project memory is disabled; set allow_home_project to opt in");
25270
25297
  }
25271
25298
  }
25272
- function resolveProjectIdentity(directory, allowHomeProject = false) {
25299
+ function resolveProjectIdentity(directory, allowHomeProject = homeProjectPermission) {
25273
25300
  assertProjectAllowed(directory, allowHomeProject);
25274
25301
  const canonical = path4.resolve(directory);
25275
25302
  const cachedFallback = directoryFallbackCache.get(canonical);
@@ -25357,7 +25384,7 @@ function gitRootDirectory(canonical) {
25357
25384
  return null;
25358
25385
  }
25359
25386
  }
25360
- var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, linkedGitWorktreeCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, sessionIdentityCache, execFileSyncForIdentity, userHomeDirectoryForIdentity = () => homedir14(), nowMs = () => Date.now(), ProjectIdentityError;
25387
+ var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, linkedGitWorktreeCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, sessionIdentityCache, homeProjectPermission = false, execFileSyncForIdentity, userHomeDirectoryForIdentity = () => homedir14(), nowMs = () => Date.now(), ProjectIdentityError;
25361
25388
  var init_project_identity = __esm(() => {
25362
25389
  init_logger();
25363
25390
  init_project_identity_cache();
@@ -33563,11 +33590,11 @@ async function reportAuthorityMarkers(args) {
33563
33590
  args.info(" no authority_managed markers");
33564
33591
  return;
33565
33592
  }
33593
+ const loaded = loadPluginConfig(process.cwd());
33566
33594
  let currentIdentity;
33567
33595
  try {
33568
- currentIdentity = resolveProjectIdentity(process.cwd());
33596
+ currentIdentity = resolveProjectIdentity(process.cwd(), loaded.allow_home_project);
33569
33597
  } catch {}
33570
- const loaded = loadPluginConfig(process.cwd());
33571
33598
  const transport = new SubcModuleTransport(loaded.subc?.connection_file ?? getDefaultSubcConnectionFile());
33572
33599
  for (const marker of markers) {
33573
33600
  if (marker.project_path !== currentIdentity) {
@@ -33594,12 +33621,18 @@ async function runDoctorDrainAuthority(projectRoot, dbPath) {
33594
33621
  return 1;
33595
33622
  }
33596
33623
  try {
33597
- const projectPath = resolveProjectIdentity(projectRoot);
33624
+ const loaded = loadPluginConfig(projectRoot);
33625
+ let projectPath;
33626
+ try {
33627
+ projectPath = resolveProjectIdentity(projectRoot, loaded.allow_home_project);
33628
+ } catch (error) {
33629
+ console.error(error instanceof Error ? error.message : String(error));
33630
+ return 1;
33631
+ }
33598
33632
  if (!getAuthorityManagedMarker(db, projectPath)) {
33599
33633
  console.log(`No authority_managed marker exists for ${projectPath}.`);
33600
33634
  return 0;
33601
33635
  }
33602
- const loaded = loadPluginConfig(projectRoot);
33603
33636
  const module = authorityClient(new SubcModuleTransport(loaded.subc?.connection_file ?? getDefaultSubcConnectionFile()), projectRoot);
33604
33637
  let drainedAny = false;
33605
33638
  for (const domain of AUTHORITY_DOMAINS) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/magic-context",
3
- "version": "0.44.2",
3
+ "version": "0.44.3",
4
4
  "description": "Unified CLI for Magic Context — setup, doctor, and migration across OpenCode, Pi, and OMP",
5
5
  "keywords": [
6
6
  "opencode",