@hasna/mcps 0.0.20 → 0.0.22

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/mcp/index.js CHANGED
@@ -3508,7 +3508,7 @@ class JSONSchemaGenerator {
3508
3508
  if (val === undefined) {
3509
3509
  if (this.unrepresentable === "throw") {
3510
3510
  throw new Error("Literal `undefined` cannot be represented in JSON Schema");
3511
- } else {}
3511
+ }
3512
3512
  } else if (typeof val === "bigint") {
3513
3513
  if (this.unrepresentable === "throw") {
3514
3514
  throw new Error("BigInt literals cannot be represented in JSON Schema");
@@ -5685,14 +5685,14 @@ import { join, relative } from "path";
5685
5685
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync, writeFileSync } from "fs";
5686
5686
  import { homedir as homedir2 } from "os";
5687
5687
  import { join as join2 } from "path";
5688
- import { readdirSync as readdirSync2, existsSync as existsSync3 } from "fs";
5689
- import { join as join3 } from "path";
5690
- import { homedir as homedir3 } from "os";
5688
+ import { readdirSync as readdirSync3, existsSync as existsSync6 } from "fs";
5689
+ import { join as join6 } from "path";
5690
+ import { homedir as homedir5 } from "os";
5691
5691
  import { hostname as hostname2 } from "os";
5692
- import { homedir as homedir4 } from "os";
5693
- import { join as join4 } from "path";
5694
- import { join as join6, dirname } from "path";
5695
- import { homedir as homedir5, platform } from "os";
5692
+ import { homedir as homedir3 } from "os";
5693
+ import { join as join3 } from "path";
5694
+ import { join as join5, dirname } from "path";
5695
+ import { homedir as homedir4, platform } from "os";
5696
5696
  function __accessProp2(key) {
5697
5697
  return this[key];
5698
5698
  }
@@ -6620,11 +6620,11 @@ function isSyncExcludedTable(table) {
6620
6620
  return SYNC_EXCLUDED_TABLE_PATTERNS.some((p) => p.test(table));
6621
6621
  }
6622
6622
  function discoverServices() {
6623
- const dataDir = join3(homedir3(), ".hasna");
6624
- if (!existsSync3(dataDir))
6623
+ const dataDir = join6(homedir5(), ".hasna");
6624
+ if (!existsSync6(dataDir))
6625
6625
  return [];
6626
6626
  try {
6627
- const entries = readdirSync2(dataDir, { withFileTypes: true });
6627
+ const entries = readdirSync3(dataDir, { withFileTypes: true });
6628
6628
  return entries.filter((e) => {
6629
6629
  if (!e.isDirectory())
6630
6630
  return false;
@@ -6636,30 +6636,30 @@ function discoverServices() {
6636
6636
  return [];
6637
6637
  }
6638
6638
  }
6639
- function discoverSyncableServices() {
6639
+ function discoverSyncableServices2() {
6640
6640
  const local = discoverServices();
6641
6641
  const pgSet = new Set(KNOWN_PG_SERVICES);
6642
6642
  return local.filter((s) => pgSet.has(s));
6643
6643
  }
6644
6644
  function getServiceDbPath(service) {
6645
- const dataDir = join3(homedir3(), ".hasna", service);
6646
- if (!existsSync3(dataDir))
6645
+ const dataDir = join6(homedir5(), ".hasna", service);
6646
+ if (!existsSync6(dataDir))
6647
6647
  return null;
6648
6648
  const candidates = [
6649
- join3(dataDir, `${service}.db`),
6650
- join3(dataDir, "data.db"),
6651
- join3(dataDir, "database.db")
6649
+ join6(dataDir, `${service}.db`),
6650
+ join6(dataDir, "data.db"),
6651
+ join6(dataDir, "database.db")
6652
6652
  ];
6653
6653
  try {
6654
- const files = readdirSync2(dataDir);
6654
+ const files = readdirSync3(dataDir);
6655
6655
  for (const f of files) {
6656
6656
  if (f.endsWith(".db") && !f.endsWith("-wal") && !f.endsWith("-shm")) {
6657
- candidates.push(join3(dataDir, f));
6657
+ candidates.push(join6(dataDir, f));
6658
6658
  }
6659
6659
  }
6660
6660
  } catch {}
6661
6661
  for (const p of candidates) {
6662
- if (existsSync3(p))
6662
+ if (existsSync6(p))
6663
6663
  return p;
6664
6664
  }
6665
6665
  return null;
@@ -6966,9 +6966,9 @@ async function syncTransfer(source, target, options, _direction) {
6966
6966
  const batch = rows.slice(offset, offset + batchSize);
6967
6967
  try {
6968
6968
  if (isAsyncAdapter(target)) {
6969
- await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
6969
+ await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch);
6970
6970
  } else {
6971
- batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
6971
+ batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch);
6972
6972
  }
6973
6973
  result.rowsWritten += batch.length;
6974
6974
  } catch (err) {
@@ -7015,7 +7015,7 @@ async function syncTransfer(source, target, options, _direction) {
7015
7015
  }
7016
7016
  return results;
7017
7017
  }
7018
- async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
7018
+ async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch) {
7019
7019
  if (batch.length === 0)
7020
7020
  return;
7021
7021
  const colList = columns.map((c) => `"${c}"`).join(", ");
@@ -7025,22 +7025,20 @@ async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, ba
7025
7025
  }).join(", ");
7026
7026
  const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
7027
7027
  const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
7028
- const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
7029
7028
  const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
7030
- ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
7029
+ ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
7031
7030
  const params = batch.flatMap((row) => columns.map((c) => row[c] ?? null));
7032
7031
  await target.run(sql, ...params);
7033
7032
  }
7034
- function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
7033
+ function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch) {
7035
7034
  if (batch.length === 0)
7036
7035
  return;
7037
7036
  const colList = columns.map((c) => `"${c}"`).join(", ");
7038
7037
  const valuePlaceholders = batch.map(() => `(${columns.map(() => "?").join(", ")})`).join(", ");
7039
7038
  const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
7040
7039
  const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
7041
- const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
7042
7040
  const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
7043
- ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
7041
+ ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
7044
7042
  const params = batch.flatMap((row) => columns.map((c) => coerceForSqlite(row[c])));
7045
7043
  target.run(sql, ...params);
7046
7044
  }
@@ -7265,7 +7263,7 @@ class SyncProgressTracker {
7265
7263
  }
7266
7264
  }
