@openez-graph/cli 0.11.1 → 0.12.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/cli.cjs CHANGED
@@ -2912,7 +2912,7 @@ var require_command = __commonJS({
2912
2912
  var EventEmitter2 = require("events").EventEmitter;
2913
2913
  var childProcess = require("child_process");
2914
2914
  var path24 = require("path");
2915
- var fs22 = require("fs");
2915
+ var fs23 = require("fs");
2916
2916
  var process3 = require("process");
2917
2917
  var { Argument: Argument2, humanReadableArgName } = require_argument();
2918
2918
  var { CommanderError: CommanderError2 } = require_error();
@@ -3906,7 +3906,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
3906
3906
  * @param {string} subcommandName
3907
3907
  */
3908
3908
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
3909
- if (fs22.existsSync(executableFile)) return;
3909
+ if (fs23.existsSync(executableFile)) return;
3910
3910
  const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
3911
3911
  const executableMissing = `'${executableFile}' does not exist
3912
3912
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
@@ -3925,10 +3925,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
3925
3925
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
3926
3926
  function findFile(baseDir, baseName) {
3927
3927
  const localBin = path24.resolve(baseDir, baseName);
3928
- if (fs22.existsSync(localBin)) return localBin;
3928
+ if (fs23.existsSync(localBin)) return localBin;
3929
3929
  if (sourceExt.includes(path24.extname(baseName))) return void 0;
3930
3930
  const foundExt = sourceExt.find(
3931
- (ext) => fs22.existsSync(`${localBin}${ext}`)
3931
+ (ext) => fs23.existsSync(`${localBin}${ext}`)
3932
3932
  );
3933
3933
  if (foundExt) return `${localBin}${foundExt}`;
3934
3934
  return void 0;
@@ -3940,7 +3940,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
3940
3940
  if (this._scriptPath) {
3941
3941
  let resolvedScriptPath;
3942
3942
  try {
3943
- resolvedScriptPath = fs22.realpathSync(this._scriptPath);
3943
+ resolvedScriptPath = fs23.realpathSync(this._scriptPath);
3944
3944
  } catch {
3945
3945
  resolvedScriptPath = this._scriptPath;
3946
3946
  }
@@ -11528,6 +11528,8 @@ var init_schema = __esm({
11528
11528
  nodeCount: integer("node_count").notNull().default(0),
11529
11529
  edgeCount: integer("edge_count").notNull().default(0),
11530
11530
  lastError: text("last_error"),
11531
+ pinnedAt: text("pinned_at"),
11532
+ pinOrder: integer("pin_order"),
11531
11533
  createdAt: text("created_at").notNull().default(sql`(datetime('now'))`),
11532
11534
  updatedAt: text("updated_at").notNull().default(sql`(datetime('now'))`)
11533
11535
  },
@@ -11724,9 +11726,11 @@ function getRegistryDb() {
11724
11726
  const sqlite = createNativeDatabase(dbPath);
11725
11727
  sqlite.pragma("journal_mode = WAL");
11726
11728
  sqlite.pragma("foreign_keys = ON");
11727
- registryDb = drizzle(sqlite, { schema: schema_exports });
11729
+ const db = drizzle(sqlite, { schema: schema_exports });
11728
11730
  initializeRegistrySchema(sqlite);
11731
+ registryDb = db;
11729
11732
  } catch (err) {
11733
+ registryDb = null;
11730
11734
  const message = err instanceof Error ? err.message : String(err);
11731
11735
  throw new Error(`Failed to open registry DB at "${dbPath}": ${message}`);
11732
11736
  }
@@ -11751,6 +11755,7 @@ function initializeRegistrySchema(sqlite) {
11751
11755
  node_count INTEGER NOT NULL DEFAULT 0,
11752
11756
  edge_count INTEGER NOT NULL DEFAULT 0,
11753
11757
  last_error TEXT,
11758
+ pinned_at TEXT,
11754
11759
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
11755
11760
  updated_at TEXT NOT NULL DEFAULT (datetime('now'))
11756
11761
  );
@@ -11764,6 +11769,38 @@ function initializeRegistrySchema(sqlite) {
11764
11769
  updated_at TEXT NOT NULL DEFAULT (datetime('now'))
11765
11770
  );
11766
11771
  `);
11772
+ migrateRegistryColumns(sqlite);
11773
+ }
11774
+ function migrateRegistryColumns(sqlite) {
11775
+ const getColumns = () => new Set(
11776
+ sqlite.prepare("PRAGMA table_info(workspaces)").all().map(
11777
+ (row) => row.name
11778
+ )
11779
+ );
11780
+ const addColumnIfMissing = (name, definition) => {
11781
+ if (getColumns().has(name)) return;
11782
+ try {
11783
+ sqlite.exec(`ALTER TABLE workspaces ADD COLUMN ${definition}`);
11784
+ } catch (err) {
11785
+ if (!getColumns().has(name)) {
11786
+ throw err;
11787
+ }
11788
+ }
11789
+ };
11790
+ addColumnIfMissing("pinned_at", "pinned_at TEXT");
11791
+ addColumnIfMissing("pin_order", "pin_order INTEGER");
11792
+ const unbackfilled = sqlite.prepare(
11793
+ "SELECT id FROM workspaces WHERE pinned_at IS NOT NULL AND pin_order IS NULL ORDER BY pinned_at DESC"
11794
+ ).all();
11795
+ if (unbackfilled.length > 0) {
11796
+ const maxRow = sqlite.prepare("SELECT MAX(pin_order) AS max_order FROM workspaces WHERE pin_order IS NOT NULL").get();
11797
+ let next = (maxRow?.max_order ?? 0) + 1;
11798
+ const stmt = sqlite.prepare("UPDATE workspaces SET pin_order = ? WHERE id = ?");
11799
+ for (const row of unbackfilled) {
11800
+ stmt.run(next, row.id);
11801
+ next += 1;
11802
+ }
11803
+ }
11767
11804
  }
11768
11805
  var import_node_fs2, import_node_os, import_node_path3, registryDb;
