@hasna/recordings 0.1.34 → 0.1.36

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.
@@ -1,7 +1,7 @@
1
1
  export type StorageMode = "local" | "hybrid" | "remote";
2
2
  export interface StorageConfig {
3
3
  mode: StorageMode;
4
- rds: {
4
+ postgres: {
5
5
  host: string;
6
6
  port: number;
7
7
  username: string;
@@ -16,6 +16,7 @@ export declare const RECORDINGS_STORAGE_ENV = "HASNA_RECORDINGS_DATABASE_URL";
16
16
  export declare const RECORDINGS_STORAGE_FALLBACK_ENV = "RECORDINGS_DATABASE_URL";
17
17
  export declare const RECORDINGS_STORAGE_MODE_ENV = "HASNA_RECORDINGS_STORAGE_MODE";
18
18
  export declare const RECORDINGS_STORAGE_MODE_FALLBACK_ENV = "RECORDINGS_STORAGE_MODE";
19
+ export declare const RECORDINGS_STORAGE_CONFIG_ENV = "HASNA_RECORDINGS_STORAGE_CONFIG";
19
20
  export declare const STORAGE_DATABASE_ENV: readonly ["HASNA_RECORDINGS_DATABASE_URL", "RECORDINGS_DATABASE_URL"];
20
21
  export declare const STORAGE_MODE_ENV: readonly ["HASNA_RECORDINGS_STORAGE_MODE", "RECORDINGS_STORAGE_MODE"];
21
22
  export declare function getStorageDatabaseEnvName(): (typeof STORAGE_DATABASE_ENV)[number] | null;
@@ -1 +1 @@
1
- {"version":3,"file":"storage-config.d.ts","sourceRoot":"","sources":["../../src/db/storage-config.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,GAAG,EAAE;QACH,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,GAAG,EAAE,OAAO,CAAC;KACd,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;CACd;AAGD,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AACtE,eAAO,MAAM,+BAA+B,4BAA4B,CAAC;AACzE,eAAO,MAAM,2BAA2B,kCAAkC,CAAC;AAC3E,eAAO,MAAM,oCAAoC,4BAA4B,CAAC;AAC9E,eAAO,MAAM,oBAAoB,uEAAqE,CAAC;AACvG,eAAO,MAAM,gBAAgB,uEAA+E,CAAC;AAa7G,wBAAgB,yBAAyB,IAAI,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAKxF;AAED,wBAAgB,qBAAqB,IAAI,UAAU,GAAG,IAAI,CAGzD;AAED,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,SAAS,CAG1D;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CA+BhD;AAED,wBAAgB,0BAA0B,CAAC,MAAM,SAAe,GAAG,MAAM,CAiBxE;AAED,eAAO,MAAM,mBAAmB,mCAA6B,CAAC"}
1
+ {"version":3,"file":"storage-config.d.ts","sourceRoot":"","sources":["../../src/db/storage-config.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,GAAG,EAAE,OAAO,CAAC;KACd,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;CACd;AAGD,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AACtE,eAAO,MAAM,+BAA+B,4BAA4B,CAAC;AACzE,eAAO,MAAM,2BAA2B,kCAAkC,CAAC;AAC3E,eAAO,MAAM,oCAAoC,4BAA4B,CAAC;AAC9E,eAAO,MAAM,6BAA6B,oCAAoC,CAAC;AAC/E,eAAO,MAAM,oBAAoB,uEAAqE,CAAC;AACvG,eAAO,MAAM,gBAAgB,uEAA+E,CAAC;AAa7G,wBAAgB,yBAAyB,IAAI,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAKxF;AAED,wBAAgB,qBAAqB,IAAI,UAAU,GAAG,IAAI,CAGzD;AAED,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,SAAS,CAG1D;AAQD,wBAAgB,gBAAgB,IAAI,aAAa,CAoChD;AAED,wBAAgB,0BAA0B,CAAC,MAAM,SAAe,GAAG,MAAM,CAiBxE;AAED,eAAO,MAAM,mBAAmB,mCAA6B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"storage-sync.d.ts","sourceRoot":"","sources":["../../src/db/storage-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EACL,oBAAoB,EAIpB,KAAK,WAAW,EACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAKrD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,OAAO,oBAAoB,CAAC;IACjC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,eAAO,MAAM,cAAc,6EAMjB,CAAC;AAEX,eAAO,MAAM,yBAAyB,6EAAiB,CAAC;AA6ExD,wBAAsB,YAAY,IAAI,OAAO,CAAC,cAAc,CAAC,CAE5D;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhF;AAED,wBAAgB,gBAAgB,CAAC,EAAE,GAAE,QAAwB,GAAG,aAAa,CAoB5E;AAED,wBAAsB,kBAAkB,CAAC,MAAM,GAAE,MAAM,EAAwB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAuBtG;AAED,wBAAsB,kBAAkB,CAAC,MAAM,GAAE,MAAM,EAAwB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAuBtG;AAED,wBAAsB,kBAAkB,CAAC,MAAM,GAAE,MAAM,EAAwB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,UAAU,EAAE,CAAA;CAAE,CAAC,CAKpI;AAED,wBAAgB,kBAAkB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAQzD"}
1
+ {"version":3,"file":"storage-sync.d.ts","sourceRoot":"","sources":["../../src/db/storage-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EACL,oBAAoB,EAIpB,KAAK,WAAW,EACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAKrD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,OAAO,oBAAoB,CAAC;IACjC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,eAAO,MAAM,cAAc,6EAMjB,CAAC;AAEX,eAAO,MAAM,yBAAyB,6EAAiB,CAAC;AA6ExD,wBAAsB,YAAY,IAAI,OAAO,CAAC,cAAc,CAAC,CAE5D;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhF;AAED,wBAAgB,gBAAgB,CAAC,EAAE,GAAE,QAAwB,GAAG,aAAa,CAqB5E;AAED,wBAAsB,kBAAkB,CAAC,MAAM,GAAE,MAAM,EAAwB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAuBtG;AAED,wBAAsB,kBAAkB,CAAC,MAAM,GAAE,MAAM,EAAwB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAuBtG;AAED,wBAAsB,kBAAkB,CAAC,MAAM,GAAE,MAAM,EAAwB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,UAAU,EAAE,CAAA;CAAE,CAAC,CAKpI;AAED,wBAAgB,kBAAkB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAQzD"}
package/dist/index.js CHANGED
@@ -2940,7 +2940,7 @@ var require_dist = __commonJS((exports) => {
2940
2940
  function parse(stream, callback) {
2941
2941
  const parser = new parser_1.Parser;
2942
2942
  stream.on("data", (buffer) => parser.parse(buffer, callback));
2943
- return new Promise((resolve) => stream.on("end", () => resolve()));
2943
+ return new Promise((resolve2) => stream.on("end", () => resolve2()));
2944
2944
  }
2945
2945
  exports.parse = parse;
2946
2946
  });
@@ -3619,12 +3619,12 @@ var require_client = __commonJS((exports, module) => {
3619
3619
  this._connect(callback);
3620
3620
  return;
3621
3621
  }
3622
- return new this._Promise((resolve, reject) => {
3622
+ return new this._Promise((resolve2, reject) => {
3623
3623
  this._connect((error) => {
3624
3624
  if (error) {
3625
3625
  reject(error);
3626
3626
  } else {
3627
- resolve(this);
3627
+ resolve2(this);
3628
3628
  }
3629
3629
  });
3630
3630
  });
@@ -3956,8 +3956,8 @@ var require_client = __commonJS((exports, module) => {
3956
3956
  readTimeout = config.query_timeout || this.connectionParameters.query_timeout;
3957
3957
  query = new Query(config, values, callback);
3958
3958
  if (!query.callback) {
3959
- result = new this._Promise((resolve, reject) => {
3960
- query.callback = (err, res) => err ? reject(err) : resolve(res);
3959
+ result = new this._Promise((resolve2, reject) => {
3960
+ query.callback = (err, res) => err ? reject(err) : resolve2(res);
3961
3961
  }).catch((err) => {
3962
3962
  Error.captureStackTrace(err);
3963
3963
  throw err;
@@ -4032,8 +4032,8 @@ var require_client = __commonJS((exports, module) => {
4032
4032
  if (cb) {
4033
4033
  this.connection.once("end", cb);
4034
4034
  } else {
4035
- return new this._Promise((resolve) => {
4036
- this.connection.once("end", resolve);
4035
+ return new this._Promise((resolve2) => {
4036
+ this.connection.once("end", resolve2);
4037
4037
  });
4038
4038
  }
4039
4039
  }
@@ -4080,8 +4080,8 @@ var require_pg_pool = __commonJS((exports, module) => {
4080
4080
  const cb = function(err, client) {
4081
4081
  err ? rej(err) : res(client);
4082
4082
  };
4083
- const result = new Promise2(function(resolve, reject) {
4084
- res = resolve;
4083
+ const result = new Promise2(function(resolve2, reject) {
4084
+ res = resolve2;
4085
4085
  rej = reject;
4086
4086
  }).catch((err) => {
4087
4087
  Error.captureStackTrace(err);
@@ -4142,7 +4142,7 @@ var require_pg_pool = __commonJS((exports, module) => {
4142
4142
  if (typeof Promise2.try === "function") {
4143
4143
  return Promise2.try(f);
4144
4144
  }
4145
- return new Promise2((resolve) => resolve(f()));
4145
+ return new Promise2((resolve2) => resolve2(f()));
4146
4146
  }
4147
4147
  _isFull() {
4148
4148
  return this._clients.length >= this.options.max;
@@ -4518,8 +4518,8 @@ var require_query2 = __commonJS((exports, module) => {
4518
4518
  NativeQuery.prototype._getPromise = function() {
4519
4519
  if (this._promise)
4520
4520
  return this._promise;
4521
- this._promise = new Promise(function(resolve, reject) {
4522
- this._once("end", resolve);
4521
+ this._promise = new Promise(function(resolve2, reject) {
4522
+ this._once("end", resolve2);
4523
4523
  this._once("error", reject);
4524
4524
  }.bind(this));
4525
4525
  return this._promise;
@@ -4693,12 +4693,12 @@ var require_client2 = __commonJS((exports, module) => {
4693
4693
  this._connect(callback);
4694
4694
  return;
4695
4695
  }
4696
- return new this._Promise((resolve, reject) => {
4696
+ return new this._Promise((resolve2, reject) => {
4697
4697
  this._connect((error) => {
4698
4698
  if (error) {
4699
4699
  reject(error);
4700
4700
  } else {
4701
- resolve(this);
4701
+ resolve2(this);
4702
4702
  }
4703
4703
  });
4704
4704
  });
@@ -4722,8 +4722,8 @@ var require_client2 = __commonJS((exports, module) => {
4722
4722
  query = new NativeQuery(config, values, callback);
4723
4723
  if (!query.callback) {
4724
4724
  let resolveOut, rejectOut;
4725
- result = new this._Promise((resolve, reject) => {
4726
- resolveOut = resolve;
4725
+ result = new this._Promise((resolve2, reject) => {
4726
+ resolveOut = resolve2;
4727
4727
  rejectOut = reject;
4728
4728
  }).catch((err) => {
4729
4729
  Error.captureStackTrace(err);
@@ -4781,8 +4781,8 @@ var require_client2 = __commonJS((exports, module) => {
4781
4781
  }
4782
4782
  let result;
4783
4783
  if (!cb) {
4784
- result = new this._Promise(function(resolve, reject) {
4785
- cb = (err) => err ? reject(err) : resolve();
4784
+ result = new this._Promise(function(resolve2, reject) {
4785
+ cb = (err) => err ? reject(err) : resolve2();
4786
4786
  });
4787
4787
  }
4788
4788
  this.native.end(function() {
@@ -4963,11 +4963,11 @@ class SqliteAdapter {
4963
4963
 
4964
4964
  // src/db/database.ts
4965
4965
  import { mkdirSync as mkdirSync2 } from "fs";
4966
- import { dirname } from "path";
4966
+ import { dirname as dirname2 } from "path";
4967
4967
 
4968
4968
  // src/lib/config.ts
4969
- import { existsSync, readFileSync, mkdirSync, cpSync, readdirSync, statSync } from "fs";
4970
- import { join } from "path";
4969
+ import { copyFileSync, existsSync, readFileSync, mkdirSync, readdirSync, statSync } from "fs";
4970
+ import { dirname, join, resolve } from "path";
4971
4971
  import { homedir } from "os";
4972
4972
  var DEFAULT_CONFIG = {
4973
4973
  openai_api_key: "",
@@ -5061,44 +5061,53 @@ function expandEnvBackedConfig(config) {
5061
5061
  return expanded;
5062
5062
  }
5063
5063
  function findConfigFile() {
5064
- let dir = process.cwd();
5065
- const root = "/";
5066
- while (dir !== root) {
5067
- const candidate = join(dir, ".recordings", "config.json");
5068
- if (existsSync(candidate))
5069
- return candidate;
5070
- const parent = join(dir, "..");
5071
- if (parent === dir)
5072
- break;
5073
- dir = parent;
5074
- }
5075
- return null;
5064
+ return findProjectRecordingsPath("config.json");
5076
5065
  }
5077
5066
  function getDataDir() {
5078
- let dir = process.cwd();
5079
- const root = "/";
5080
- while (dir !== root) {
5081
- const candidate = join(dir, ".recordings");
5082
- if (existsSync(candidate))
5083
- return candidate;
5084
- const parent = join(dir, "..");
5085
- if (parent === dir)
5086
- break;
5087
- dir = parent;
5088
- }
5089
- const home = homedir();
5067
+ const projectLocalDir = findProjectRecordingsPath();
5068
+ if (projectLocalDir)
5069
+ return projectLocalDir;
5070
+ const home = getHomeDir();
5090
5071
  const newDir = join(home, ".hasna", "recordings");
5091
5072
  const oldDir = join(home, ".recordings");
5092
- if (!existsSync(newDir) && existsSync(oldDir)) {
5073
+ if (existsSync(oldDir)) {
5093
5074
  try {
5094
- mkdirSync(join(home, ".hasna"), { recursive: true });
5095
- cpSync(oldDir, newDir, { recursive: true });
5075
+ mergeDirectoryContents(oldDir, newDir);
5096
5076
  } catch {}
5097
5077
  }
5098
5078
  return newDir;
5099
5079
  }
5080
+ function findProjectRecordingsPath(entry) {
5081
+ const home = resolve(getHomeDir());
5082
+ let dir = resolve(process.cwd());
5083
+ while (true) {
5084
+ if (dir !== home) {
5085
+ const candidate = entry ? join(dir, ".recordings", entry) : join(dir, ".recordings");
5086
+ if (existsSync(candidate))
5087
+ return candidate;
5088
+ }
5089
+ const parent = dirname(dir);
5090
+ if (parent === dir)
5091
+ break;
5092
+ dir = parent;
5093
+ }
5094
+ return null;
5095
+ }
5096
+ function mergeDirectoryContents(sourceDir, targetDir) {
5097
+ mkdirSync(targetDir, { recursive: true });
5098
+ for (const entry of readdirSync(sourceDir)) {
5099
+ const sourcePath = join(sourceDir, entry);
5100
+ const targetPath = join(targetDir, entry);
5101
+ const sourceStats = statSync(sourcePath);
5102
+ if (sourceStats.isDirectory()) {
5103
+ mergeDirectoryContents(sourcePath, targetPath);
5104
+ } else if (!existsSync(targetPath)) {
5105
+ copyFileSync(sourcePath, targetPath);
5106
+ }
5107
+ }
5108
+ }
5100
5109
  function loadSecretKey(keyName) {
5101
- const secretsPath = join(homedir(), ".secrets");
5110
+ const secretsPath = join(getHomeDir(), ".secrets");
5102
5111
  if (!existsSync(secretsPath))
5103
5112
  return "";
5104
5113
  for (const candidate of listSecretFiles(secretsPath)) {
@@ -5139,6 +5148,9 @@ function listSecretFiles(path) {
5139
5148
  return [];
5140
5149
  }
5141
5150
  }
5151
+ function getHomeDir() {
5152
+ return process.env["HOME"] || process.env["USERPROFILE"] || homedir();
5153
+ }
5142
5154
  function ensureDataDir(config) {
5143
5155
  const { mkdirSync: mkdirSync2 } = __require("fs");
5144
5156
  mkdirSync2(config.audio_dir, { recursive: true });
@@ -5233,7 +5245,7 @@ function getDatabase(dbPath) {
5233
5245
  if (_db)
5234
5246
  return _db;
5235
5247
  const path = dbPath || loadConfig().db_path;
5236
- const dir = dirname(path);
5248
+ const dir = dirname2(path);
5237
5249
  mkdirSync2(dir, { recursive: true });
5238
5250
  _adapter = new SqliteAdapter(path);
5239
5251
  _db = _adapter.raw;
@@ -5359,11 +5371,12 @@ class PgAdapterAsync {
5359
5371
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
5360
5372
  import { homedir as homedir2 } from "os";
5361
5373
  import { join as join2 } from "path";
5362
- var STORAGE_CONFIG_PATH = join2(homedir2(), ".hasna", "recordings", "storage", "config.json");
5374
+ var LEGACY_DATABASE_CONFIG_KEY = ["r", "d", "s"].join("");
5363
5375
  var RECORDINGS_STORAGE_ENV = "HASNA_RECORDINGS_DATABASE_URL";
5364
5376
  var RECORDINGS_STORAGE_FALLBACK_ENV = "RECORDINGS_DATABASE_URL";
5365
5377
  var RECORDINGS_STORAGE_MODE_ENV = "HASNA_RECORDINGS_STORAGE_MODE";
5366
5378
  var RECORDINGS_STORAGE_MODE_FALLBACK_ENV = "RECORDINGS_STORAGE_MODE";
5379
+ var RECORDINGS_STORAGE_CONFIG_ENV = "HASNA_RECORDINGS_STORAGE_CONFIG";
5367
5380
  var STORAGE_DATABASE_ENV = [RECORDINGS_STORAGE_ENV, RECORDINGS_STORAGE_FALLBACK_ENV];
5368
5381
  var STORAGE_MODE_ENV = [RECORDINGS_STORAGE_MODE_ENV, RECORDINGS_STORAGE_MODE_FALLBACK_ENV];
5369
5382
  function readEnv(name) {
@@ -5391,10 +5404,16 @@ function getStorageDatabaseUrl() {
5391
5404
  const env = getStorageDatabaseEnv();
5392
5405
  return env ? readEnv(env.name) : undefined;
5393
5406
  }
5407
+ function getStorageConfigPath() {
5408
+ const override = readEnv(RECORDINGS_STORAGE_CONFIG_ENV);
5409
+ if (override)
5410
+ return override;
5411
+ return join2(homedir2(), ".hasna", "recordings", "storage", "config.json");
5412
+ }
5394
5413
  function getStorageConfig() {
5395
5414
  const config = {
5396
5415
  mode: "local",
5397
- rds: {
5416
+ postgres: {
5398
5417
  host: "",
5399
5418
  port: 5432,
5400
5419
  username: "",
@@ -5402,11 +5421,13 @@ function getStorageConfig() {
5402
5421
  ssl: true
5403
5422
  }
5404
5423
  };
5405
- if (existsSync2(STORAGE_CONFIG_PATH)) {
5424
+ const storageConfigPath = getStorageConfigPath();
5425
+ if (existsSync2(storageConfigPath)) {
5406
5426
  try {
5407
- const raw = JSON.parse(readFileSync2(STORAGE_CONFIG_PATH, "utf-8"));
5427
+ const raw = JSON.parse(readFileSync2(storageConfigPath, "utf-8"));
5428
+ const legacyDatabaseConfig = typeof raw[LEGACY_DATABASE_CONFIG_KEY] === "object" && raw[LEGACY_DATABASE_CONFIG_KEY] !== null ? raw[LEGACY_DATABASE_CONFIG_KEY] : {};
5408
5429
  config.mode = normalizeMode(raw.mode) ?? config.mode;
5409
- config.rds = { ...config.rds, ...raw.rds ?? {} };
5430
+ config.postgres = { ...config.postgres, ...legacyDatabaseConfig, ...raw.postgres ?? {} };
5410
5431
  } catch {}
5411
5432
  }
5412
5433
  const modeOverride = readEnv(RECORDINGS_STORAGE_MODE_ENV) ?? readEnv(RECORDINGS_STORAGE_MODE_FALLBACK_ENV);
@@ -5423,7 +5444,7 @@ function getStorageConnectionString(dbName = "recordings") {
5423
5444
  if (direct)
5424
5445
  return direct;
5425
5446
  const config = getStorageConfig();
5426
- const { host, port, username, password_env, ssl } = config.rds;
5447
+ const { host, port, username, password_env, ssl } = config.postgres;
5427
5448
  if (!host || !username) {
5428
5449
  throw new Error("Storage database is not configured. Set HASNA_RECORDINGS_DATABASE_URL or configure ~/.hasna/recordings/storage/config.json.");
5429
5450
  }
@@ -5575,8 +5596,9 @@ async function runStorageMigrations(remote) {
5575
5596
  function getStorageStatus(db = getDatabase()) {
5576
5597
  const config = getStorageConfig();
5577
5598
  const activeEnv = getStorageDatabaseEnv();
5599
+ const hasConfiguredPostgres = Boolean(config.postgres.host && config.postgres.username);
5578
5600
  return {
5579
- configured: Boolean(activeEnv),
5601
+ configured: Boolean(activeEnv) || hasConfiguredPostgres,
5580
5602
  mode: config.mode,
5581
5603
  enabled: config.mode === "hybrid" || config.mode === "remote",
5582
5604
  env: STORAGE_DATABASE_ENV,
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,eAAO,MAAM,cAAc,EAAE,gBA2B5B,CAAC;AAEF,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAqEhE;AA6BD,wBAAgB,UAAU,IAAI,MAAM,CA4BnC;AAqDD,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAU5D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,eAAO,MAAM,cAAc,EAAE,gBA2B5B,CAAC;AAEF,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAqEhE;AAmBD,wBAAgB,UAAU,IAAI,MAAM,CAoBnC;AAwFD,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAU5D"}
package/dist/mcp/index.js CHANGED
@@ -2954,7 +2954,7 @@ var require_dist = __commonJS((exports) => {
2954
2954
  function parse(stream, callback) {
2955
2955
  const parser = new parser_1.Parser;
2956
2956
  stream.on("data", (buffer) => parser.parse(buffer, callback));
2957
- return new Promise((resolve) => stream.on("end", () => resolve()));
2957
+ return new Promise((resolve2) => stream.on("end", () => resolve2()));
2958
2958
  }
2959
2959
  exports.parse = parse;
2960
2960
  });
@@ -3633,12 +3633,12 @@ var require_client = __commonJS((exports, module) => {
3633
3633
  this._connect(callback);
3634
3634
  return;
3635
3635
  }
3636
- return new this._Promise((resolve, reject) => {
3636
+ return new this._Promise((resolve2, reject) => {
3637
3637
  this._connect((error) => {
3638
3638
  if (error) {
3639
3639
  reject(error);
3640
3640
  } else {
3641
- resolve(this);
3641
+ resolve2(this);
3642
3642
  }
3643
3643
  });
3644
3644
  });
@@ -3970,8 +3970,8 @@ var require_client = __commonJS((exports, module) => {
3970
3970
  readTimeout = config.query_timeout || this.connectionParameters.query_timeout;
3971
3971
  query = new Query(config, values, callback);
3972
3972
  if (!query.callback) {
3973
- result = new this._Promise((resolve, reject) => {
3974
- query.callback = (err, res) => err ? reject(err) : resolve(res);
3973
+ result = new this._Promise((resolve2, reject) => {
3974
+ query.callback = (err, res) => err ? reject(err) : resolve2(res);
3975
3975
  }).catch((err) => {
3976
3976
  Error.captureStackTrace(err);
3977
3977
  throw err;
@@ -4046,8 +4046,8 @@ var require_client = __commonJS((exports, module) => {
4046
4046
  if (cb) {
4047
4047
  this.connection.once("end", cb);
4048
4048
  } else {
4049
- return new this._Promise((resolve) => {
4050
- this.connection.once("end", resolve);
4049
+ return new this._Promise((resolve2) => {
4050
+ this.connection.once("end", resolve2);
4051
4051
  });
4052
4052
  }
4053
4053
  }
@@ -4094,8 +4094,8 @@ var require_pg_pool = __commonJS((exports, module) => {
4094
4094
  const cb = function(err, client) {
4095
4095
  err ? rej(err) : res(client);
4096
4096
  };
4097
- const result = new Promise2(function(resolve, reject) {
4098
- res = resolve;
4097
+ const result = new Promise2(function(resolve2, reject) {
4098
+ res = resolve2;
4099
4099
  rej = reject;
4100
4100
  }).catch((err) => {
4101
4101
  Error.captureStackTrace(err);
@@ -4156,7 +4156,7 @@ var require_pg_pool = __commonJS((exports, module) => {
4156
4156
  if (typeof Promise2.try === "function") {
4157
4157
  return Promise2.try(f);
4158
4158
  }
4159
- return new Promise2((resolve) => resolve(f()));
4159
+ return new Promise2((resolve2) => resolve2(f()));
4160
4160
  }
4161
4161
  _isFull() {
4162
4162
  return this._clients.length >= this.options.max;
@@ -4532,8 +4532,8 @@ var require_query2 = __commonJS((exports, module) => {
4532
4532
  NativeQuery.prototype._getPromise = function() {
4533
4533
  if (this._promise)
4534
4534
  return this._promise;
4535
- this._promise = new Promise(function(resolve, reject) {
4536
- this._once("end", resolve);
4535
+ this._promise = new Promise(function(resolve2, reject) {
4536
+ this._once("end", resolve2);
4537
4537
  this._once("error", reject);
4538
4538
  }.bind(this));
4539
4539
  return this._promise;
@@ -4707,12 +4707,12 @@ var require_client2 = __commonJS((exports, module) => {
4707
4707
  this._connect(callback);
4708
4708
  return;
4709
4709
  }
4710
- return new this._Promise((resolve, reject) => {
4710
+ return new this._Promise((resolve2, reject) => {
4711
4711
  this._connect((error) => {
4712
4712
  if (error) {
4713
4713
  reject(error);
4714
4714
  } else {
4715
- resolve(this);
4715
+ resolve2(this);
4716
4716
  }
4717
4717
  });
4718
4718
  });
@@ -4736,8 +4736,8 @@ var require_client2 = __commonJS((exports, module) => {
4736
4736
  query = new NativeQuery(config, values, callback);
4737
4737
  if (!query.callback) {
4738
4738
  let resolveOut, rejectOut;
4739
- result = new this._Promise((resolve, reject) => {
4740
- resolveOut = resolve;
4739
+ result = new this._Promise((resolve2, reject) => {
4740
+ resolveOut = resolve2;
4741
4741
  rejectOut = reject;
4742
4742
  }).catch((err) => {
4743
4743
  Error.captureStackTrace(err);
@@ -4795,8 +4795,8 @@ var require_client2 = __commonJS((exports, module) => {
4795
4795
  }
4796
4796
  let result;
4797
4797
  if (!cb) {
4798
- result = new this._Promise(function(resolve, reject) {
4799
- cb = (err) => err ? reject(err) : resolve();
4798
+ result = new this._Promise(function(resolve2, reject) {
4799
+ cb = (err) => err ? reject(err) : resolve2();
4800
4800
  });
4801
4801
  }
4802
4802
  this.native.end(function() {
@@ -4920,7 +4920,7 @@ var require_lib2 = __commonJS((exports, module) => {
4920
4920
  var require_package = __commonJS((exports, module) => {
4921
4921
  module.exports = {
4922
4922
  name: "@hasna/recordings",
4923
- version: "0.1.34",
4923
+ version: "0.1.36",
4924
4924
  type: "module",
4925
4925
  description: "Speech-to-text recording tool with MCP and CLI \u2014 records, transcribes, and optionally enhances text using AI",
4926
4926
  repository: {
@@ -4954,7 +4954,9 @@ var require_package = __commonJS((exports, module) => {
4954
4954
  "test:coverage": "bun test --coverage",
4955
4955
  "dev:cli": "bun run src/cli/index.ts",
4956
4956
  "dev:mcp": "bun run src/mcp/index.ts",
4957
- prepack: "bun run build",
4957
+ "verify:release": "bun run scripts/release-guard.ts",
4958
+ prepack: "bun run build && bun run verify:release",
4959
+ prepublishOnly: "bun run typecheck && bun run test",
4958
4960
  postinstall: "bash scripts/install_macos_app.sh --postinstall"
4959
4961
  },
4960
4962
  files: [
@@ -4970,7 +4972,7 @@ var require_package = __commonJS((exports, module) => {
4970
4972
  "LICENSE"
4971
4973
  ],
4972
4974
  dependencies: {
4973
- "@hasna/events": "^0.1.7",
4975
+ "@hasna/events": "^0.1.11",
4974
4976
  "@modelcontextprotocol/sdk": "^1.12.1",
4975
4977
  chalk: "^5.4.1",
4976
4978
  commander: "^13.1.0",
@@ -9015,8 +9017,8 @@ var coerce = {
9015
9017
  };
9016
9018
  var NEVER = INVALID;
9017
9019
  // src/lib/config.ts
9018
- import { existsSync, readFileSync, mkdirSync, cpSync, readdirSync, statSync } from "fs";
9019
- import { join } from "path";
9020
+ import { copyFileSync, existsSync, readFileSync, mkdirSync, readdirSync, statSync } from "fs";
9021
+ import { dirname, join, resolve } from "path";
9020
9022
  import { homedir } from "os";
9021
9023
  var DEFAULT_CONFIG = {
9022
9024
  openai_api_key: "",
@@ -9110,44 +9112,53 @@ function expandEnvBackedConfig(config) {
9110
9112
  return expanded;
9111
9113
  }
9112
9114
  function findConfigFile() {
9113
- let dir = process.cwd();
9114
- const root = "/";
9115
- while (dir !== root) {
9116
- const candidate = join(dir, ".recordings", "config.json");
9117
- if (existsSync(candidate))
9118
- return candidate;
9119
- const parent = join(dir, "..");
9120
- if (parent === dir)
9121
- break;
9122
- dir = parent;
9123
- }
9124
- return null;
9115
+ return findProjectRecordingsPath("config.json");
9125
9116
  }
9126
9117
  function getDataDir() {
9127
- let dir = process.cwd();
9128
- const root = "/";
9129
- while (dir !== root) {
9130
- const candidate = join(dir, ".recordings");
9131
- if (existsSync(candidate))
9132
- return candidate;
9133
- const parent = join(dir, "..");
9134
- if (parent === dir)
9135
- break;
9136
- dir = parent;
9137
- }
9138
- const home = homedir();
9118
+ const projectLocalDir = findProjectRecordingsPath();
9119
+ if (projectLocalDir)
9120
+ return projectLocalDir;
9121
+ const home = getHomeDir();
9139
9122
  const newDir = join(home, ".hasna", "recordings");
9140
9123
  const oldDir = join(home, ".recordings");
9141
- if (!existsSync(newDir) && existsSync(oldDir)) {
9124
+ if (existsSync(oldDir)) {
9142
9125
  try {
9143
- mkdirSync(join(home, ".hasna"), { recursive: true });
9144
- cpSync(oldDir, newDir, { recursive: true });
9126
+ mergeDirectoryContents(oldDir, newDir);
9145
9127
  } catch {}
9146
9128
  }
9147
9129
  return newDir;
9148
9130
  }
9131
+ function findProjectRecordingsPath(entry) {
9132
+ const home = resolve(getHomeDir());
9133
+ let dir = resolve(process.cwd());
9134
+ while (true) {
9135
+ if (dir !== home) {
9136
+ const candidate = entry ? join(dir, ".recordings", entry) : join(dir, ".recordings");
9137
+ if (existsSync(candidate))
9138
+ return candidate;
9139
+ }
9140
+ const parent = dirname(dir);
9141
+ if (parent === dir)
9142
+ break;
9143
+ dir = parent;
9144
+ }
9145
+ return null;
9146
+ }
9147
+ function mergeDirectoryContents(sourceDir, targetDir) {
9148
+ mkdirSync(targetDir, { recursive: true });
9149
+ for (const entry of readdirSync(sourceDir)) {
9150
+ const sourcePath = join(sourceDir, entry);
9151
+ const targetPath = join(targetDir, entry);
9152
+ const sourceStats = statSync(sourcePath);
9153
+ if (sourceStats.isDirectory()) {
9154
+ mergeDirectoryContents(sourcePath, targetPath);
9155
+ } else if (!existsSync(targetPath)) {
9156
+ copyFileSync(sourcePath, targetPath);
9157
+ }
9158
+ }
9159
+ }
9149
9160
  function loadSecretKey(keyName) {
9150
- const secretsPath = join(homedir(), ".secrets");
9161
+ const secretsPath = join(getHomeDir(), ".secrets");
9151
9162
  if (!existsSync(secretsPath))
9152
9163
  return "";
9153
9164
  for (const candidate of listSecretFiles(secretsPath)) {
@@ -9188,6 +9199,9 @@ function listSecretFiles(path) {
9188
9199
  return [];
9189
9200
  }
9190
9201
  }
9202
+ function getHomeDir() {
9203
+ return process.env["HOME"] || process.env["USERPROFILE"] || homedir();
9204
+ }
9191
9205
  function ensureDataDir(config) {
9192
9206
  const { mkdirSync: mkdirSync2 } = __require("fs");
9193
9207
  mkdirSync2(config.audio_dir, { recursive: true });
@@ -9229,7 +9243,7 @@ class SqliteAdapter {
9229
9243
 
9230
9244
  // src/db/database.ts
9231
9245
  import { mkdirSync as mkdirSync2 } from "fs";
9232
- import { dirname } from "path";
9246
+ import { dirname as dirname2 } from "path";
9233
9247
  var _db = null;
9234
9248
  var _adapter = null;
9235
9249
  var MIGRATIONS = [
@@ -9315,7 +9329,7 @@ function getDatabase(dbPath) {
9315
9329
  if (_db)
9316
9330
  return _db;
9317
9331
  const path = dbPath || loadConfig().db_path;
9318
- const dir = dirname(path);
9332
+ const dir = dirname2(path);
9319
9333
  mkdirSync2(dir, { recursive: true });
9320
9334
  _adapter = new SqliteAdapter(path);
9321
9335
  _db = _adapter.raw;
@@ -9798,17 +9812,18 @@ async function processText(rawText, config, systemPrompt) {
9798
9812
  }
9799
9813
 
9800
9814
  // src/version.ts
9801
- var VERSION = "0.1.33";
9815
+ var VERSION = "0.1.36";
9802
9816
 
9803
9817
  // src/db/storage-config.ts
9804
9818
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
9805
9819
  import { homedir as homedir2 } from "os";
9806
9820
  import { join as join2 } from "path";
9807
- var STORAGE_CONFIG_PATH = join2(homedir2(), ".hasna", "recordings", "storage", "config.json");
9821
+ var LEGACY_DATABASE_CONFIG_KEY = ["r", "d", "s"].join("");
9808
9822
  var RECORDINGS_STORAGE_ENV = "HASNA_RECORDINGS_DATABASE_URL";
9809
9823
  var RECORDINGS_STORAGE_FALLBACK_ENV = "RECORDINGS_DATABASE_URL";
9810
9824
  var RECORDINGS_STORAGE_MODE_ENV = "HASNA_RECORDINGS_STORAGE_MODE";
9811
9825
  var RECORDINGS_STORAGE_MODE_FALLBACK_ENV = "RECORDINGS_STORAGE_MODE";
9826
+ var RECORDINGS_STORAGE_CONFIG_ENV = "HASNA_RECORDINGS_STORAGE_CONFIG";
9812
9827
  var STORAGE_DATABASE_ENV = [RECORDINGS_STORAGE_ENV, RECORDINGS_STORAGE_FALLBACK_ENV];
9813
9828
  function readEnv(name) {
9814
9829
  const value = process.env[name]?.trim();
@@ -9835,10 +9850,16 @@ function getStorageDatabaseUrl() {
9835
9850
  const env = getStorageDatabaseEnv();
9836
9851
  return env ? readEnv(env.name) : undefined;
9837
9852
  }
9853
+ function getStorageConfigPath() {
9854
+ const override = readEnv(RECORDINGS_STORAGE_CONFIG_ENV);
9855
+ if (override)
9856
+ return override;
9857
+ return join2(homedir2(), ".hasna", "recordings", "storage", "config.json");
9858
+ }
9838
9859
  function getStorageConfig() {
9839
9860
  const config = {
9840
9861
  mode: "local",
9841
- rds: {
9862
+ postgres: {
9842
9863
  host: "",
9843
9864
  port: 5432,
9844
9865
  username: "",
@@ -9846,11 +9867,13 @@ function getStorageConfig() {
9846
9867
  ssl: true
9847
9868
  }
9848
9869
  };
9849
- if (existsSync2(STORAGE_CONFIG_PATH)) {
9870
+ const storageConfigPath = getStorageConfigPath();
9871
+ if (existsSync2(storageConfigPath)) {
9850
9872
  try {
9851
- const raw = JSON.parse(readFileSync2(STORAGE_CONFIG_PATH, "utf-8"));
9873
+ const raw = JSON.parse(readFileSync2(storageConfigPath, "utf-8"));
9874
+ const legacyDatabaseConfig = typeof raw[LEGACY_DATABASE_CONFIG_KEY] === "object" && raw[LEGACY_DATABASE_CONFIG_KEY] !== null ? raw[LEGACY_DATABASE_CONFIG_KEY] : {};
9852
9875
  config.mode = normalizeMode(raw.mode) ?? config.mode;
9853
- config.rds = { ...config.rds, ...raw.rds ?? {} };
9876
+ config.postgres = { ...config.postgres, ...legacyDatabaseConfig, ...raw.postgres ?? {} };
9854
9877
  } catch {}
9855
9878
  }
9856
9879
  const modeOverride = readEnv(RECORDINGS_STORAGE_MODE_ENV) ?? readEnv(RECORDINGS_STORAGE_MODE_FALLBACK_ENV);
@@ -9867,7 +9890,7 @@ function getStorageConnectionString(dbName = "recordings") {
9867
9890
  if (direct)
9868
9891
  return direct;
9869
9892
  const config = getStorageConfig();
9870
- const { host, port, username, password_env, ssl } = config.rds;
9893
+ const { host, port, username, password_env, ssl } = config.postgres;
9871
9894
  if (!host || !username) {
9872
9895
  throw new Error("Storage database is not configured. Set HASNA_RECORDINGS_DATABASE_URL or configure ~/.hasna/recordings/storage/config.json.");
9873
9896
  }
@@ -10071,8 +10094,9 @@ async function runStorageMigrations(remote) {
10071
10094
  function getStorageStatus(db = getDatabase()) {
10072
10095
  const config = getStorageConfig();
10073
10096
  const activeEnv = getStorageDatabaseEnv();
10097
+ const hasConfiguredPostgres = Boolean(config.postgres.host && config.postgres.username);
10074
10098
  return {
10075
- configured: Boolean(activeEnv),
10099
+ configured: Boolean(activeEnv) || hasConfiguredPostgres,
10076
10100
  mode: config.mode,
10077
10101
  enabled: config.mode === "hybrid" || config.mode === "remote",
10078
10102
  env: STORAGE_DATABASE_ENV,