@hasna/cloud 0.1.38 → 0.1.40

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/index.js CHANGED
@@ -8956,7 +8956,7 @@ var require_dist = __commonJS((exports) => {
8956
8956
  function parse(stream, callback) {
8957
8957
  const parser = new parser_1.Parser;
8958
8958
  stream.on("data", (buffer) => parser.parse(buffer, callback));
8959
- return new Promise((resolve) => stream.on("end", () => resolve()));
8959
+ return new Promise((resolve2) => stream.on("end", () => resolve2()));
8960
8960
  }
8961
8961
  exports.parse = parse;
8962
8962
  });
@@ -9635,12 +9635,12 @@ var require_client = __commonJS((exports, module) => {
9635
9635
  this._connect(callback);
9636
9636
  return;
9637
9637
  }
9638
- return new this._Promise((resolve, reject) => {
9638
+ return new this._Promise((resolve2, reject) => {
9639
9639
  this._connect((error) => {
9640
9640
  if (error) {
9641
9641
  reject(error);
9642
9642
  } else {
9643
- resolve(this);
9643
+ resolve2(this);
9644
9644
  }
9645
9645
  });
9646
9646
  });
@@ -9972,8 +9972,8 @@ var require_client = __commonJS((exports, module) => {
9972
9972
  readTimeout = config.query_timeout || this.connectionParameters.query_timeout;
9973
9973
  query = new Query(config, values, callback);
9974
9974
  if (!query.callback) {
9975
- result = new this._Promise((resolve, reject) => {
9976
- query.callback = (err, res) => err ? reject(err) : resolve(res);
9975
+ result = new this._Promise((resolve2, reject) => {
9976
+ query.callback = (err, res) => err ? reject(err) : resolve2(res);
9977
9977
  }).catch((err) => {
9978
9978
  Error.captureStackTrace(err);
9979
9979
  throw err;
@@ -10048,8 +10048,8 @@ var require_client = __commonJS((exports, module) => {
10048
10048
  if (cb) {
10049
10049
  this.connection.once("end", cb);
10050
10050
  } else {
10051
- return new this._Promise((resolve) => {
10052
- this.connection.once("end", resolve);
10051
+ return new this._Promise((resolve2) => {
10052
+ this.connection.once("end", resolve2);
10053
10053
  });
10054
10054
  }
10055
10055
  }
@@ -10096,8 +10096,8 @@ var require_pg_pool = __commonJS((exports, module) => {
10096
10096
  const cb = function(err, client) {
10097
10097
  err ? rej(err) : res(client);
10098
10098
  };
10099
- const result = new Promise2(function(resolve, reject) {
10100
- res = resolve;
10099
+ const result = new Promise2(function(resolve2, reject) {
10100
+ res = resolve2;
10101
10101
  rej = reject;
10102
10102
  }).catch((err) => {
10103
10103
  Error.captureStackTrace(err);
@@ -10158,7 +10158,7 @@ var require_pg_pool = __commonJS((exports, module) => {
10158
10158
  if (typeof Promise2.try === "function") {
10159
10159
  return Promise2.try(f);
10160
10160
  }
10161
- return new Promise2((resolve) => resolve(f()));
10161
+ return new Promise2((resolve2) => resolve2(f()));
10162
10162
  }
10163
10163
  _isFull() {
10164
10164
  return this._clients.length >= this.options.max;
@@ -10534,8 +10534,8 @@ var require_query2 = __commonJS((exports, module) => {
10534
10534
  NativeQuery.prototype._getPromise = function() {
10535
10535
  if (this._promise)
10536
10536
  return this._promise;
10537
- this._promise = new Promise(function(resolve, reject) {
10538
- this._once("end", resolve);
10537
+ this._promise = new Promise(function(resolve2, reject) {
10538
+ this._once("end", resolve2);
10539
10539
  this._once("error", reject);
10540
10540
  }.bind(this));
10541
10541
  return this._promise;
@@ -10709,12 +10709,12 @@ var require_client2 = __commonJS((exports, module) => {
10709
10709
  this._connect(callback);
10710
10710
  return;
10711
10711
  }
10712
- return new this._Promise((resolve, reject) => {
10712
+ return new this._Promise((resolve2, reject) => {
10713
10713
  this._connect((error) => {
10714
10714
  if (error) {
10715
10715
  reject(error);
10716
10716
  } else {
10717
- resolve(this);
10717
+ resolve2(this);
10718
10718
  }
10719
10719
  });
10720
10720
  });
@@ -10738,8 +10738,8 @@ var require_client2 = __commonJS((exports, module) => {
10738
10738
  query = new NativeQuery(config, values, callback);
10739
10739
  if (!query.callback) {
10740
10740
  let resolveOut, rejectOut;
10741
- result = new this._Promise((resolve, reject) => {
10742
- resolveOut = resolve;
10741
+ result = new this._Promise((resolve2, reject) => {
10742
+ resolveOut = resolve2;
10743
10743
  rejectOut = reject;
10744
10744
  }).catch((err) => {
10745
10745
  Error.captureStackTrace(err);
@@ -10797,8 +10797,8 @@ var require_client2 = __commonJS((exports, module) => {
10797
10797
  }
10798
10798
  let result;
10799
10799
  if (!cb) {
10800
- result = new this._Promise(function(resolve, reject) {
10801
- cb = (err) => err ? reject(err) : resolve();
10800
+ result = new this._Promise(function(resolve2, reject) {
10801
+ cb = (err) => err ? reject(err) : resolve2();
10802
10802
  });
10803
10803
  }
10804
10804
  this.native.end(function() {
@@ -11238,7 +11238,7 @@ var init_adapter = __esm(() => {
11238
11238
 
11239
11239
  // src/dotfile.ts
11240
11240
  import {
11241
- existsSync as existsSync2,
11241
+ existsSync as existsSync3,
11242
11242
  mkdirSync,
11243
11243
  readdirSync,
11244
11244
  copyFileSync
@@ -11257,9 +11257,9 @@ function getDbPath(serviceName) {
11257
11257
  function migrateDotfile(serviceName) {
11258
11258
  const legacyDir = join2(homedir2(), `.${serviceName}`);
11259
11259
  const newDir = join2(HASNA_DIR, serviceName);
11260
- if (!existsSync2(legacyDir))
11260
+ if (!existsSync3(legacyDir))
11261
11261
  return [];
11262
- if (existsSync2(newDir))
11262
+ if (existsSync3(newDir))
11263
11263
  return [];
11264
11264
  mkdirSync(newDir, { recursive: true });
11265
11265
  const migrated = [];
@@ -11299,7 +11299,7 @@ __export(exports_discover, {
11299
11299
  SYNC_EXCLUDED_TABLE_PATTERNS: () => SYNC_EXCLUDED_TABLE_PATTERNS,
11300
11300
  KNOWN_PG_SERVICES: () => KNOWN_PG_SERVICES
11301
11301
  });
11302
- import { readdirSync as readdirSync2, existsSync as existsSync3 } from "fs";
11302
+ import { readdirSync as readdirSync2, existsSync as existsSync4 } from "fs";
11303
11303
  import { join as join3 } from "path";
11304
11304
  import { homedir as homedir3 } from "os";
11305
11305
  function isSyncExcludedTable(table) {
@@ -11307,7 +11307,7 @@ function isSyncExcludedTable(table) {
11307
11307
  }
11308
11308
  function discoverServices() {
11309
11309
  const dataDir = join3(homedir3(), ".hasna");
11310
- if (!existsSync3(dataDir))
11310
+ if (!existsSync4(dataDir))
11311
11311
  return [];
11312
11312
  try {
11313
11313
  const entries = readdirSync2(dataDir, { withFileTypes: true });
@@ -11329,7 +11329,7 @@ function discoverSyncableServices() {
11329
11329
  }
11330
11330
  function getServiceDbPath(service) {
11331
11331
  const dataDir = join3(homedir3(), ".hasna", service);
11332
- if (!existsSync3(dataDir))
11332
+ if (!existsSync4(dataDir))
11333
11333
  return null;
11334
11334
  const candidates = [
11335
11335
  join3(dataDir, `${service}.db`),
@@ -11345,7 +11345,7 @@ function getServiceDbPath(service) {
11345
11345
  }
11346
11346
  } catch {}
11347
11347
  for (const p of candidates) {
11348
- if (existsSync3(p))
11348
+ if (existsSync4(p))
11349
11349
  return p;
11350
11350
  }
11351
11351
  return null;
@@ -11400,9 +11400,9 @@ var init_discover = __esm(() => {
11400
11400
 
11401
11401
  // src/machines.ts
11402
11402
  import { spawnSync } from "child_process";
11403
- import { existsSync as existsSync4 } from "fs";
11403
+ import { existsSync as existsSync5 } from "fs";
11404
11404
  import { homedir as homedir4, hostname, platform, arch, userInfo } from "os";
11405
- import { dirname, join as join4 } from "path";
11405
+ import { dirname as dirname2, join as join4 } from "path";
11406
11406
  function quoteSqlString(value) {
11407
11407
  return `'${value.replace(/'/g, "''")}'`;
11408
11408
  }
@@ -11417,7 +11417,7 @@ function detectWorkspacePath() {
11417
11417
  const home = homedir4();
11418
11418
  const candidates = [join4(home, "workspace"), join4(home, "Workspace")];
11419
11419
  for (const candidate of candidates) {
11420
- if (existsSync4(candidate))
11420
+ if (existsSync5(candidate))
11421
11421
  return candidate;
11422
11422
  }
11423
11423
  const cwd = process.cwd();
@@ -11432,7 +11432,7 @@ function detectWorkspacePath() {
11432
11432
  return cwd;
11433
11433
  }
11434
11434
  function detectBunPath() {
11435
- return dirname(process.execPath);
11435
+ return dirname2(process.execPath);
11436
11436
  }
11437
11437
  function toFlag(value, fallback = 0) {
11438
11438
  if (value === undefined)
@@ -11814,7 +11814,7 @@ __export(exports_config, {
11814
11814
  createDatabase: () => createDatabase,
11815
11815
  CloudConfigSchema: () => CloudConfigSchema
11816
11816
  });
11817
- import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync, writeFileSync } from "fs";
11817
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
11818
11818
  import { homedir as homedir5 } from "os";
11819
11819
  import { join as join5 } from "path";
11820
11820
  function getConfigDir() {
@@ -11824,11 +11824,11 @@ function getConfigPath() {
11824
11824
  return CONFIG_PATH;
11825
11825
  }
11826
11826
  function getCloudConfig() {
11827
- if (!existsSync5(CONFIG_PATH)) {
11827
+ if (!existsSync6(CONFIG_PATH)) {
11828
11828
  return CloudConfigSchema.parse({});
11829
11829
  }
11830
11830
  try {
11831
- const raw = readFileSync(CONFIG_PATH, "utf-8");
11831
+ const raw = readFileSync2(CONFIG_PATH, "utf-8");
11832
11832
  return CloudConfigSchema.parse(JSON.parse(raw));
11833
11833
  } catch {
11834
11834
  return CloudConfigSchema.parse({});
@@ -11849,8 +11849,15 @@ function getConnectionString(dbName) {
11849
11849
  if (password === undefined || password === "") {
11850
11850
  throw new Error(`RDS password not set. Export ${password_env} in your shell or add it to ~/.secrets/hasna/rds/live.env`);
11851
11851
  }
11852
- const sslParam = ssl ? "?sslmode=require" : "";
11853
- return `postgres://${username}:${encodeURIComponent(password)}@${host}:${port}/${dbName}${sslParam}`;
11852
+ const url = new URL("postgres:" + "//placeholder");
11853
+ url.hostname = host;
11854
+ url.port = String(port);
11855
+ url.username = username;
11856
+ url.password = password;
11857
+ url.pathname = `/${dbName}`;
11858
+ if (ssl)
11859
+ url.searchParams.set("sslmode", "require");
11860
+ return url.toString();
11854
11861
  }
11855
11862
  function createDatabase(options) {
11856
11863
  const config = getCloudConfig();
@@ -11891,7 +11898,7 @@ var init_config = __esm(() => {
11891
11898
  password_env: exports_external.string().default("HASNA_RDS_PASSWORD"),
11892
11899
  ssl: exports_external.boolean().default(true)
11893
11900
  }).default({}),
11894
- mode: exports_external.enum(["local", "cloud", "hybrid"]).default("hybrid"),
11901
+ mode: exports_external.enum(["local", "cloud", "hybrid"]).default("local"),
11895
11902
  auto_sync_interval_minutes: exports_external.number().default(0),
11896
11903
  feedback_endpoint: exports_external.string().default("https://feedback.hasna.com/api/v1/feedback"),
11897
11904
  sync: exports_external.object({
@@ -12603,6 +12610,31 @@ function collectValues(value, previous) {
12603
12610
  return previous;
12604
12611
  }
12605
12612
 
12613
+ // src/version.ts
12614
+ import { existsSync as existsSync2, readFileSync } from "node:fs";
12615
+ import { dirname, resolve } from "node:path";
12616
+ import { fileURLToPath } from "node:url";
12617
+ var cachedPackageVersion;
12618
+ function getPackageVersion() {
12619
+ if (cachedPackageVersion)
12620
+ return cachedPackageVersion;
12621
+ const here = dirname(fileURLToPath(import.meta.url));
12622
+ const candidates = [
12623
+ resolve(here, "../package.json"),
12624
+ resolve(here, "../../package.json")
12625
+ ];
12626
+ for (const path of candidates) {
12627
+ if (!existsSync2(path))
12628
+ continue;
12629
+ const pkg = JSON.parse(readFileSync(path, "utf8"));
12630
+ if (typeof pkg.version === "string" && pkg.version.length > 0) {
12631
+ cachedPackageVersion = pkg.version;
12632
+ return cachedPackageVersion;
12633
+ }
12634
+ }
12635
+ throw new Error("Unable to resolve @hasna/cloud package version");
12636
+ }
12637
+
12606
12638
  // src/cli/cmd-setup.ts
12607
12639
  init_config();
12608
12640
 
@@ -13194,8 +13226,8 @@ async function ensureAllPgDatabases() {
13194
13226
 
13195
13227
  // src/sync-schedule.ts
13196
13228
  init_config();
13197
- import { join as join6, dirname as dirname2 } from "path";
13198
- import { existsSync as existsSync6, writeFileSync as writeFileSync2, unlinkSync, mkdirSync as mkdirSync3 } from "fs";
13229
+ import { join as join6, dirname as dirname3 } from "path";
13230
+ import { existsSync as existsSync7, writeFileSync as writeFileSync2, unlinkSync, mkdirSync as mkdirSync3 } from "fs";
13199
13231
  import { homedir as homedir6, platform as platform2 } from "os";
13200
13232
  var SERVICE_NAME = "hasna-cloud-sync";
13201
13233
  var CONFIG_DIR2 = join6(homedir6(), ".hasna", "cloud");
@@ -13238,11 +13270,11 @@ function minutesToCron(minutes) {
13238
13270
  return `*/${minutes} * * * *`;
13239
13271
  }
13240
13272
  function getWorkerPath() {
13241
- const dir = typeof import.meta.dir === "string" ? import.meta.dir : dirname2(import.meta.url.replace("file://", ""));
13273
+ const dir = typeof import.meta.dir === "string" ? import.meta.dir : dirname3(import.meta.url.replace("file://", ""));
13242
13274
  const tsPath = join6(dir, "scheduled-sync.ts");
13243
13275
  const jsPath = join6(dir, "scheduled-sync.js");
13244
13276
  try {
13245
- if (existsSync6(tsPath))
13277
+ if (existsSync7(tsPath))
13246
13278
  return tsPath;
13247
13279
  } catch {}
13248
13280
  return jsPath;
@@ -13254,7 +13286,7 @@ function getBunPath() {
13254
13286
  "/usr/bin/bun"
13255
13287
  ];
13256
13288
  for (const p of candidates) {
13257
- if (existsSync6(p))
13289
+ if (existsSync7(p))
13258
13290
  return p;
13259
13291
  }
13260
13292
  return "bun";
@@ -13299,7 +13331,7 @@ function createLaunchdPlist(intervalMinutes) {
13299
13331
  }
13300
13332
  async function registerLaunchd(intervalMinutes) {
13301
13333
  const plistPath = getLaunchdPlistPath();
13302
- const plistDir = dirname2(plistPath);
13334
+ const plistDir = dirname3(plistPath);
13303
13335
  mkdirSync3(plistDir, { recursive: true });
13304
13336
  try {
13305
13337
  await Bun.spawn(["launchctl", "unload", plistPath]).exited;
@@ -13403,9 +13435,9 @@ function getSyncScheduleStatus() {
13403
13435
  let mechanism = "none";
13404
13436
  if (registered) {
13405
13437
  if (platform2() === "darwin") {
13406
- mechanism = existsSync6(getLaunchdPlistPath()) ? "launchd" : "none";
13438
+ mechanism = existsSync7(getLaunchdPlistPath()) ? "launchd" : "none";
13407
13439
  } else {
13408
- mechanism = existsSync6(join6(getSystemdDir(), `${SERVICE_NAME}.timer`)) ? "systemd" : "none";
13440
+ mechanism = existsSync7(join6(getSystemdDir(), `${SERVICE_NAME}.timer`)) ? "systemd" : "none";
13409
13441
  }
13410
13442
  }
13411
13443
  return {
@@ -13597,7 +13629,7 @@ function purgeResolvedConflicts(db) {
13597
13629
  // src/scheduled-sync.ts
13598
13630
  init_config();
13599
13631
  init_adapter();
13600
- import { existsSync as existsSync7, readdirSync as readdirSync3 } from "fs";
13632
+ import { existsSync as existsSync8, readdirSync as readdirSync3 } from "fs";
13601
13633
  import { join as join7 } from "path";
13602
13634
 
13603
13635
  // src/sync-incremental.ts
@@ -13806,7 +13838,7 @@ function discoverSyncableServices2() {
13806
13838
  if (!entry.isDirectory())
13807
13839
  continue;
13808
13840
  const dbPath = join7(hasnaDir, entry.name, `${entry.name}.db`);
13809
- if (existsSync7(dbPath)) {
13841
+ if (existsSync8(dbPath)) {
13810
13842
  services.push(entry.name);
13811
13843
  }
13812
13844
  }
@@ -13829,7 +13861,7 @@ async function runScheduledSync() {
13829
13861
  };
13830
13862
  try {
13831
13863
  const dbPath = join7(getDataDir(service), `${service}.db`);
13832
- if (!existsSync7(dbPath)) {
13864
+ if (!existsSync8(dbPath)) {
13833
13865
  continue;
13834
13866
  }
13835
13867
  const local = new SqliteAdapter(dbPath);
@@ -13872,7 +13904,7 @@ async function runScheduledSync() {
13872
13904
  }
13873
13905
 
13874
13906
  // src/cli/cmd-sync.ts
13875
- import { existsSync as existsSync9, statSync as statSync5 } from "fs";
13907
+ import { existsSync as existsSync10, statSync as statSync5 } from "fs";
13876
13908
  import { join as join9 } from "path";
13877
13909
  import { homedir as homedir8 } from "os";
13878
13910
 
@@ -13883,9 +13915,9 @@ init_discover();
13883
13915
  init_dotfile();
13884
13916
  import { spawn as spawn2 } from "child_process";
13885
13917
  import {
13886
- existsSync as existsSync8,
13918
+ existsSync as existsSync9,
13887
13919
  mkdirSync as mkdirSync4,
13888
- readFileSync as readFileSync3,
13920
+ readFileSync as readFileSync4,
13889
13921
  statSync as statSync4,
13890
13922
  writeFileSync as writeFileSync3
13891
13923
  } from "fs";
@@ -13959,11 +13991,11 @@ function createDefaultDaemonState() {
13959
13991
  };
13960
13992
  }
13961
13993
  function readDaemonState() {
13962
- if (!existsSync8(DAEMON_STATE_PATH)) {
13994
+ if (!existsSync9(DAEMON_STATE_PATH)) {
13963
13995
  return createDefaultDaemonState();
13964
13996
  }
13965
13997
  try {
13966
- const raw = JSON.parse(readFileSync3(DAEMON_STATE_PATH, "utf-8"));
13998
+ const raw = JSON.parse(readFileSync4(DAEMON_STATE_PATH, "utf-8"));
13967
13999
  const defaults2 = createDefaultDaemonState();
13968
14000
  return {
13969
14001
  ...defaults2,
@@ -14132,7 +14164,7 @@ function runDaemonPass(config, state = createDefaultDaemonState(), options = {})
14132
14164
  }
14133
14165
  for (const service of services) {
14134
14166
  const dbPath = adapterFactory.getLocalDbPath(service);
14135
- if (!existsSync8(dbPath))
14167
+ if (!existsSync9(dbPath))
14136
14168
  continue;
14137
14169
  const serviceState = getServiceState(nextState, service);
14138
14170
  let local = null;
@@ -14632,7 +14664,7 @@ function registerStatusCommand(syncCmd) {
14632
14664
  const statuses = [];
14633
14665
  for (const service of services) {
14634
14666
  const dbPath = getDbPath(service);
14635
- const localExists = existsSync9(dbPath);
14667
+ const localExists = existsSync10(dbPath);
14636
14668
  let localSize = "—";
14637
14669
  let tableCount = 0;
14638
14670
  if (localExists) {
@@ -15124,14 +15156,14 @@ function registerFeedbackCommand(program3) {
15124
15156
  init_config();
15125
15157
  init_adapter();
15126
15158
  init_discover();
15127
- import { existsSync as existsSync10 } from "fs";
15159
+ import { existsSync as existsSync11 } from "fs";
15128
15160
  import { join as join10 } from "path";
15129
15161
  import { homedir as homedir9 } from "os";
15130
15162
  function registerDoctorCommand(program3) {
15131
15163
  program3.command("doctor").description("Comprehensive health check for cloud sync setup").action(async () => {
15132
15164
  const checks = [];
15133
15165
  const configPath = join10(homedir9(), ".hasna", "cloud", "config.json");
15134
- checks.push(existsSync10(configPath) ? { name: "Config file", status: "pass", detail: configPath } : { name: "Config file", status: "fail", detail: "Missing. Run `cloud setup`." });
15166
+ checks.push(existsSync11(configPath) ? { name: "Config file", status: "pass", detail: configPath } : { name: "Config file", status: "fail", detail: "Missing. Run `cloud setup`." });
15135
15167
  const config = getCloudConfig();
15136
15168
  checks.push(config.mode === "hybrid" || config.mode === "cloud" ? { name: "Sync mode", status: "pass", detail: config.mode } : { name: "Sync mode", status: "fail", detail: `"${config.mode}" — sync disabled. Run \`cloud setup --mode hybrid\`.` });
15137
15169
  checks.push(config.rds.host ? { name: "RDS host", status: "pass", detail: config.rds.host } : { name: "RDS host", status: "fail", detail: "Not configured. Run `cloud setup`." });
@@ -15150,7 +15182,7 @@ function registerDoctorCommand(program3) {
15150
15182
  checks.push({ name: "PG connection", status: "fail", detail: "Skipped — missing host or password" });
15151
15183
  }
15152
15184
  const caPath = process.env.NODE_EXTRA_CA_CERTS;
15153
- if (caPath && existsSync10(caPath)) {
15185
+ if (caPath && existsSync11(caPath)) {
15154
15186
  checks.push({ name: "SSL CA cert", status: "pass", detail: caPath });
15155
15187
  } else if (caPath) {
15156
15188
  checks.push({ name: "SSL CA cert", status: "warn", detail: `NODE_EXTRA_CA_CERTS set but file missing: ${caPath}` });
@@ -15191,7 +15223,7 @@ init_zod();
15191
15223
  init_adapter();
15192
15224
  init_dotfile();
15193
15225
  init_machines();
15194
- import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
15226
+ import { existsSync as existsSync12, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
15195
15227
  import { homedir as homedir10 } from "os";
15196
15228
  import { join as join11 } from "path";
15197
15229
  var DaemonConfigSchema2 = exports_external.object({
@@ -15217,7 +15249,7 @@ var CloudConfigSchema2 = exports_external.object({
15217
15249
  password_env: exports_external.string().default("HASNA_RDS_PASSWORD"),
15218
15250
  ssl: exports_external.boolean().default(true)
15219
15251
  }).default({}),
15220
- mode: exports_external.enum(["local", "cloud", "hybrid"]).default("hybrid"),
15252
+ mode: exports_external.enum(["local", "cloud", "hybrid"]).default("local"),
15221
15253
  auto_sync_interval_minutes: exports_external.number().default(0),
15222
15254
  feedback_endpoint: exports_external.string().default("https://feedback.hasna.com/api/v1/feedback"),
15223
15255
  sync: exports_external.object({
@@ -15228,11 +15260,11 @@ var CloudConfigSchema2 = exports_external.object({
15228
15260
  var CONFIG_DIR3 = join11(homedir10(), ".hasna", "cloud");
15229
15261
  var CONFIG_PATH2 = join11(CONFIG_DIR3, "config.json");
15230
15262
  function getCloudConfig2() {
15231
- if (!existsSync11(CONFIG_PATH2)) {
15263
+ if (!existsSync12(CONFIG_PATH2)) {
15232
15264
  return CloudConfigSchema2.parse({});
15233
15265
  }
15234
15266
  try {
15235
- const raw = readFileSync4(CONFIG_PATH2, "utf-8");
15267
+ const raw = readFileSync5(CONFIG_PATH2, "utf-8");
15236
15268
  return CloudConfigSchema2.parse(JSON.parse(raw));
15237
15269
  } catch {
15238
15270
  return CloudConfigSchema2.parse({});
@@ -15248,8 +15280,15 @@ function getConnectionString2(dbName) {
15248
15280
  if (password === undefined || password === "") {
15249
15281
  throw new Error(`RDS password not set. Export ${password_env} in your shell or add it to ~/.secrets/hasna/rds/live.env`);
15250
15282
  }
15251
- const sslParam = ssl ? "?sslmode=require" : "";
15252
- return `postgres://${username}:${encodeURIComponent(password)}@${host}:${port}/${dbName}${sslParam}`;
15283
+ const url = new URL("postgres:" + "//placeholder");
15284
+ url.hostname = host;
15285
+ url.port = String(port);
15286
+ url.username = username;
15287
+ url.password = password;
15288
+ url.pathname = `/${dbName}`;
15289
+ if (ssl)
15290
+ url.searchParams.set("sslmode", "require");
15291
+ return url.toString();
15253
15292
  }
15254
15293
 
15255
15294
  // src/adapter.ts
@@ -15313,7 +15352,7 @@ class PgAdapterAsync2 {
15313
15352
 
15314
15353
  // src/cli/index.ts
15315
15354
  var program3 = new Command;
15316
- program3.name("cloud").description("Shared cloud infrastructure \u2014 database adapter, sync engine, feedback, dotfile migration").version("0.1.13");
15355
+ program3.name("cloud").description("Shared cloud infrastructure \u2014 database adapter, sync engine, feedback, dotfile migration").version(getPackageVersion());
15317
15356
  registerEventsCommands(program3, { source: "cloud" });
15318
15357
  registerSetupCommand(program3);
15319
15358
  program3.command("status").description("Show current cloud configuration and connection health").action(async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwBV,CAAC;AAMf,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqB5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AASnE,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAMD,wBAAgB,cAAc,IAAI,WAAW,CAU5C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAGzD;AAMD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAoB1D;AAQD,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpC,qCAAqC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,GAC7B,qBAAqB,CAavB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwBV,CAAC;AAMf,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqB5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AASnE,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAMD,wBAAgB,cAAc,IAAI,WAAW,CAU5C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAGzD;AAMD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA0B1D;AAQD,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpC,qCAAqC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,GAC7B,qBAAqB,CAavB"}
package/dist/index.js CHANGED
@@ -9827,8 +9827,15 @@ function getConnectionString(dbName) {
9827
9827
  if (password === undefined || password === "") {
9828
9828
  throw new Error(`RDS password not set. Export ${password_env} in your shell or add it to ~/.secrets/hasna/rds/live.env`);
9829
9829
  }
9830
- const sslParam = ssl ? "?sslmode=require" : "";
9831
- return `postgres://${username}:${encodeURIComponent(password)}@${host}:${port}/${dbName}${sslParam}`;
9830
+ const url = new URL("postgres:" + "//placeholder");
9831
+ url.hostname = host;
9832
+ url.port = String(port);
9833
+ url.username = username;
9834
+ url.password = password;
9835
+ url.pathname = `/${dbName}`;
9836
+ if (ssl)
9837
+ url.searchParams.set("sslmode", "require");
9838
+ return url.toString();
9832
9839
  }
9833
9840
  function createDatabase(options) {
9834
9841
  const config = getCloudConfig();
@@ -9869,7 +9876,7 @@ var init_config = __esm(() => {
9869
9876
  password_env: exports_external.string().default("HASNA_RDS_PASSWORD"),
9870
9877
  ssl: exports_external.boolean().default(true)
9871
9878
  }).default({}),
9872
- mode: exports_external.enum(["local", "cloud", "hybrid"]).default("hybrid"),
9879
+ mode: exports_external.enum(["local", "cloud", "hybrid"]).default("local"),
9873
9880
  auto_sync_interval_minutes: exports_external.number().default(0),
9874
9881
  feedback_endpoint: exports_external.string().default("https://feedback.hasna.com/api/v1/feedback"),
9875
9882
  sync: exports_external.object({
package/dist/mcp/bin.js CHANGED
@@ -16257,8 +16257,15 @@ function getConnectionString(dbName) {
16257
16257
  if (password === undefined || password === "") {
16258
16258
  throw new Error(`RDS password not set. Export ${password_env} in your shell or add it to ~/.secrets/hasna/rds/live.env`);
16259
16259
  }
16260
- const sslParam = ssl ? "?sslmode=require" : "";
16261
- return `postgres://${username}:${encodeURIComponent(password)}@${host}:${port}/${dbName}${sslParam}`;
16260
+ const url = new URL("postgres:" + "//placeholder");
16261
+ url.hostname = host;
16262
+ url.port = String(port);
16263
+ url.username = username;
16264
+ url.password = password;
16265
+ url.pathname = `/${dbName}`;
16266
+ if (ssl)
16267
+ url.searchParams.set("sslmode", "require");
16268
+ return url.toString();
16262
16269
  }
16263
16270
  function createDatabase(options) {
16264
16271
  const config2 = getCloudConfig();
@@ -16299,7 +16306,7 @@ var init_config = __esm(() => {
16299
16306
  password_env: exports_external.string().default("HASNA_RDS_PASSWORD"),
16300
16307
  ssl: exports_external.boolean().default(true)
16301
16308
  }).default({}),
16302
- mode: exports_external.enum(["local", "cloud", "hybrid"]).default("hybrid"),
16309
+ mode: exports_external.enum(["local", "cloud", "hybrid"]).default("local"),
16303
16310
  auto_sync_interval_minutes: exports_external.number().default(0),
16304
16311
  feedback_endpoint: exports_external.string().default("https://feedback.hasna.com/api/v1/feedback"),
16305
16312
  sync: exports_external.object({
@@ -25964,6 +25971,31 @@ async function sendFeedback(feedback, db) {
25964
25971
  init_dotfile();
25965
25972
  init_adapter();
25966
25973
 
25974
+ // src/version.ts
25975
+ import { existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
25976
+ import { dirname as dirname2, resolve } from "node:path";
25977
+ import { fileURLToPath } from "node:url";
25978
+ var cachedPackageVersion;
25979
+ function getPackageVersion() {
25980
+ if (cachedPackageVersion)
25981
+ return cachedPackageVersion;
25982
+ const here = dirname2(fileURLToPath(import.meta.url));
25983
+ const candidates = [
25984
+ resolve(here, "../package.json"),
25985
+ resolve(here, "../../package.json")
25986
+ ];
25987
+ for (const path of candidates) {
25988
+ if (!existsSync5(path))
25989
+ continue;
25990
+ const pkg = JSON.parse(readFileSync2(path, "utf8"));
25991
+ if (typeof pkg.version === "string" && pkg.version.length > 0) {
25992
+ cachedPackageVersion = pkg.version;
25993
+ return cachedPackageVersion;
25994
+ }
25995
+ }
25996
+ throw new Error("Unable to resolve @hasna/cloud package version");
25997
+ }
25998
+
25967
25999
  // src/mcp/http.ts
25968
26000
  import { createServer } from "node:http";
25969
26001
 
@@ -26378,7 +26410,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
26378
26410
  });
26379
26411
  if (!chunk) {
26380
26412
  if (i === 1) {
26381
- await new Promise((resolve) => setTimeout(resolve));
26413
+ await new Promise((resolve2) => setTimeout(resolve2));
26382
26414
  maxReadCount = 3;
26383
26415
  continue;
26384
26416
  }
@@ -26829,9 +26861,9 @@ data:
26829
26861
  const initRequest = messages.find((m) => isInitializeRequest(m));
26830
26862
  const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
26831
26863
  if (this._enableJsonResponse) {
26832
- return new Promise((resolve) => {
26864
+ return new Promise((resolve2) => {
26833
26865
  this._streamMapping.set(streamId, {
26834
- resolveJson: resolve,
26866
+ resolveJson: resolve2,
26835
26867
  cleanup: () => {
26836
26868
  this._streamMapping.delete(streamId);
26837
26869
  }
@@ -27098,7 +27130,7 @@ init_adapter();
27098
27130
  function buildServer() {
27099
27131
  const server = new McpServer({
27100
27132
  name: "cloud",
27101
- version: "0.1.0"
27133
+ version: getPackageVersion()
27102
27134
  });
27103
27135
  server.tool("cloud_status", "Show cloud configuration and connection health", {}, async () => {
27104
27136
  const config2 = getCloudConfig();
@@ -27466,16 +27498,16 @@ async function startMcpHttpServer(options = {}) {
27466
27498
  res.writeHead(404);
27467
27499
  res.end("Not found");
27468
27500
  });
27469
- await new Promise((resolve, reject) => {
27501
+ await new Promise((resolve2, reject) => {
27470
27502
  httpServer.once("error", reject);
27471
- httpServer.listen(port, host, () => resolve());
27503
+ httpServer.listen(port, host, () => resolve2());
27472
27504
  });
27473
27505
  const address = httpServer.address();
27474
27506
  const boundPort = typeof address === "object" && address ? address.port : port;
27475
27507
  return {
27476
27508
  port: boundPort,
27477
- close: () => new Promise((resolve, reject) => {
27478
- httpServer.close((err) => err ? reject(err) : resolve());
27509
+ close: () => new Promise((resolve2, reject) => {
27510
+ httpServer.close((err) => err ? reject(err) : resolve2());
27479
27511
  })
27480
27512
  };
27481
27513
  }
@@ -27489,7 +27521,7 @@ async function runMcpHttpServer(options = {}) {
27489
27521
  function buildServer2() {
27490
27522
  const server = new McpServer({
27491
27523
  name: "cloud",
27492
- version: "0.1.0"
27524
+ version: getPackageVersion()
27493
27525
  });
27494
27526
  server.tool("cloud_status", "Show cloud configuration and connection health", {}, async () => {
27495
27527
  const config2 = getCloudConfig();
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAcpE,wBAAgB,WAAW,IAAI,SAAS,CAwVvC;AAED,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAW1C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAepE,wBAAgB,WAAW,IAAI,SAAS,CAwVvC;AAED,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAW1C"}
package/dist/mcp/index.js CHANGED
@@ -16257,8 +16257,15 @@ function getConnectionString2(dbName) {
16257
16257
  if (password === undefined || password === "") {
16258
16258
  throw new Error(`RDS password not set. Export ${password_env} in your shell or add it to ~/.secrets/hasna/rds/live.env`);
16259
16259
  }
16260
- const sslParam = ssl ? "?sslmode=require" : "";
16261
- return `postgres://${username}:${encodeURIComponent(password)}@${host}:${port}/${dbName}${sslParam}`;
16260
+ const url = new URL("postgres:" + "//placeholder");
16261
+ url.hostname = host;
16262
+ url.port = String(port);
16263
+ url.username = username;
16264
+ url.password = password;
16265
+ url.pathname = `/${dbName}`;
16266
+ if (ssl)
16267
+ url.searchParams.set("sslmode", "require");
16268
+ return url.toString();
16262
16269
  }
16263
16270
  function createDatabase2(options) {
16264
16271
  const config2 = getCloudConfig2();
@@ -16299,7 +16306,7 @@ var init_config = __esm(() => {
16299
16306
  password_env: exports_external.string().default("HASNA_RDS_PASSWORD"),
16300
16307
  ssl: exports_external.boolean().default(true)
16301
16308
  }).default({}),
16302
- mode: exports_external.enum(["local", "cloud", "hybrid"]).default("hybrid"),
16309
+ mode: exports_external.enum(["local", "cloud", "hybrid"]).default("local"),
16303
16310
  auto_sync_interval_minutes: exports_external.number().default(0),
16304
16311
  feedback_endpoint: exports_external.string().default("https://feedback.hasna.com/api/v1/feedback"),
16305
16312
  sync: exports_external.object({
@@ -16321,7 +16328,7 @@ __export(exports_discover2, {
16321
16328
  SYNC_EXCLUDED_TABLE_PATTERNS: () => SYNC_EXCLUDED_TABLE_PATTERNS2,
16322
16329
  KNOWN_PG_SERVICES: () => KNOWN_PG_SERVICES2
16323
16330
  });
16324
- import { readdirSync as readdirSync4, existsSync as existsSync7 } from "fs";
16331
+ import { readdirSync as readdirSync4, existsSync as existsSync8 } from "fs";
16325
16332
  import { join as join7 } from "path";
16326
16333
  import { homedir as homedir7 } from "os";
16327
16334
  function isSyncExcludedTable2(table) {
@@ -16329,7 +16336,7 @@ function isSyncExcludedTable2(table) {
16329
16336
  }
16330
16337
  function discoverServices2() {
16331
16338
  const dataDir = join7(homedir7(), ".hasna");
16332
- if (!existsSync7(dataDir))
16339
+ if (!existsSync8(dataDir))
16333
16340
  return [];
16334
16341
  try {
16335
16342
  const entries = readdirSync4(dataDir, { withFileTypes: true });
@@ -16351,7 +16358,7 @@ function discoverSyncableServices2() {
16351
16358
  }
16352
16359
  function getServiceDbPath2(service) {
16353
16360
  const dataDir = join7(homedir7(), ".hasna", service);
16354
- if (!existsSync7(dataDir))
16361
+ if (!existsSync8(dataDir))
16355
16362
  return null;
16356
16363
  const candidates = [
16357
16364
  join7(dataDir, `${service}.db`),
@@ -16367,7 +16374,7 @@ function getServiceDbPath2(service) {
16367
16374
  }
16368
16375
  } catch {}
16369
16376
  for (const p of candidates) {
16370
- if (existsSync7(p))
16377
+ if (existsSync8(p))
16371
16378
  return p;
16372
16379
  }
16373
16380
  return null;
@@ -25584,7 +25591,7 @@ var CloudConfigSchema = exports_external.object({
25584
25591
  password_env: exports_external.string().default("HASNA_RDS_PASSWORD"),
25585
25592
  ssl: exports_external.boolean().default(true)
25586
25593
  }).default({}),
25587
- mode: exports_external.enum(["local", "cloud", "hybrid"]).default("hybrid"),
25594
+ mode: exports_external.enum(["local", "cloud", "hybrid"]).default("local"),
25588
25595
  auto_sync_interval_minutes: exports_external.number().default(0),
25589
25596
  feedback_endpoint: exports_external.string().default("https://feedback.hasna.com/api/v1/feedback"),
25590
25597
  sync: exports_external.object({
@@ -25615,8 +25622,15 @@ function getConnectionString(dbName) {
25615
25622
  if (password === undefined || password === "") {
25616
25623
  throw new Error(`RDS password not set. Export ${password_env} in your shell or add it to ~/.secrets/hasna/rds/live.env`);
25617
25624
  }
25618
- const sslParam = ssl ? "?sslmode=require" : "";
25619
- return `postgres://${username}:${encodeURIComponent(password)}@${host}:${port}/${dbName}${sslParam}`;
25625
+ const url = new URL("postgres:" + "//placeholder");
25626
+ url.hostname = host;
25627
+ url.port = String(port);
25628
+ url.username = username;
25629
+ url.password = password;
25630
+ url.pathname = `/${dbName}`;
25631
+ if (ssl)
25632
+ url.searchParams.set("sslmode", "require");
25633
+ return url.toString();
25620
25634
  }
25621
25635
  function createDatabase(options) {
25622
25636
  const config2 = getCloudConfig();
@@ -26284,6 +26298,31 @@ class PgAdapterAsync2 {
26284
26298
  }
26285
26299
  }
26286
26300
 
26301
+ // src/version.ts
26302
+ import { existsSync as existsSync7, readFileSync as readFileSync3 } from "node:fs";
26303
+ import { dirname as dirname2, resolve } from "node:path";
26304
+ import { fileURLToPath } from "node:url";
26305
+ var cachedPackageVersion;
26306
+ function getPackageVersion() {
26307
+ if (cachedPackageVersion)
26308
+ return cachedPackageVersion;
26309
+ const here = dirname2(fileURLToPath(import.meta.url));
26310
+ const candidates = [
26311
+ resolve(here, "../package.json"),
26312
+ resolve(here, "../../package.json")
26313
+ ];
26314
+ for (const path of candidates) {
26315
+ if (!existsSync7(path))
26316
+ continue;
26317
+ const pkg = JSON.parse(readFileSync3(path, "utf8"));
26318
+ if (typeof pkg.version === "string" && pkg.version.length > 0) {
26319
+ cachedPackageVersion = pkg.version;
26320
+ return cachedPackageVersion;
26321
+ }
26322
+ }
26323
+ throw new Error("Unable to resolve @hasna/cloud package version");
26324
+ }
26325
+
26287
26326
  // src/mcp/http.ts
26288
26327
  import { createServer } from "node:http";
26289
26328
 
@@ -26698,7 +26737,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
26698
26737
  });
26699
26738
  if (!chunk) {
26700
26739
  if (i === 1) {
26701
- await new Promise((resolve) => setTimeout(resolve));
26740
+ await new Promise((resolve2) => setTimeout(resolve2));
26702
26741
  maxReadCount = 3;
26703
26742
  continue;
26704
26743
  }
@@ -27149,9 +27188,9 @@ data:
27149
27188
  const initRequest = messages.find((m) => isInitializeRequest(m));
27150
27189
  const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
27151
27190
  if (this._enableJsonResponse) {
27152
- return new Promise((resolve) => {
27191
+ return new Promise((resolve2) => {
27153
27192
  this._streamMapping.set(streamId, {
27154
- resolveJson: resolve,
27193
+ resolveJson: resolve2,
27155
27194
  cleanup: () => {
27156
27195
  this._streamMapping.delete(streamId);
27157
27196
  }
@@ -27505,16 +27544,16 @@ async function startMcpHttpServer(options = {}) {
27505
27544
  res.writeHead(404);
27506
27545
  res.end("Not found");
27507
27546
  });
27508
- await new Promise((resolve, reject) => {
27547
+ await new Promise((resolve2, reject) => {
27509
27548
  httpServer.once("error", reject);
27510
- httpServer.listen(port, host, () => resolve());
27549
+ httpServer.listen(port, host, () => resolve2());
27511
27550
  });
27512
27551
  const address = httpServer.address();
27513
27552
  const boundPort = typeof address === "object" && address ? address.port : port;
27514
27553
  return {
27515
27554
  port: boundPort,
27516
- close: () => new Promise((resolve, reject) => {
27517
- httpServer.close((err) => err ? reject(err) : resolve());
27555
+ close: () => new Promise((resolve2, reject) => {
27556
+ httpServer.close((err) => err ? reject(err) : resolve2());
27518
27557
  })
27519
27558
  };
27520
27559
  }
@@ -27528,7 +27567,7 @@ async function runMcpHttpServer(options = {}) {
27528
27567
  function buildServer() {
27529
27568
  const server = new McpServer({
27530
27569
  name: "cloud",
27531
- version: "0.1.0"
27570
+ version: getPackageVersion()
27532
27571
  });
27533
27572
  server.tool("cloud_status", "Show cloud configuration and connection health", {}, async () => {
27534
27573
  const config2 = getCloudConfig();
@@ -9252,7 +9252,7 @@ var CloudConfigSchema = exports_external.object({
9252
9252
  password_env: exports_external.string().default("HASNA_RDS_PASSWORD"),
9253
9253
  ssl: exports_external.boolean().default(true)
9254
9254
  }).default({}),
9255
- mode: exports_external.enum(["local", "cloud", "hybrid"]).default("hybrid"),
9255
+ mode: exports_external.enum(["local", "cloud", "hybrid"]).default("local"),
9256
9256
  auto_sync_interval_minutes: exports_external.number().default(0),
9257
9257
  feedback_endpoint: exports_external.string().default("https://feedback.hasna.com/api/v1/feedback"),
9258
9258
  sync: exports_external.object({
@@ -9283,8 +9283,15 @@ function getConnectionString(dbName) {
9283
9283
  if (password === undefined || password === "") {
9284
9284
  throw new Error(`RDS password not set. Export ${password_env} in your shell or add it to ~/.secrets/hasna/rds/live.env`);
9285
9285
  }
9286
- const sslParam = ssl ? "?sslmode=require" : "";
9287
- return `postgres://${username}:${encodeURIComponent(password)}@${host}:${port}/${dbName}${sslParam}`;
9286
+ const url = new URL("postgres:" + "//placeholder");
9287
+ url.hostname = host;
9288
+ url.port = String(port);
9289
+ url.username = username;
9290
+ url.password = password;
9291
+ url.pathname = `/${dbName}`;
9292
+ if (ssl)
9293
+ url.searchParams.set("sslmode", "require");
9294
+ return url.toString();
9288
9295
  }
9289
9296
 
9290
9297
  // src/sync-incremental.ts
@@ -0,0 +1,2 @@
1
+ export declare function getPackageVersion(): string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAMA,wBAAgB,iBAAiB,IAAI,MAAM,CAmB1C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/cloud",
3
- "version": "0.1.38",
3
+ "version": "0.1.40",
4
4
  "description": "Shared cloud infrastructure — database adapter (SQLite + PostgreSQL), sync engine, feedback system, unified dotfile config",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -24,8 +24,7 @@
24
24
  "build": "bun build src/index.ts --outdir dist --target node && bun build src/cli/index.ts --outdir dist/cli --target node && bun build src/mcp/index.ts --outdir dist/mcp --target node && bun build src/mcp/bin.ts --outfile dist/mcp/bin.js --target node && chmod +x dist/mcp/bin.js && bun build src/scheduled-sync.ts --outdir dist --target node && bun run build:types",
25
25
  "build:types": "tsc --emitDeclarationOnly --declaration --outDir dist",
26
26
  "test": "bun test",
27
- "prepublishOnly": "bun run build",
28
- "postinstall": "mkdir -p $HOME/.hasna/cloud 2>/dev/null || true; test -f $HOME/.hasna/cloud/config.json || printf '{\"rds\":{\"host\":\"hasnaxyz-prod-opensource.c4limg0qgqvk.us-east-1.rds.amazonaws.com\",\"port\":5432,\"username\":\"\",\"password_env\":\"HASNA_RDS_PASSWORD\",\"ssl\":true},\"mode\":\"local\",\"feedback_endpoint\":\"https://feedback.hasna.com/api/v1/feedback\",\"auto_sync_interval_minutes\":0,\"sync\":{\"schedule_minutes\":0}}\\n' > $HOME/.hasna/cloud/config.json 2>/dev/null || true"
27
+ "prepublishOnly": "bun run build"
29
28
  },
30
29
  "publishConfig": {
31
30
  "registry": "https://registry.npmjs.org",