7267
7265
  }
7268
- function registerCloudTools(server, serviceName, opts = {}) {
7266
+ function registerCloudTools(server, serviceName) {
7269
7267
  server.tool(`${serviceName}_cloud_status`, "Show cloud configuration and connection health", {}, async () => {
7270
7268
  const config2 = getCloudConfig();
7271
7269
  const lines = [
@@ -7298,13 +7296,8 @@ function registerCloudTools(server, serviceName, opts = {}) {
7298
7296
  isError: true
7299
7297
  };
7300
7298
  }
7301
- const local = new SqliteAdapter(opts.dbPath ?? getDbPath(serviceName));
7299
+ const local = new SqliteAdapter(getDbPath(serviceName));
7302
7300
  const cloud = new PgAdapterAsync(getConnectionString(serviceName));
7303
- if (opts.migrations?.length) {
7304
- for (const sql of opts.migrations) {
7305
- await cloud.run(sql);
7306
- }
7307
- }
7308
7301
  const tableList = tablesStr ? tablesStr.split(",").map((t) => t.trim()) : listSqliteTables(local);
7309
7302
  const results = await syncPush(local, cloud, { tables: tableList });
7310
7303
  local.close();
@@ -7326,7 +7319,7 @@ function registerCloudTools(server, serviceName, opts = {}) {
7326
7319
  isError: true
7327
7320
  };
7328
7321
  }
7329
- const local = new SqliteAdapter(opts.dbPath ?? getDbPath(serviceName));
7322
+ const local = new SqliteAdapter(getDbPath(serviceName));
7330
7323
  const cloud = new PgAdapterAsync(getConnectionString(serviceName));
7331
7324
  let tableList;
7332
7325
  if (tablesStr) {
@@ -15631,7 +15624,7 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
15631
15624
  __export2(exports_discover, {
15632
15625
  isSyncExcludedTable: () => isSyncExcludedTable,
15633
15626
  getServiceDbPath: () => getServiceDbPath,
15634
- discoverSyncableServices: () => discoverSyncableServices,
15627
+ discoverSyncableServices: () => discoverSyncableServices2,
15635
15628
  discoverServices: () => discoverServices,
15636
15629
  SYNC_EXCLUDED_TABLE_PATTERNS: () => SYNC_EXCLUDED_TABLE_PATTERNS,
15637
15630
  KNOWN_PG_SERVICES: () => KNOWN_PG_SERVICES
@@ -15686,15 +15679,13 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
15686
15679
  init_config();
15687
15680
  init_config();
15688
15681
  init_dotfile();
15689
- init_adapter();
15690
15682
  init_config();
15691
- init_discover();
15692
- AUTO_SYNC_CONFIG_PATH = join4(homedir4(), ".hasna", "cloud", "config.json");
15683
+ AUTO_SYNC_CONFIG_PATH = join3(homedir3(), ".hasna", "cloud", "config.json");
15693
15684
  init_config();
15694
15685
  init_adapter();
15695
15686
  init_dotfile();
15696
15687
  init_config();
15697
- CONFIG_DIR2 = join6(homedir5(), ".hasna", "cloud");
15688
+ CONFIG_DIR2 = join5(homedir4(), ".hasna", "cloud");
15698
15689
  init_adapter();
15699
15690
  init_config();
15700
15691
  init_discover();
@@ -29935,18 +29926,18 @@ var init_mcp = __esm(() => {
29935
29926
  });
29936
29927
 
29937
29928
  // src/lib/version.ts
29938
- import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
29939
- import { dirname as dirname2, join as join5 } from "path";
29929
+ import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
29930
+ import { dirname as dirname2, join as join4 } from "path";
29940
29931
  import { fileURLToPath } from "url";
29941
29932
  function readPackageVersion(moduleUrl, fallback = FALLBACK_VERSION) {
29942
29933
  const baseDir = dirname2(fileURLToPath(moduleUrl));
29943
29934
  const candidates = [
29944
- join5(baseDir, "..", "..", "package.json"),
29945
- join5(baseDir, "..", "package.json"),
29946
- join5(baseDir, "package.json")
29935
+ join4(baseDir, "..", "..", "package.json"),
29936
+ join4(baseDir, "..", "package.json"),
29937
+ join4(baseDir, "package.json")
29947
29938
  ];
29948
29939
  for (const candidate of candidates) {
29949
- if (!existsSync4(candidate))
29940
+ if (!existsSync3(candidate))
29950
29941
  continue;
29951
29942
  try {
29952
29943
  const pkg = JSON.parse(readFileSync2(candidate, "utf-8"));
@@ -29962,14 +29953,14 @@ var init_version = () => {};
29962
29953
  // src/lib/config.ts
29963
29954
  import { join as join7 } from "path";
29964
29955
  import { homedir as homedir6 } from "os";
29965
- import { existsSync as existsSync6, mkdirSync as mkdirSync3, cpSync } from "fs";
29956
+ import { existsSync as existsSync5, mkdirSync as mkdirSync3, cpSync } from "fs";
29966
29957
  function resolveMcpsDir() {
29967
29958
  const explicit = process.env.HASNA_MCPS_DATA_DIR ?? process.env.MCPS_DATA_DIR;
29968
29959
  if (explicit)
29969
29960
  return explicit;
29970
29961
  const newDir = join7(homedir6(), ".hasna", "mcps");
29971
29962
  const oldDir = join7(homedir6(), ".mcps");
29972
- if (!existsSync6(newDir) && existsSync6(oldDir)) {
29963
+ if (!existsSync5(newDir) && existsSync5(oldDir)) {
29973
29964
  mkdirSync3(join7(homedir6(), ".hasna"), { recursive: true });
29974
29965
  cpSync(oldDir, newDir, { recursive: true });
29975
29966
  }
@@ -30595,7 +30586,7 @@ var init_db = __esm(() => {
30595
30586
 
30596
30587
  // src/lib/credentials.ts
30597
30588
  import { existsSync as existsSync7, readFileSync as readFileSync3 } from "fs";
30598
- import { join as join8 } from "path";
30589
+ import { join as join9 } from "path";
30599
30590
  function normalizeKey(key) {
30600
30591
  return key.trim();
30601
30592
  }
@@ -30669,7 +30660,7 @@ function normalizeLiteralEnv(env) {
30669
30660
  return normalized;
30670
30661
  }
30671
30662
  function readLocalVault() {
30672
- const path = process.env.HASNA_MCPS_CREDENTIAL_VAULT_PATH ?? join8(MCPS_DIR, "credentials.local.json");
30663
+ const path = process.env.HASNA_MCPS_CREDENTIAL_VAULT_PATH ?? join9(MCPS_DIR, "credentials.local.json");
30673
30664
  if (!existsSync7(path))
30674
30665
  return {};
30675
30666
  const parsed = JSON.parse(readFileSync3(path, "utf-8"));
@@ -31186,15 +31177,15 @@ __export(exports_sources, {
31186
31177
  clearCache: () => clearCache,
31187
31178
  addSource: () => addSource
31188
31179
  });
31189
- import { mkdirSync as mkdirSync6, existsSync as existsSync8, readFileSync as readFileSync4, writeFileSync as writeFileSync2, readdirSync as readdirSync3, unlinkSync } from "fs";
31190
- import { join as join9 } from "path";
31180
+ import { mkdirSync as mkdirSync6, existsSync as existsSync9, readFileSync as readFileSync4, writeFileSync as writeFileSync2, readdirSync as readdirSync2, unlinkSync } from "fs";
31181
+ import { join as join10 } from "path";
31191
31182
  function getCacheFile(sourceId) {
31192
- return join9(CACHE_DIR, `${sourceId}.json`);
31183
+ return join10(CACHE_DIR, `${sourceId}.json`);
31193
31184
  }
31194
31185
  function readCache(sourceId) {
31195
31186
  try {
31196
31187
  const file = getCacheFile(sourceId);
31197
- if (!existsSync8(file))
31188
+ if (!existsSync9(file))
31198
31189
  return null;
31199
31190
  const data = JSON.parse(readFileSync4(file, "utf-8"));
31200
31191
  return data;
@@ -31210,15 +31201,15 @@ function writeCache(sourceId, results) {
31210
31201
  }
31211
31202
  function clearCache(sourceId) {
31212
31203
  try {
31213
- if (!existsSync8(CACHE_DIR))
31204
+ if (!existsSync9(CACHE_DIR))
31214
31205
  return;
31215
- const files = readdirSync3(CACHE_DIR);
31206
+ const files = readdirSync2(CACHE_DIR);
31216
31207
  for (const file of files) {
31217
31208
  if (!file.endsWith(".json"))
31218
31209
  continue;
31219
31210
  if (!sourceId || file.startsWith(`${sourceId}.`)) {
31220
31211
  try {
31221
- unlinkSync(join9(CACHE_DIR, file));
31212
+ unlinkSync(join10(CACHE_DIR, file));
31222
31213
  } catch {}
31223
31214
  }
31224
31215
  }
@@ -31464,7 +31455,7 @@ var CACHE_DIR, DEFAULT_TTL_MS;
31464
31455
  var init_sources = __esm(() => {
31465
31456
  init_db();
31466
31457
  init_config2();
31467
- CACHE_DIR = join9(MCPS_DIR, "cache");
31458
+ CACHE_DIR = join10(MCPS_DIR, "cache");
31468
31459
  DEFAULT_TTL_MS = 10 * 60 * 1000;
31469
31460
  });
31470
31461
 
@@ -31482,8 +31473,8 @@ var init_finder = __esm(() => {
31482
31473
 
31483
31474
  // src/lib/install.ts
31484
31475
  import { execFileSync } from "child_process";
31485
- import { existsSync as existsSync9, readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync7 } from "fs";
31486
- import { join as join10 } from "path";
31476
+ import { existsSync as existsSync10, readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync7 } from "fs";
31477
+ import { join as join11 } from "path";
31487
31478
  import { homedir as homedir8 } from "os";
31488
31479
  function installToClaude(entry) {
31489
31480
  try {
@@ -31507,9 +31498,9 @@ function installToClaude(entry) {
31507
31498
  }
31508
31499
  function installToCodex(entry) {
31509
31500
  try {
31510
- const configDir = join10(homedir8(), ".codex");
31511
- const configPath = join10(configDir, "config.toml");
31512
- if (!existsSync9(configDir)) {
31501
+ const configDir = join11(homedir8(), ".codex");
31502
+ const configPath = join11(configDir, "config.toml");
31503
+ if (!existsSync10(configDir)) {
31513
31504
  mkdirSync7(configDir, { recursive: true });
31514
31505
  }
31515
31506
  const block = `
@@ -31517,7 +31508,7 @@ function installToCodex(entry) {
31517
31508
  ` + `command = ${JSON.stringify(entry.command)}
31518
31509
  ` + `args = [${entry.args.map((a) => JSON.stringify(a)).join(", ")}]
31519
31510
  `;
31520
- const existing = existsSync9(configPath) ? readFileSync5(configPath, "utf-8") : "";
31511
+ const existing = existsSync10(configPath) ? readFileSync5(configPath, "utf-8") : "";
31521
31512
  if (existing.includes(`[mcp_servers.${entry.id}]`)) {
31522
31513
  return { agent: "codex", success: true };
31523
31514
  }
@@ -31529,13 +31520,13 @@ function installToCodex(entry) {
31529
31520
  }
31530
31521
  function installToGemini(entry) {
31531
31522
  try {
31532
- const configDir = join10(homedir8(), ".gemini");
31533
- const configPath = join10(configDir, "settings.json");
31534
- if (!existsSync9(configDir)) {
31523
+ const configDir = join11(homedir8(), ".gemini");
31524
+ const configPath = join11(configDir, "settings.json");
31525
+ if (!existsSync10(configDir)) {
31535
31526
  mkdirSync7(configDir, { recursive: true });
31536
31527
  }
31537
31528
  let settings = {};
31538
- if (existsSync9(configPath)) {
31529
+ if (existsSync10(configPath)) {
31539
31530
  settings = JSON.parse(readFileSync5(configPath, "utf-8"));
31540
31531
  }
31541
31532
  if (!settings.mcpServers)
@@ -34939,15 +34930,15 @@ var init_machines = __esm(() => {
34939
34930
 
34940
34931
  // src/lib/fleet.ts
34941
34932
  import { spawn as spawn2 } from "child_process";
34942
- import { existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
34943
- import { join as join11 } from "path";
34933
+ import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
34934
+ import { join as join12 } from "path";
34944
34935
  function normalizeQueryList(values) {
34945
34936
  const trimmed = values?.map((value) => value.trim()).filter(Boolean);
34946
34937
  return trimmed && trimmed.length > 0 ? trimmed : undefined;
34947
34938
  }
34948
34939
  function readCatalogCache(maxAgeMs) {
34949
34940
  try {
34950
- if (!existsSync10(CATALOG_CACHE_PATH))
34941
+ if (!existsSync11(CATALOG_CACHE_PATH))
34951
34942
  return null;
34952
34943
  const parsed = JSON.parse(readFileSync6(CATALOG_CACHE_PATH, "utf-8"));
34953
34944
  if (!parsed.cachedAt || !Array.isArray(parsed.entries))
@@ -34961,7 +34952,7 @@ function readCatalogCache(maxAgeMs) {
34961
34952
  }
34962
34953
  function writeCatalogCache(entries) {
34963
34954
  try {
34964
- mkdirSync8(join11(MCPS_DIR, "cache"), { recursive: true });
34955
+ mkdirSync8(join12(MCPS_DIR, "cache"), { recursive: true });
34965
34956
  writeFileSync4(CATALOG_CACHE_PATH, JSON.stringify({ cachedAt: Date.now(), entries }, null, 2), "utf-8");
34966
34957
  } catch {}
34967
34958
  }
@@ -35635,7 +35626,7 @@ var NPM_SEARCH_URL = "https://registry.npmjs.org/-/v1/search", NPM_REGISTRY_URL
35635
35626
  var init_fleet = __esm(() => {
35636
35627
  init_config2();
35637
35628
  init_machines();
35638
- CATALOG_CACHE_PATH = join11(MCPS_DIR, "cache", "hasna-catalog.json");
35629
+ CATALOG_CACHE_PATH = join12(MCPS_DIR, "cache", "hasna-catalog.json");
35639
35630
  DEFAULT_CATALOG_CACHE_TTL_MS = 60 * 60 * 1000;
35640
35631
  });
35641
35632
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/mcps",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "description": "Meta-MCP registry & CLI — discover, manage, and proxy MCP servers",
5
5
  "type": "module",
6
6
  "repository": {
@@ -43,7 +43,8 @@
43
43
  "postinstall": "mkdir -p $HOME/.hasna/mcps/cache 2>/dev/null || true"
44
44
  },
45
45
  "dependencies": {
46
- "@hasna/cloud": "^0.1.24",
46
+ "@hasna/cloud": "0.1.24",
47
+ "@hasna/events": "^0.1.6",
47
48
  "@modelcontextprotocol/sdk": "^1.26.0",
48
49
  "chalk": "^5.3.0",
49
50
  "commander": "^12.1.0",