11769
11806
  var init_registry_db = __esm({
@@ -11796,8 +11833,20 @@ function getWorkspaceDb(rootPath) {
11796
11833
  const db = drizzle(sqlite, { schema: schema_exports });
11797
11834
  initializeWorkspaceSchema(sqlite);
11798
11835
  dbCache.set(rootPath, db);
11836
+ nativeCache.set(rootPath, sqlite);
11799
11837
  return db;
11800
11838
  }
11839
+ function closeWorkspaceDb(rootPath) {
11840
+ const native = nativeCache.get(rootPath);
11841
+ if (native) {
11842
+ try {
11843
+ native.close();
11844
+ } catch {
11845
+ }
11846
+ nativeCache.delete(rootPath);
11847
+ }
11848
+ dbCache.delete(rootPath);
11849
+ }
11801
11850
  function initializeWorkspaceSchema(sqlite) {
11802
11851
  const tables = getWorkspaceTableDefinitions();
11803
11852
  for (const ddl of tables) {
@@ -12045,7 +12094,7 @@ function getWorkspaceTableDefinitions() {
12045
12094
  )`
12046
12095
  ];
12047
12096
  }
12048
- var import_node_fs3, import_node_path4, WORKSPACE_DB_DIR_NAME, WORKSPACE_DB_FILE_NAME, dbCache;
12097
+ var import_node_fs3, import_node_path4, WORKSPACE_DB_DIR_NAME, WORKSPACE_DB_FILE_NAME, dbCache, nativeCache;
12049
12098
  var init_workspace_db = __esm({
12050
12099
  "../../packages/db/src/sqlite/workspace-db.ts"() {
12051
12100
  "use strict";
@@ -12057,6 +12106,7 @@ var init_workspace_db = __esm({
12057
12106
  WORKSPACE_DB_DIR_NAME = ".openez";
12058
12107
  WORKSPACE_DB_FILE_NAME = "index.sqlite";
12059
12108
  dbCache = /* @__PURE__ */ new Map();
12109
+ nativeCache = /* @__PURE__ */ new Map();
12060
12110
  }
12061
12111
  });
12062
12112
 
@@ -12181,7 +12231,7 @@ function createRegistryRepository() {
12181
12231
  return {
12182
12232
  async listWorkspaces() {
12183
12233
  const rows = db.select().from(workspaces).all();
12184
- return rows.map(mapWorkspaceRow);
12234
+ return rows.map(mapWorkspaceRow).sort(compareWorkspaces);
12185
12235
  },
12186
12236
  async getWorkspace(id) {
12187
12237
  const row = db.select().from(workspaces).where(eq(workspaces.id, id)).get();
@@ -12291,6 +12341,15 @@ function createRegistryRepository() {
12291
12341
  async deleteWorkspace(id) {
12292
12342
  db.delete(workspaces).where(eq(workspaces.id, id)).run();
12293
12343
  },
12344
+ async setPinned(id, pinned) {
12345
+ if (pinned) {
12346
+ const maxRow = native.prepare("SELECT MAX(pin_order) AS max_order FROM workspaces WHERE pin_order IS NOT NULL").get();
12347
+ const nextOrder = (maxRow?.max_order ?? 0) + 1;
12348
+ native.prepare("UPDATE workspaces SET pinned_at = ?, pin_order = ? WHERE id = ?").run((/* @__PURE__ */ new Date()).toISOString(), nextOrder, id);
12349
+ } else {
12350
+ native.prepare("UPDATE workspaces SET pinned_at = NULL, pin_order = NULL WHERE id = ?").run(id);
12351
+ }
12352
+ },
12294
12353
  async getSetting(key) {
12295
12354
  const row = native.prepare("SELECT value FROM settings WHERE key = ?").get(key);
12296
12355
  if (!row) return null;
@@ -12348,10 +12407,23 @@ function mapWorkspaceRow(row) {
12348
12407
  nodeCount: row.nodeCount,
12349
12408
  edgeCount: row.edgeCount,
12350
12409
  lastError: row.lastError ?? void 0,
12410
+ pinnedAt: row.pinnedAt ?? void 0,
12411
+ pinOrder: row.pinOrder ?? void 0,
12351
12412
  createdAt: row.createdAt,
12352
12413
  updatedAt: row.updatedAt
12353
12414
  };
12354
12415
  }
12416
+ function compareWorkspaces(a, b) {
12417
+ if (a.pinnedAt && !b.pinnedAt) return -1;
12418
+ if (!a.pinnedAt && b.pinnedAt) return 1;
12419
+ if (a.pinnedAt && b.pinnedAt) {
12420
+ const aOrder = a.pinOrder ?? -Infinity;
12421
+ const bOrder = b.pinOrder ?? -Infinity;
12422
+ if (aOrder !== bOrder) return bOrder - aOrder;
12423
+ if (a.pinnedAt !== b.pinnedAt) return b.pinnedAt.localeCompare(a.pinnedAt);
12424
+ }
12425
+ return b.createdAt.localeCompare(a.createdAt);
12426
+ }
12355
12427
  function getNativeWorkspaceDb(rootPath) {
12356
12428
  const db = getWorkspaceDb(rootPath);
12357
12429
  const native = db.$client;
@@ -13223,6 +13295,93 @@ var init_local_workspace = __esm({
13223
13295
  }
13224
13296
  });
13225
13297
 
13298
+ // ../../packages/db/src/sqlite/remove-workspace.ts
13299
+ async function pathExists(target) {
13300
+ try {
13301
+ await import_promises5.default.stat(target);
13302
+ return true;
13303
+ } catch (err) {
13304
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
13305
+ return false;
13306
+ }
13307
+ throw err;
13308
+ }
13309
+ }
13310
+ async function removeWorkspace(selector) {
13311
+ const repo = createRegistryRepository();
13312
+ const workspace = selector.id ? await repo.getWorkspace(selector.id) : selector.rootPath ? await repo.getWorkspaceByPath(selector.rootPath) : null;
13313
+ if (!workspace) return null;
13314
+ const warnings = [];
13315
+ if (workspace.indexingStatus === "running" || workspace.graphStatus === "running") {
13316
+ warnings.push(
13317
+ "Workspace appears to be indexing or building its graph; stop the process first to avoid stale writes."
13318
+ );
13319
+ }
13320
+ const dataDirPath = getLocalWorkspaceDir(workspace.rootPath);
13321
+ let dataDirRemoved = false;
13322
+ let rootPathExists = null;
13323
+ try {
13324
+ rootPathExists = await pathExists(workspace.rootPath);
13325
+ if (!rootPathExists) {
13326
+ warnings.push(`Workspace root path does not exist on disk: ${workspace.rootPath}`);
13327
+ } else {
13328
+ closeWorkspaceDb(workspace.rootPath);
13329
+ try {
13330
+ await import_promises5.default.rm(dataDirPath, { recursive: true, force: true });
13331
+ dataDirRemoved = !await pathExists(dataDirPath);
13332
+ } catch (err) {
13333
+ dataDirRemoved = false;
13334
+ warnings.push(
13335
+ `Failed to delete ${dataDirPath}: ${err instanceof Error ? err.message : String(err)}`
13336
+ );
13337
+ }
13338
+ }
13339
+ } catch (err) {
13340
+ warnings.push(
13341
+ `Could not check workspace root path ${workspace.rootPath}: ${err instanceof Error ? err.message : String(err)}`
13342
+ );
13343
+ }
13344
+ let unregistered = false;
13345
+ let rootPathAbsent = false;
13346
+ if (rootPathExists === false) {
13347
+ rootPathAbsent = true;
13348
+ } else if (rootPathExists === true) {
13349
+ try {
13350
+ rootPathAbsent = !await pathExists(workspace.rootPath);
13351
+ } catch (err) {
13352
+ warnings.push(
13353
+ `Could not re-check workspace root path ${workspace.rootPath}: ${err instanceof Error ? err.message : String(err)}`
13354
+ );
13355
+ }
13356
+ }
13357
+ if (dataDirRemoved || rootPathAbsent) {
13358
+ await repo.deleteWorkspace(workspace.id);
13359
+ unregistered = true;
13360
+ } else {
13361
+ warnings.push(
13362
+ "Workspace was not unregistered because the data directory could not be removed. Retry to attempt cleanup again."
13363
+ );
13364
+ }
13365
+ return {
13366
+ workspaceId: workspace.id,
13367
+ rootPath: workspace.rootPath,
13368
+ unregistered,
13369
+ dataDirRemoved,
13370
+ dataDirPath,
13371
+ warnings
13372
+ };
13373
+ }
13374
+ var import_promises5;
13375
+ var init_remove_workspace = __esm({
13376
+ "../../packages/db/src/sqlite/remove-workspace.ts"() {
13377
+ "use strict";
13378
+ import_promises5 = __toESM(require("fs/promises"), 1);
13379
+ init_local_workspace();
13380
+ init_repository();
13381
+ init_workspace_db();
13382
+ }
13383
+ });
13384
+
13226
13385
  // ../../packages/db/src/sqlite/index.ts
13227
13386
  var init_sqlite = __esm({
13228
13387
  "../../packages/db/src/sqlite/index.ts"() {
@@ -13232,6 +13391,7 @@ var init_sqlite = __esm({
13232
13391
  init_repository();
13233
13392
  init_secure_storage();
13234
13393
  init_local_workspace();
13394
+ init_remove_workspace();
13235
13395
  init_schema();
13236
13396
  }
13237
13397
  });
@@ -13316,7 +13476,7 @@ var require_package = __commonJS({
13316
13476
  var require_main = __commonJS({
13317
13477
  "../../node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js"(exports2, module4) {
13318
13478
  "use strict";
13319
- var fs22 = require("fs");
13479
+ var fs23 = require("fs");
13320
13480
  var path24 = require("path");
13321
13481
  var os9 = require("os");
13322
13482
  var crypto4 = require("crypto");
@@ -13425,7 +13585,7 @@ var require_main = __commonJS({
13425
13585
  if (options && options.path && options.path.length > 0) {
13426
13586
  if (Array.isArray(options.path)) {
13427
13587
  for (const filepath of options.path) {
13428
- if (fs22.existsSync(filepath)) {
13588
+ if (fs23.existsSync(filepath)) {
13429
13589
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
13430
13590
  }
13431
13591
  }
@@ -13435,7 +13595,7 @@ var require_main = __commonJS({
13435
13595
  } else {
13436
13596
  possibleVaultPath = path24.resolve(process.cwd(), ".env.vault");
13437
13597
  }
13438
- if (fs22.existsSync(possibleVaultPath)) {
13598
+ if (fs23.existsSync(possibleVaultPath)) {
13439
13599
  return possibleVaultPath;
13440
13600
  }
13441
13601
  return null;
@@ -13484,7 +13644,7 @@ var require_main = __commonJS({
13484
13644
  const parsedAll = {};
13485
13645
  for (const path25 of optionPaths) {
13486
13646
  try {
13487
- const parsed = DotenvModule.parse(fs22.readFileSync(path25, { encoding }));
13647
+ const parsed = DotenvModule.parse(fs23.readFileSync(path25, { encoding }));
13488
13648
  DotenvModule.populate(parsedAll, parsed, options);
13489
13649
  } catch (e) {
13490
13650
  if (debug) {
@@ -17826,7 +17986,7 @@ async function loadBrainConfig(startDir = process.cwd()) {
17826
17986
  retrieval: defaults3.retrieval
17827
17987
  };
17828
17988
  }
17829
- const source = await import_promises5.default.readFile(configFile, "utf8");
17989
+ const source = await import_promises6.default.readFile(configFile, "utf8");
17830
17990
  const sanitized = source.replace(/^import\s+type\s+.*$/gm, "").replace(/^import\s+.*$/gm, "").replace(/const\s+config\s*:\s*[^=]+=/m, "const config =").replace(/export default\s+/m, "const __default__ = ");
17831
17991
  const evaluator = new Function(
17832
17992
  `${sanitized}
@@ -17854,11 +18014,11 @@ async function getBrainSettings(startDir = process.cwd()) {
17854
18014
  retrieval: config2.retrieval ?? defaults2.retrieval
17855
18015
  };
17856
18016
  }
17857
- var import_promises5, import_node_path9, import_node_fs7, CONFIG_FILE_CANDIDATES;
18017
+ var import_promises6, import_node_path9, import_node_fs7, CONFIG_FILE_CANDIDATES;
17858
18018
  var init_load_brain_config = __esm({
17859
18019
  "../../packages/config/src/load-brain-config.ts"() {
17860
18020
  "use strict";
17861
- import_promises5 = __toESM(require("fs/promises"), 1);
18021
+ import_promises6 = __toESM(require("fs/promises"), 1);
17862
18022
  import_node_path9 = __toESM(require("path"), 1);
17863
18023
  import_node_fs7 = require("fs");
17864
18024
  init_types2();
@@ -32635,11 +32795,11 @@ var require_source_map_support = __commonJS({
32635
32795
  "use strict";
32636
32796
  var SourceMapConsumer = require_source_map().SourceMapConsumer;
32637
32797
  var path24 = require("path");
32638
- var fs22;
32798
+ var fs23;
32639
32799
  try {
32640
- fs22 = require("fs");
32641
- if (!fs22.existsSync || !fs22.readFileSync) {
32642
- fs22 = null;
32800
+ fs23 = require("fs");
32801
+ if (!fs23.existsSync || !fs23.readFileSync) {
32802
+ fs23 = null;
32643
32803
  }
32644
32804
  } catch (err) {
32645
32805
  }
@@ -32710,7 +32870,7 @@ var require_source_map_support = __commonJS({
32710
32870
  }
32711
32871
  var contents = "";
32712
32872
  try {
32713
- if (!fs22) {
32873
+ if (!fs23) {
32714
32874
  var xhr = new XMLHttpRequest();
32715
32875
  xhr.open(
32716
32876
  "GET",
@@ -32722,8 +32882,8 @@ var require_source_map_support = __commonJS({
32722
32882
  if (xhr.readyState === 4 && xhr.status === 200) {
32723
32883
  contents = xhr.responseText;
32724
32884
  }
32725
- } else if (fs22.existsSync(path25)) {
32726
- contents = fs22.readFileSync(path25, "utf8");
32885
+ } else if (fs23.existsSync(path25)) {
32886
+ contents = fs23.readFileSync(path25, "utf8");
32727
32887
  }
32728
32888
  } catch (er) {
32729
32889
  }
@@ -32987,9 +33147,9 @@ var require_source_map_support = __commonJS({
32987
33147
  var line = +match2[2];
32988
33148
  var column = +match2[3];
32989
33149
  var contents = fileContentsCache[source];
32990
- if (!contents && fs22 && fs22.existsSync(source)) {
33150
+ if (!contents && fs23 && fs23.existsSync(source)) {
32991
33151
  try {
32992
- contents = fs22.readFileSync(source, "utf8");
33152
+ contents = fs23.readFileSync(source, "utf8");
32993
33153
  } catch (er) {
32994
33154
  contents = "";
32995
33155
  }
@@ -36761,10 +36921,10 @@ var require_typescript = __commonJS({
36761
36921
  function and2(f, g2) {
36762
36922
  return (arg) => f(arg) && g2(arg);
36763
36923
  }
36764
- function or2(...fs22) {
36924
+ function or2(...fs23) {
36765
36925
  return (...args) => {
36766
36926
  let lastResult;
36767
- for (const f of fs22) {
36927
+ for (const f of fs23) {
36768
36928
  lastResult = f(...args);
36769
36929
  if (lastResult) {
36770
36930
  return lastResult;
@@ -38339,7 +38499,7 @@ ${lanes.join("\n")}
38339
38499
  var tracing;
38340
38500
  var tracingEnabled;
38341
38501
  ((tracingEnabled2) => {
38342
- let fs22;
38502
+ let fs23;
38343
38503
  let traceCount = 0;
38344
38504
  let traceFd = 0;
38345
38505
  let mode;
@@ -38348,9 +38508,9 @@ ${lanes.join("\n")}
38348
38508
  const legend = [];
38349
38509
  function startTracing2(tracingMode, traceDir, configFilePath) {
38350
38510
  Debug.assert(!tracing, "Tracing already started");
38351
- if (fs22 === void 0) {
38511
+ if (fs23 === void 0) {
38352
38512
  try {
38353
- fs22 = require("fs");
38513
+ fs23 = require("fs");
38354
38514
  } catch (e) {
38355
38515
  throw new Error(`tracing requires having fs
38356
38516
  (original error: ${e.message || e})`);
@@ -38361,8 +38521,8 @@ ${lanes.join("\n")}
38361
38521
  if (legendPath === void 0) {
38362
38522
  legendPath = combinePaths(traceDir, "legend.json");
38363
38523
  }
38364
- if (!fs22.existsSync(traceDir)) {
38365
- fs22.mkdirSync(traceDir, { recursive: true });
38524
+ if (!fs23.existsSync(traceDir)) {
38525
+ fs23.mkdirSync(traceDir, { recursive: true });
38366
38526
  }
38367
38527
  const countPart = mode === "build" ? `.${process.pid}-${++traceCount}` : mode === "server" ? `.${process.pid}` : ``;
38368
38528
  const tracePath = combinePaths(traceDir, `trace${countPart}.json`);
@@ -38372,10 +38532,10 @@ ${lanes.join("\n")}
38372
38532
  tracePath,
38373
38533
  typesPath
38374
38534
  });
38375
- traceFd = fs22.openSync(tracePath, "w");
38535
+ traceFd = fs23.openSync(tracePath, "w");
38376
38536
  tracing = tracingEnabled2;
38377
38537
  const meta = { cat: "__metadata", ph: "M", ts: 1e3 * timestamp(), pid: 1, tid: 1 };
38378
- fs22.writeSync(
38538
+ fs23.writeSync(
38379
38539
  traceFd,
38380
38540
  "[\n" + [{ name: "process_name", args: { name: "tsc" }, ...meta }, { name: "thread_name", args: { name: "Main" }, ...meta }, { name: "TracingStartedInBrowser", ...meta, cat: "disabled-by-default-devtools.timeline" }].map((v) => JSON.stringify(v)).join(",\n")
38381
38541
  );
@@ -38384,10 +38544,10 @@ ${lanes.join("\n")}
38384
38544
  function stopTracing() {
38385
38545
  Debug.assert(tracing, "Tracing is not in progress");
38386
38546
  Debug.assert(!!typeCatalog.length === (mode !== "server"));
38387
- fs22.writeSync(traceFd, `
38547
+ fs23.writeSync(traceFd, `
38388
38548
  ]
38389
38549
  `);
38390
- fs22.closeSync(traceFd);
38550
+ fs23.closeSync(traceFd);
38391
38551
  tracing = void 0;
38392
38552
  if (typeCatalog.length) {
38393
38553
  dumpTypes(typeCatalog);
@@ -38459,11 +38619,11 @@ ${lanes.join("\n")}
38459
38619
  function writeEvent(eventType, phase, name, args, extras, time3 = 1e3 * timestamp()) {
38460
38620
  if (mode === "server" && phase === "checkTypes") return;
38461
38621
  mark("beginTracing");
38462
- fs22.writeSync(traceFd, `,
38622
+ fs23.writeSync(traceFd, `,
38463
38623
  {"pid":1,"tid":1,"ph":"${eventType}","cat":"${phase}","ts":${time3},"name":"${name}"`);
38464
- if (extras) fs22.writeSync(traceFd, `,${extras}`);
38465
- if (args) fs22.writeSync(traceFd, `,"args":${JSON.stringify(args)}`);
38466
- fs22.writeSync(traceFd, `}`);
38624
+ if (extras) fs23.writeSync(traceFd, `,${extras}`);
38625
+ if (args) fs23.writeSync(traceFd, `,"args":${JSON.stringify(args)}`);
38626
+ fs23.writeSync(traceFd, `}`);
38467
38627
  mark("endTracing");
38468
38628
  measure("Tracing", "beginTracing", "endTracing");
38469
38629
  }
@@ -38485,9 +38645,9 @@ ${lanes.join("\n")}
38485
38645
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
38486
38646
  mark("beginDumpTypes");
38487
38647
  const typesPath = legend[legend.length - 1].typesPath;
38488
- const typesFd = fs22.openSync(typesPath, "w");
38648
+ const typesFd = fs23.openSync(typesPath, "w");
38489
38649
  const recursionIdentityMap = /* @__PURE__ */ new Map();
38490
- fs22.writeSync(typesFd, "[");
38650
+ fs23.writeSync(typesFd, "[");
38491
38651
  const numTypes = types.length;
38492
38652
  for (let i = 0; i < numTypes; i++) {
38493
38653
  const type = types[i];
@@ -38583,13 +38743,13 @@ ${lanes.join("\n")}
38583
38743
  flags: Debug.formatTypeFlags(type.flags).split("|"),
38584
38744
  display
38585
38745
  };
38586
- fs22.writeSync(typesFd, JSON.stringify(descriptor));
38746
+ fs23.writeSync(typesFd, JSON.stringify(descriptor));
38587
38747
  if (i < numTypes - 1) {
38588
- fs22.writeSync(typesFd, ",\n");
38748
+ fs23.writeSync(typesFd, ",\n");
38589
38749
  }
38590
38750
  }
38591
- fs22.writeSync(typesFd, "]\n");
38592
- fs22.closeSync(typesFd);
38751
+ fs23.writeSync(typesFd, "]\n");
38752
+ fs23.closeSync(typesFd);
38593
38753
  mark("endDumpTypes");
38594
38754
  measure("Dump types", "beginDumpTypes", "endDumpTypes");
38595
38755
  }
@@ -38597,7 +38757,7 @@ ${lanes.join("\n")}
38597
38757
  if (!legendPath) {
38598
38758
  return;
38599
38759
  }
38600
- fs22.writeFileSync(legendPath, JSON.stringify(legend));
38760
+ fs23.writeFileSync(legendPath, JSON.stringify(legend));
38601
38761
  }
38602
38762
  tracingEnabled2.dumpLegend = dumpLegend;
38603
38763
  })(tracingEnabled || (tracingEnabled = {}));
@@ -248718,7 +248878,7 @@ var require_dist = __commonJS({
248718
248878
  enumerable: true
248719
248879
  }) : target, mod));
248720
248880
  var path24 = __toESM2(require("path"));
248721
- var fs22 = __toESM2(require("fs"));
248881
+ var fs23 = __toESM2(require("fs"));
248722
248882
  function cleanPath(path$1) {
248723
248883
  let normalized = (0, path24.normalize)(path$1);
248724
248884
  if (normalized.length > 1 && normalized[normalized.length - 1] === path24.sep) normalized = normalized.substring(0, normalized.length - 1);
@@ -249015,7 +249175,7 @@ var require_dist = __commonJS({
249015
249175
  symlinks: /* @__PURE__ */ new Map(),
249016
249176
  visited: [""].slice(0, 0),
249017
249177
  controller: new Aborter(),
249018
- fs: options.fs || fs22
249178
+ fs: options.fs || fs23
249019
249179
  };
249020
249180
  this.joinPath = build$7(this.root, options);
249021
249181
  this.pushDirectory = build$6(this.root, options);
@@ -249251,7 +249411,7 @@ var require_dist2 = __commonJS({
249251
249411
  value: mod,
249252
249412
  enumerable: true
249253
249413
  }) : target, mod));
249254
- var fs22 = require("fs");
249414
+ var fs23 = require("fs");
249255
249415
  var path24 = require("path");
249256
249416
  var url = require("url");
249257
249417
  var fdir = require_dist();
@@ -249499,12 +249659,12 @@ var require_dist2 = __commonJS({
249499
249659
  opts.cwd = (opts.cwd instanceof URL ? (0, url.fileURLToPath)(opts.cwd) : (0, path24.resolve)(opts.cwd)).replace(BACKSLASHES, "/");
249500
249660
  opts.ignore = ensureStringArray(opts.ignore);
249501
249661
  opts.fs && (opts.fs = {
249502
- readdir: opts.fs.readdir || fs22.readdir,
249503
- readdirSync: opts.fs.readdirSync || fs22.readdirSync,
249504
- realpath: opts.fs.realpath || fs22.realpath,
249505
- realpathSync: opts.fs.realpathSync || fs22.realpathSync,
249506
- stat: opts.fs.stat || fs22.stat,
249507
- statSync: opts.fs.statSync || fs22.statSync
249662
+ readdir: opts.fs.readdir || fs23.readdir,
249663
+ readdirSync: opts.fs.readdirSync || fs23.readdirSync,
249664
+ realpath: opts.fs.realpath || fs23.realpath,
249665
+ realpathSync: opts.fs.realpathSync || fs23.realpathSync,
249666
+ stat: opts.fs.stat || fs23.stat,
249667
+ statSync: opts.fs.statSync || fs23.statSync
249508
249668
  });
249509
249669
  if (opts.debug) log("globbing with options:", opts);
249510
249670
  return opts;
@@ -251435,30 +251595,30 @@ ${nodeLocation}` : message;
251435
251595
  yield path25;
251436
251596
  }
251437
251597
  }
251438
- var fs22 = runtime.fs;
251598
+ var fs23 = runtime.fs;
251439
251599
  var RealFileSystemHost = class {
251440
251600
  async delete(path25) {
251441
251601
  try {
251442
- await fs22.delete(path25);
251602
+ await fs23.delete(path25);
251443
251603
  } catch (err) {
251444
251604
  throw this.#getFileNotFoundErrorIfNecessary(err, path25);
251445
251605
  }
251446
251606
  }
251447
251607
  deleteSync(path25) {
251448
251608
  try {
251449
- fs22.deleteSync(path25);
251609
+ fs23.deleteSync(path25);
251450
251610
  } catch (err) {
251451
251611
  throw this.#getFileNotFoundErrorIfNecessary(err, path25);
251452
251612
  }
251453
251613
  }
251454
251614
  readDirSync(dirPath) {
251455
251615
  try {
251456
- const entries = fs22.readDirSync(dirPath);
251616
+ const entries = fs23.readDirSync(dirPath);
251457
251617
  for (const entry of entries) {
251458
251618
  entry.name = FileUtils.pathJoin(dirPath, entry.name);
251459
251619
  if (entry.isSymlink) {
251460
251620
  try {
251461
- const info = fs22.statSync(entry.name);
251621
+ const info = fs23.statSync(entry.name);
251462
251622
  if (info != null) {
251463
251623
  entry.isDirectory = info.isDirectory();
251464
251624
  entry.isFile = info.isFile();
@@ -251474,84 +251634,84 @@ ${nodeLocation}` : message;
251474
251634
  }
251475
251635
  async readFile(filePath, encoding = "utf-8") {
251476
251636
  try {
251477
- return await fs22.readFile(filePath, encoding);
251637
+ return await fs23.readFile(filePath, encoding);
251478
251638
  } catch (err) {
251479
251639
  throw this.#getFileNotFoundErrorIfNecessary(err, filePath);
251480
251640
  }
251481
251641
  }
251482
251642
  readFileSync(filePath, encoding = "utf-8") {
251483
251643
  try {
251484
- return fs22.readFileSync(filePath, encoding);
251644
+ return fs23.readFileSync(filePath, encoding);
251485
251645
  } catch (err) {
251486
251646
  throw this.#getFileNotFoundErrorIfNecessary(err, filePath);
251487
251647
  }
251488
251648
  }
251489
251649
  async writeFile(filePath, fileText) {
251490
- return fs22.writeFile(filePath, fileText);
251650
+ return fs23.writeFile(filePath, fileText);
251491
251651
  }
251492
251652
  writeFileSync(filePath, fileText) {
251493
- fs22.writeFileSync(filePath, fileText);
251653
+ fs23.writeFileSync(filePath, fileText);
251494
251654
  }
251495
251655
  mkdir(dirPath) {
251496
- return fs22.mkdir(dirPath);
251656
+ return fs23.mkdir(dirPath);
251497
251657
  }
251498
251658
  mkdirSync(dirPath) {
251499
- fs22.mkdirSync(dirPath);
251659
+ fs23.mkdirSync(dirPath);
251500
251660
  }
251501
251661
  move(srcPath, destPath) {
251502
- return fs22.move(srcPath, destPath);
251662
+ return fs23.move(srcPath, destPath);
251503
251663
  }
251504
251664
  moveSync(srcPath, destPath) {
251505
- fs22.moveSync(srcPath, destPath);
251665
+ fs23.moveSync(srcPath, destPath);
251506
251666
  }
251507
251667
  copy(srcPath, destPath) {
251508
- return fs22.copy(srcPath, destPath);
251668
+ return fs23.copy(srcPath, destPath);
251509
251669
  }
251510
251670
  copySync(srcPath, destPath) {
251511
- fs22.copySync(srcPath, destPath);
251671
+ fs23.copySync(srcPath, destPath);
251512
251672
  }
251513
251673
  async fileExists(filePath) {
251514
251674
  try {
251515
- return (await fs22.stat(filePath))?.isFile() ?? false;
251675
+ return (await fs23.stat(filePath))?.isFile() ?? false;
251516
251676
  } catch {
251517
251677
  return false;
251518
251678
  }
251519
251679
  }
251520
251680
  fileExistsSync(filePath) {
251521
251681
  try {
251522
- return fs22.statSync(filePath)?.isFile() ?? false;
251682
+ return fs23.statSync(filePath)?.isFile() ?? false;
251523
251683
  } catch {
251524
251684
  return false;
251525
251685
  }
251526
251686
  }
251527
251687
  async directoryExists(dirPath) {
251528
251688
  try {
251529
- return (await fs22.stat(dirPath))?.isDirectory() ?? false;
251689
+ return (await fs23.stat(dirPath))?.isDirectory() ?? false;
251530
251690
  } catch {
251531
251691
  return false;
251532
251692
  }
251533
251693
  }
251534
251694
  directoryExistsSync(dirPath) {
251535
251695
  try {
251536
- return fs22.statSync(dirPath)?.isDirectory() ?? false;
251696
+ return fs23.statSync(dirPath)?.isDirectory() ?? false;
251537
251697
  } catch {
251538
251698
  return false;
251539
251699
  }
251540
251700
  }
251541
251701
  realpathSync(path25) {
251542
- return fs22.realpathSync(path25);
251702
+ return fs23.realpathSync(path25);
251543
251703
  }
251544
251704
  getCurrentDirectory() {
251545
- return FileUtils.standardizeSlashes(fs22.getCurrentDirectory());
251705
+ return FileUtils.standardizeSlashes(fs23.getCurrentDirectory());
251546
251706
  }
251547
251707
  glob(patterns) {
251548
- return fs22.glob(backSlashesToForward(patterns));
251708
+ return fs23.glob(backSlashesToForward(patterns));
251549
251709
  }
251550
251710
  globSync(patterns) {
251551
- return fs22.globSync(backSlashesToForward(patterns));
251711
+ return fs23.globSync(backSlashesToForward(patterns));
251552
251712
  }
251553
251713
  isCaseSensitive() {
251554
- return fs22.isCaseSensitive();
251714
+ return fs23.isCaseSensitive();
251555
251715
  }
251556
251716
  #getDirectoryNotFoundErrorIfNecessary(err, path25) {
251557
251717
  return FileUtils.isNotExistsError(err) ? new exports2.errors.DirectoryNotFoundError(FileUtils.getStandardizedAbsolutePath(this, path25)) : err;
@@ -278658,8 +278818,8 @@ var require_utils4 = __commonJS({
278658
278818
  exports2.array = array2;
278659
278819
  var errno = require_errno();
278660
278820
  exports2.errno = errno;
278661
- var fs22 = require_fs();
278662
- exports2.fs = fs22;
278821
+ var fs23 = require_fs();
278822
+ exports2.fs = fs23;
278663
278823
  var path24 = require_path();
278664
278824
  exports2.path = path24;
278665
278825
  var pattern = require_pattern();
@@ -278843,12 +279003,12 @@ var require_fs2 = __commonJS({
278843
279003
  "use strict";
278844
279004
  Object.defineProperty(exports2, "__esModule", { value: true });
278845
279005
  exports2.createFileSystemAdapter = exports2.FILE_SYSTEM_ADAPTER = void 0;
278846
- var fs22 = require("fs");
279006
+ var fs23 = require("fs");
278847
279007
  exports2.FILE_SYSTEM_ADAPTER = {
278848
- lstat: fs22.lstat,
278849
- stat: fs22.stat,
278850
- lstatSync: fs22.lstatSync,
278851
- statSync: fs22.statSync
279008
+ lstat: fs23.lstat,
279009
+ stat: fs23.stat,
279010
+ lstatSync: fs23.lstatSync,
279011
+ statSync: fs23.statSync
278852
279012
  };
278853
279013
  function createFileSystemAdapter(fsMethods) {
278854
279014
  if (fsMethods === void 0) {
@@ -278865,12 +279025,12 @@ var require_settings = __commonJS({
278865
279025
  "../../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/settings.js"(exports2) {
278866
279026
  "use strict";
278867
279027
  Object.defineProperty(exports2, "__esModule", { value: true });
278868
- var fs22 = require_fs2();
279028
+ var fs23 = require_fs2();
278869
279029
  var Settings = class {
278870
279030
  constructor(_options = {}) {
278871
279031
  this._options = _options;
278872
279032
  this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true);
278873
- this.fs = fs22.createFileSystemAdapter(this._options.fs);
279033
+ this.fs = fs23.createFileSystemAdapter(this._options.fs);
278874
279034
  this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false);
278875
279035
  this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
278876
279036
  }
@@ -279027,8 +279187,8 @@ var require_utils5 = __commonJS({
279027
279187
  "use strict";
279028
279188
  Object.defineProperty(exports2, "__esModule", { value: true });
279029
279189
  exports2.fs = void 0;
279030
- var fs22 = require_fs3();
279031
- exports2.fs = fs22;
279190
+ var fs23 = require_fs3();
279191
+ exports2.fs = fs23;
279032
279192
  }
279033
279193
  });
279034
279194
 
@@ -279223,14 +279383,14 @@ var require_fs4 = __commonJS({
279223
279383
  "use strict";
279224
279384
  Object.defineProperty(exports2, "__esModule", { value: true });
279225
279385
  exports2.createFileSystemAdapter = exports2.FILE_SYSTEM_ADAPTER = void 0;
279226
- var fs22 = require("fs");
279386
+ var fs23 = require("fs");
279227
279387
  exports2.FILE_SYSTEM_ADAPTER = {
279228
- lstat: fs22.lstat,
279229
- stat: fs22.stat,
279230
- lstatSync: fs22.lstatSync,
279231
- statSync: fs22.statSync,
279232
- readdir: fs22.readdir,
279233
- readdirSync: fs22.readdirSync
279388
+ lstat: fs23.lstat,
279389
+ stat: fs23.stat,
279390
+ lstatSync: fs23.lstatSync,
279391
+ statSync: fs23.statSync,
279392
+ readdir: fs23.readdir,
279393
+ readdirSync: fs23.readdirSync
279234
279394
  };
279235
279395
  function createFileSystemAdapter(fsMethods) {
279236
279396
  if (fsMethods === void 0) {
@@ -279249,12 +279409,12 @@ var require_settings2 = __commonJS({
279249
279409
  Object.defineProperty(exports2, "__esModule", { value: true });
279250
279410
  var path24 = require("path");
279251
279411
  var fsStat = require_out();
279252
- var fs22 = require_fs4();
279412
+ var fs23 = require_fs4();
279253
279413
  var Settings = class {
279254
279414
  constructor(_options = {}) {
279255
279415
  this._options = _options;
279256
279416
  this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false);
279257
- this.fs = fs22.createFileSystemAdapter(this._options.fs);
279417
+ this.fs = fs23.createFileSystemAdapter(this._options.fs);
279258
279418
  this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path24.sep);
279259
279419
  this.stats = this._getValue(this._options.stats, false);
279260
279420
  this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
@@ -280635,16 +280795,16 @@ var require_settings4 = __commonJS({
280635
280795
  "use strict";
280636
280796
  Object.defineProperty(exports2, "__esModule", { value: true });
280637
280797
  exports2.DEFAULT_FILE_SYSTEM_ADAPTER = void 0;
280638
- var fs22 = require("fs");
280798
+ var fs23 = require("fs");
280639
280799
  var os9 = require("os");
280640
280800
  var CPU_COUNT = Math.max(os9.cpus().length, 1);
280641
280801
  exports2.DEFAULT_FILE_SYSTEM_ADAPTER = {
280642
- lstat: fs22.lstat,
280643
- lstatSync: fs22.lstatSync,
280644
- stat: fs22.stat,
280645
- statSync: fs22.statSync,
280646
- readdir: fs22.readdir,
280647
- readdirSync: fs22.readdirSync
280802
+ lstat: fs23.lstat,
280803
+ lstatSync: fs23.lstatSync,
280804
+ stat: fs23.stat,
280805
+ statSync: fs23.statSync,
280806
+ readdir: fs23.readdir,
280807
+ readdirSync: fs23.readdirSync
280648
280808
  };
280649
280809
  var Settings = class {
280650
280810
  constructor(_options = {}) {
@@ -280828,7 +280988,7 @@ async function scanWorkspaceFiles(input) {
280828
280988
  });
280829
280989
  const results = await Promise.all(
280830
280990
  entries.map(async (absolutePath) => {
280831
- const stat4 = await import_promises6.default.stat(absolutePath);
280991
+ const stat4 = await import_promises7.default.stat(absolutePath);
280832
280992
  return {
280833
280993
  absolutePath,
280834
280994
  relativePath: import_node_path13.default.relative(rootPath, absolutePath),
@@ -280839,12 +280999,12 @@ async function scanWorkspaceFiles(input) {
280839
280999
  );
280840
281000
  return results.sort((left, right) => left.relativePath.localeCompare(right.relativePath));
280841
281001
  }
280842
- var import_fast_glob, import_promises6, import_node_path13, import_node_fs10, DEFAULT_INCLUDE_PATTERNS, DEFAULT_EXCLUDE_PATTERNS;
281002
+ var import_fast_glob, import_promises7, import_node_path13, import_node_fs10, DEFAULT_INCLUDE_PATTERNS, DEFAULT_EXCLUDE_PATTERNS;
280843
281003
  var init_scanner = __esm({
280844
281004
  "../../packages/indexer/src/scanner.ts"() {
280845
281005
  "use strict";
280846
281006
  import_fast_glob = __toESM(require_out4(), 1);
280847
- import_promises6 = __toESM(require("fs/promises"), 1);
281007
+ import_promises7 = __toESM(require("fs/promises"), 1);
280848
281008
  import_node_path13 = __toESM(require("path"), 1);
280849
281009
  import_node_fs10 = require("fs");
280850
281010
  init_languages();
@@ -281099,7 +281259,9 @@ async function writeEmbeddingsToRepo(repo, chunkRows, provider) {
281099
281259
  for (let i = 0; i < toEmbed.length; i += BATCH_SIZE) {
281100
281260
  const batchNum = Math.floor(i / BATCH_SIZE) + 1;
281101
281261
  if (batchNum % 10 === 0 || batchNum === totalBatches) {
281102
- process.stdout.write(`\r[embedding] batch ${batchNum}/${totalBatches} (${totalWritten} written)`);
281262
+ process.stdout.write(
281263
+ `\r[embedding] batch ${batchNum}/${totalBatches} (${totalWritten} written)`
281264
+ );
281103
281265
  }
281104
281266
  const batch = toEmbed.slice(i, i + BATCH_SIZE);
281105
281267
  try {
@@ -281265,7 +281427,7 @@ async function indexWorkspace(input) {
281265
281427
  const i = readIndex++;
281266
281428
  fileContents.set(
281267
281429
  filesToRead[i].relativePath,
281268
- await import_promises7.default.readFile(filesToRead[i].absolutePath, "utf8")
281430
+ await import_promises8.default.readFile(filesToRead[i].absolutePath, "utf8")
281269
281431
  );
281270
281432
  }
281271
281433
  }
@@ -281462,9 +281624,7 @@ async function indexWorkspace(input) {
281462
281624
  reusedSymbolIds.add(newId);
281463
281625
  }
281464
281626
  for (const pending of pendingSymbolEdges) {
281465
- const newId = symbolNodeIdsByFileAndName.get(
281466
- `${file.relativePath}\0${pending.label}`
281467
- );
281627
+ const newId = symbolNodeIdsByFileAndName.get(`${file.relativePath}\0${pending.label}`);
281468
281628
  if (!newId) continue;
281469
281629
  edges[pending.definesEdgeIdx].toNodeId = newId;
281470
281630
  edges[pending.representedByEdgeIdx].fromNodeId = newId;
@@ -281662,11 +281822,11 @@ async function indexWorkspace(input) {
281662
281822
  embeddingFailures
281663
281823
  };
281664
281824
  }
281665
- var import_promises7, import_node_path14, RESOLVABLE_SOURCE_EXTENSIONS;
281825
+ var import_promises8, import_node_path14, RESOLVABLE_SOURCE_EXTENSIONS;
281666
281826
  var init_index_workspace = __esm({
281667
281827
  "../../packages/indexer/src/index-workspace.ts"() {
281668
281828
  "use strict";
281669
- import_promises7 = __toESM(require("fs/promises"), 1);
281829
+ import_promises8 = __toESM(require("fs/promises"), 1);
281670
281830
  import_node_path14 = __toESM(require("path"), 1);
281671
281831
  init_src2();
281672
281832
  init_src3();
@@ -295564,12 +295724,12 @@ var require_dist3 = __commonJS({
295564
295724
  throw new Error(`Unknown format "${name}"`);
295565
295725
  return f;
295566
295726
  };
295567
- function addFormats(ajv, list, fs22, exportName) {
295727
+ function addFormats(ajv, list, fs23, exportName) {
295568
295728
  var _a3;
295569
295729
  var _b;
295570
295730
  (_a3 = (_b = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
295571
295731
  for (const f of list)
295572
- ajv.addFormat(f, fs22[f]);
295732
+ ajv.addFormat(f, fs23[f]);
295573
295733
  }
295574
295734
  module4.exports = exports2 = formatsPlugin;
295575
295735
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -296762,6 +296922,19 @@ function createMcpServer(options) {
296762
296922
  },
296763
296923
  required: []
296764
296924
  }
296925
+ },
296926
+ {
296927
+ name: "remove_workspace",
296928
+ description: "Remove a workspace from the registry and delete its .openez data directory. Destructive and irreversible: call only with confirm: true after explicit user approval.",
296929
+ inputSchema: {
296930
+ type: "object",
296931
+ properties: {
296932
+ workspaceId: { type: "string" },
296933
+ path: { type: "string" },
296934
+ confirm: { type: "boolean" }
296935
+ },
296936
+ required: ["confirm"]
296937
+ }
296765
296938
  }
296766
296939
  ]
296767
296940
  }));
@@ -296935,6 +297108,34 @@ ${result.answerContext}`
296935
297108
  const summary = await indexWorkspace({ workspaceId: workspace.id, mode: input.mode });
296936
297109
  return jsonResponse(summary);
296937
297110
  }
297111
+ case "remove_workspace": {
297112
+ const input = removeWorkspaceSchema.parse(request.params.arguments ?? {});
297113
+ if (input.confirm !== true) {
297114
+ return jsonResponse({
297115
+ error: "remove_workspace permanently deletes the registry entry and the workspace's .openez data directory. Requires confirm: true.",
297116
+ hint: "Ask the user for approval, then call remove_workspace again with confirm: true."
297117
+ });
297118
+ }
297119
+ if (input.workspaceId && input.path) {
297120
+ return jsonResponse({ error: "Pass either workspaceId or path, not both." });
297121
+ }
297122
+ if (!input.workspaceId && !input.path) {
297123
+ return jsonResponse({ error: "Pass an explicit workspaceId or path." });
297124
+ }
297125
+ const report = await removeWorkspace({
297126
+ id: input.workspaceId,
297127
+ rootPath: input.path ? import_node_path15.default.resolve(input.path) : void 0
297128
+ });
297129
+ if (!report) {
297130
+ return jsonResponse({
297131
+ error: "Workspace not found",
297132
+ workspaceId: input.workspaceId,
297133
+ path: input.path
297134
+ });
297135
+ }
297136
+ stopWatcherForWorkspace(report.workspaceId);
297137
+ return jsonResponse(report);
297138
+ }
296938
297139
  default:
296939
297140
  throw new Error(`Unknown tool: ${request.params.name}`);
296940
297141
  }
@@ -296973,15 +297174,18 @@ async function autoIndexAndSync(searchRoot) {
296973
297174
  if (!WATCH_ENABLED) {
296974
297175
  return;
296975
297176
  }
296976
- let debounceTimer = null;
297177
+ const debounceTimer = null;
296977
297178
  const watcher = esm_default.watch(resolvedRoot, {
296978
297179
  ignored: WATCH_IGNORE_PATTERNS,
296979
297180
  ignoreInitial: true,
296980
297181
  persistent: true
296981
297182
  });
297183
+ activeWatcher = { watcher, workspaceId: workspace.id, rootPath: resolvedRoot, debounceTimer };
296982
297184
  const triggerReindex = () => {
296983
- if (debounceTimer) clearTimeout(debounceTimer);
296984
- debounceTimer = setTimeout(async () => {
297185
+ const current = activeWatcher;
297186
+ if (!current) return;
297187
+ if (current.debounceTimer) clearTimeout(current.debounceTimer);
297188
+ current.debounceTimer = setTimeout(async () => {
296985
297189
  try {
296986
297190
  await indexWorkspace({ workspaceId: workspace.id, mode: "incremental" });
296987
297191
  } catch {
@@ -296996,9 +297200,17 @@ async function autoIndexAndSync(searchRoot) {
296996
297200
  `OpenEZ MCP auto-sync watcher disabled: ${error2 instanceof Error ? error2.message : String(error2)}`
296997
297201
  );
296998
297202
  void watcher.close();
297203
+ activeWatcher = null;
296999
297204
  });
297000
297205
  }
297001
- var import_node_fs11, import_node_path15, MIN_RESPONSE_TOKENS, codeQuerySchema, codeContextSchema, graphNeighborsSchema, memoryWriteSchema, memoryRecallSchema, indexWorkspaceSchema, MCP_CATCHUP_INTERVAL_MS, catchupState, WATCH_DEBOUNCE_MS, WATCH_ENABLED, WATCH_IGNORE_PATTERNS;
297206
+ function stopWatcherForWorkspace(workspaceId) {
297207
+ if (activeWatcher && activeWatcher.workspaceId === workspaceId) {
297208
+ if (activeWatcher.debounceTimer) clearTimeout(activeWatcher.debounceTimer);
297209
+ void activeWatcher.watcher.close();
297210
+ activeWatcher = null;
297211
+ }
297212
+ }
297213
+ var import_node_fs11, import_node_path15, MIN_RESPONSE_TOKENS, codeQuerySchema, codeContextSchema, graphNeighborsSchema, memoryWriteSchema, memoryRecallSchema, indexWorkspaceSchema, removeWorkspaceSchema, MCP_CATCHUP_INTERVAL_MS, catchupState, activeWatcher, WATCH_DEBOUNCE_MS, WATCH_ENABLED, WATCH_IGNORE_PATTERNS;
297002
297214
  var init_mcp_core = __esm({
297003
297215
  "../mcp/src/mcp-core.ts"() {
297004
297216
  "use strict";
@@ -297066,8 +297278,14 @@ var init_mcp_core = __esm({
297066
297278
  path: external_exports.string().optional(),
297067
297279
  mode: external_exports.enum(["incremental", "full"]).optional()
297068
297280
  });
297281
+ removeWorkspaceSchema = external_exports.object({
297282
+ workspaceId: external_exports.string().optional(),
297283
+ path: external_exports.string().optional(),
297284
+ confirm: external_exports.boolean().optional()
297285
+ });
297069
297286
  MCP_CATCHUP_INTERVAL_MS = Number(process.env.OPENEZ_MCP_CATCHUP_INTERVAL_MS ?? 5e3);
297070
297287
  catchupState = /* @__PURE__ */ new Map();
297288
+ activeWatcher = null;
297071
297289
  WATCH_DEBOUNCE_MS = 2e3;
297072
297290
  WATCH_ENABLED = ["1", "true", "yes"].includes(
297073
297291
  (process.env.OPENEZ_MCP_WATCH ?? "").toLowerCase()
@@ -297091,7 +297309,7 @@ __export(mcp_bridge_exports, {
297091
297309
  startMcpServer: () => startMcpServer
297092
297310
  });
297093
297311
  async function startMcpServer(defaultPath, version4) {
297094
- await createAndStartMcpServer({ defaultPath, version: version4, build: "ebc5064-dirty" });
297312
+ await createAndStartMcpServer({ defaultPath, version: version4, build: "56dde1b-dirty" });
297095
297313
  }
297096
297314
  var init_mcp_bridge = __esm({
297097
297315
  "src/mcp-bridge.ts"() {
@@ -301061,21 +301279,73 @@ function initializeRegistrySchema2(db) {
301061
301279
  node_count INTEGER NOT NULL DEFAULT 0,
301062
301280
  edge_count INTEGER NOT NULL DEFAULT 0,
301063
301281
  last_error TEXT,
301282
+ pinned_at TEXT,
301283
+ pin_order INTEGER,
301064
301284
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
301065
301285
  updated_at TEXT NOT NULL DEFAULT (datetime('now'))
301066
301286
  );
301067
301287
  CREATE UNIQUE INDEX IF NOT EXISTS idx_workspaces_root_path ON workspaces(root_path);
301068
301288
  `);
301289
+ migrateRegistryColumns2(db);
301290
+ }
301291
+ function migrateRegistryColumns2(db) {
301292
+ const getColumns = () => new Set(
301293
+ db.prepare("PRAGMA table_info(workspaces)").all().map(
301294
+ (row) => row.name
301295
+ )
301296
+ );
301297
+ const addColumnIfMissing = (name, definition) => {
301298
+ if (getColumns().has(name)) return;
301299
+ try {
301300
+ db.exec(`ALTER TABLE workspaces ADD COLUMN ${definition}`);
301301
+ } catch (err) {
301302
+ if (!getColumns().has(name)) {
301303
+ throw err;
301304
+ }
301305
+ }
301306
+ };
301307
+ addColumnIfMissing("pinned_at", "pinned_at TEXT");
301308
+ addColumnIfMissing("pin_order", "pin_order INTEGER");
301309
+ const unbackfilled = db.prepare(
301310
+ "SELECT id FROM workspaces WHERE pinned_at IS NOT NULL AND pin_order IS NULL ORDER BY pinned_at DESC"
301311
+ ).all();
301312
+ if (unbackfilled.length > 0) {
301313
+ const maxRow = db.prepare("SELECT MAX(pin_order) AS max_order FROM workspaces WHERE pin_order IS NOT NULL").get();
301314
+ let next = (maxRow?.max_order ?? 0) + 1;
301315
+ const stmt = db.prepare("UPDATE workspaces SET pin_order = ? WHERE id = ?");
301316
+ for (const row of unbackfilled) {
301317
+ stmt.run(next, row.id);
301318
+ next += 1;
301319
+ }
301320
+ }
301069
301321
  }
301070
301322
  function getRegistryDb2() {
301071
301323
  if (!registryDb2) {
301072
301324
  const dbPath = resolveRegistryDbPath2();
301073
301325
  ensureDirForFile(dbPath);
301074
- registryDb2 = openSqlite(dbPath);
301075
- initializeRegistrySchema2(registryDb2);
301326
+ const db = openSqlite(dbPath);
301327
+ try {
301328
+ initializeRegistrySchema2(db);
301329
+ registryDb2 = db;
301330
+ } catch (err) {
301331
+ db.close();
301332
+ registryDb2 = null;
301333
+ throw err;
301334
+ }
301076
301335
  }
301077
301336
  return registryDb2;
301078
301337
  }
301338
+ function closeWorkspaceDb2(rootPath) {
301339
+ const normalized = normalizeRootPath2(rootPath);
301340
+ const db = workspaceDbs.get(normalized);
301341
+ if (db) {
301342
+ try {
301343
+ db.close();
301344
+ } catch {
301345
+ }
301346
+ workspaceDbs.delete(normalized);
301347
+ }
301348
+ }
301079
301349
  function resolveWorkspaceDbPath(rootPath) {
301080
301350
  return import_node_path17.default.join(rootPath, ".openez", "index.sqlite");
301081
301351
  }
@@ -301241,12 +301511,16 @@ function mapWorkspace(row) {
301241
301511
  nodeCount: Number(row.node_count ?? 0),
301242
301512
  edgeCount: Number(row.edge_count ?? 0),
301243
301513
  lastError: row.last_error ? String(row.last_error) : void 0,
301514
+ pinnedAt: row.pinned_at ? String(row.pinned_at) : void 0,
301515
+ pinOrder: row.pin_order != null ? Number(row.pin_order) : void 0,
301244
301516
  createdAt: String(row.created_at),
301245
301517
  updatedAt: String(row.updated_at)
301246
301518
  };
301247
301519
  }
301248
301520
  function listRegistryWorkspaces() {
301249
- const rows = getRegistryDb2().prepare("SELECT * FROM workspaces ORDER BY created_at DESC").all();
301521
+ const rows = getRegistryDb2().prepare(
301522
+ "SELECT * FROM workspaces ORDER BY (pinned_at IS NULL), pin_order DESC, pinned_at DESC, created_at DESC"
301523
+ ).all();
301250
301524
  return rows.map(mapWorkspace);
301251
301525
  }
301252
301526
  function getRegistryWorkspace(id) {
@@ -301291,8 +301565,19 @@ function ensureRegistryWorkspace(input) {
301291
301565
  );
301292
301566
  return getRegistryWorkspace(nextId);
301293
301567
  }
301294
- function deleteRegistryWorkspace(id) {
301295
- getRegistryDb2().prepare("DELETE FROM workspaces WHERE id = ?").run(id);
301568
+ function setRegistryWorkspacePinned(id, pinned) {
301569
+ const db = getRegistryDb2();
301570
+ if (pinned) {
301571
+ const maxRow = db.prepare("SELECT MAX(pin_order) AS max_order FROM workspaces WHERE pin_order IS NOT NULL").get();
301572
+ const nextOrder = (maxRow?.max_order ?? 0) + 1;
301573
+ db.prepare("UPDATE workspaces SET pinned_at = ?, pin_order = ? WHERE id = ?").run(
301574
+ (/* @__PURE__ */ new Date()).toISOString(),
301575
+ nextOrder,
301576
+ id
301577
+ );
301578
+ } else {
301579
+ db.prepare("UPDATE workspaces SET pinned_at = NULL, pin_order = NULL WHERE id = ?").run(id);
301580
+ }
301296
301581
  }
301297
301582
  function mapRunRow(row, kind) {
301298
301583
  return {
@@ -301584,6 +301869,7 @@ function mapWorkspace2(ws) {
301584
301869
  nodeCount: ws.nodeCount,
301585
301870
  edgeCount: ws.edgeCount,
301586
301871
  lastError: ws.lastError ?? null,
301872
+ pinnedAt: ws.pinnedAt ?? null,
301587
301873
  createdAt: new Date(ws.createdAt),
301588
301874
  updatedAt: new Date(ws.updatedAt)
301589
301875
  };
@@ -301871,14 +302157,34 @@ var init_server3 = __esm({
301871
302157
  return c.json({ success: false, error: "Failed to create workspace" });
301872
302158
  }
301873
302159
  });
301874
- app.delete("/api/workspaces/:id", (c) => {
302160
+ app.delete("/api/workspaces/:id", async (c) => {
301875
302161
  try {
301876
302162
  const id = c.req.param("id");
301877
- deleteRegistryWorkspace(id);
301878
- return c.json({ success: true });
302163
+ const ws = getRegistryWorkspace(id);
302164
+ if (ws) closeWorkspaceDb2(ws.rootPath);
302165
+ const report = await removeWorkspace({ id });
302166
+ if (!report) return c.json({ success: false, error: "Workspace not found" }, 404);
302167
+ return c.json({ success: true, report });
301879
302168
  } catch (err) {
301880
302169
  console.error("Failed to delete workspace:", err);
301881
- return c.json({ success: false, error: "Failed to delete workspace" });
302170
+ return c.json({ success: false, error: "Failed to delete workspace" }, 500);
302171
+ }
302172
+ });
302173
+ app.patch("/api/workspaces/:id/pin", async (c) => {
302174
+ try {
302175
+ const id = c.req.param("id");
302176
+ const body = await c.req.json().catch(() => null);
302177
+ if (typeof body?.pinned !== "boolean") {
302178
+ return c.json({ success: false, error: "pinned (boolean) is required" }, 400);
302179
+ }
302180
+ if (!getRegistryWorkspace(id)) {
302181
+ return c.json({ success: false, error: "Workspace not found" }, 404);
302182
+ }
302183
+ setRegistryWorkspacePinned(id, body.pinned);
302184
+ return c.json({ success: true });
302185
+ } catch (err) {
302186
+ console.error("Failed to pin workspace:", err);
302187
+ return c.json({ success: false, error: "Failed to pin workspace" });
301882
302188
  }
301883
302189
  });
301884
302190
  app.get("/api/workspaces/:id/index", (c) => {
@@ -303490,6 +303796,7 @@ var init_setup_devin = __esm({
303490
303796
  // src/cli.ts
303491
303797
  var import_node_fs21 = __toESM(require("fs"), 1);
303492
303798
  var import_node_path25 = __toESM(require("path"), 1);
303799
+ var import_node_readline = __toESM(require("readline"), 1);
303493
303800
  init_esm2();
303494
303801
 
303495
303802
  // ../../node_modules/.pnpm/commander@14.0.3/node_modules/commander/esm.mjs
@@ -303710,10 +304017,62 @@ program2.command("list").description("List all registered workspaces").action(as
303710
304017
  console.log("Registered workspaces:");
303711
304018
  for (const workspace of workspaces2) {
303712
304019
  const statusIcon = workspace.status === "indexed" ? "\u2713" : workspace.status === "error" ? "\u2717" : "\u25CB";
303713
- console.log(` ${statusIcon} ${workspace.name} (${workspace.id})`);
304020
+ const pinMarker = workspace.pinnedAt ? " \u{1F4CC}" : "";
304021
+ console.log(` ${statusIcon}${pinMarker} ${workspace.name} (${workspace.id})`);
303714
304022
  console.log(` ${workspace.rootPath}`);
303715
304023
  }
303716
304024
  });
304025
+ function confirmDestructive(prompt) {
304026
+ if (!process.stdin.isTTY) return Promise.reject(new Error("Confirmation required; rerun with --yes."));
304027
+ const rl = import_node_readline.default.createInterface({ input: process.stdin, output: process.stdout });
304028
+ return new Promise((resolve4) => {
304029
+ rl.question(`${prompt} [y/N] `, (answer) => {
304030
+ rl.close();
304031
+ const normalized = answer.trim().toLowerCase();
304032
+ resolve4(normalized === "y" || normalized === "yes");
304033
+ });
304034
+ });
304035
+ }
304036
+ program2.command("remove").alias("rm").description("Remove a workspace from the registry and delete its .openez data directory").argument("[path]", "path to the workspace directory", process.cwd()).option("--id <workspaceId>", "workspace id (takes precedence over path)").option("-y, --yes", "skip confirmation prompt").action(async (targetPath, options) => {
304037
+ const registry2 = createRegistryRepository();
304038
+ const resolvedPath = import_node_path25.default.resolve(targetPath);
304039
+ const workspace = options.id ? await registry2.getWorkspace(options.id) : await registry2.getWorkspaceByPath(resolvedPath);
304040
+ if (!workspace) {
304041
+ console.error(`Error: no registered workspace found for ${options.id ?? resolvedPath}`);
304042
+ process.exit(1);
304043
+ }
304044
+ const dataDir = getLocalWorkspaceDir(workspace.rootPath);
304045
+ console.log(`Workspace: ${workspace.name} (${workspace.id})`);
304046
+ console.log(` Path: ${workspace.rootPath}`);
304047
+ console.log(` Data dir: ${dataDir}`);
304048
+ console.log(` Indexed: ${workspace.documentCount} docs, ${workspace.chunkCount} chunks`);
304049
+ console.log(
304050
+ "This removes the registry entry and deletes the data directory. Source code is not touched."
304051
+ );
304052
+ if (!options.yes) {
304053
+ const confirmed = await confirmDestructive("Proceed?");
304054
+ if (!confirmed) {
304055
+ console.log("Aborted.");
304056
+ return;
304057
+ }
304058
+ }
304059
+ const report = await removeWorkspace({ id: workspace.id });
304060
+ if (!report) {
304061
+ console.error(`Error: workspace '${workspace.id}' no longer exists in the registry.`);
304062
+ process.exit(1);
304063
+ }
304064
+ if (report.unregistered) {
304065
+ console.log(`\u2713 Unregistered workspace ${report.workspaceId}`);
304066
+ } else {
304067
+ console.log(`\u2717 Workspace ${report.workspaceId} could not be unregistered (see warnings)`);
304068
+ }
304069
+ if (report.dataDirRemoved) {
304070
+ console.log(`\u2713 Deleted ${report.dataDirPath}`);
304071
+ }
304072
+ for (const warning of report.warnings) {
304073
+ console.log(`! ${warning}`);
304074
+ }
304075
+ });
303717
304076
  var EMBEDDING_CONFIG_KEYS = [
303718
304077
  "embedding.provider",
303719
304078
  "embedding.openai_api_key",