@gethmy/mcp 2.4.3 → 2.4.6

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.js CHANGED
@@ -27052,16 +27052,28 @@ async function requestWithBearer(apiUrl, bearerToken, method, path, body) {
27052
27052
  return result;
27053
27053
  }
27054
27054
 
27055
+ class HarmonyUnauthorizedError extends Error {
27056
+ constructor(message = "Invalid or expired credentials") {
27057
+ super(message);
27058
+ this.name = "HarmonyUnauthorizedError";
27059
+ }
27060
+ }
27061
+
27055
27062
  class HarmonyApiClient {
27056
27063
  apiKey;
27057
27064
  apiUrl;
27065
+ onUnauthorized;
27058
27066
  constructor(options) {
27059
27067
  this.apiKey = options?.apiKey ?? getApiKey();
27060
27068
  this.apiUrl = options?.apiUrl ?? getApiUrl();
27069
+ this.onUnauthorized = options?.onUnauthorized;
27061
27070
  }
27062
27071
  getApiUrl() {
27063
27072
  return this.apiUrl;
27064
27073
  }
27074
+ setApiKey(apiKey) {
27075
+ this.apiKey = apiKey;
27076
+ }
27065
27077
  async request(method, path, body, options) {
27066
27078
  await requestSemaphore.acquire();
27067
27079
  try {
@@ -27108,6 +27120,10 @@ class HarmonyApiClient {
27108
27120
  }
27109
27121
  if (!response.ok) {
27110
27122
  const errorMsg = data?.error || (looksLikeJson ? null : `API error: ${response.status} (non-JSON response)`) || `API error: ${response.status}`;
27123
+ if (response.status === 401) {
27124
+ this.onUnauthorized?.();
27125
+ throw new HarmonyUnauthorizedError(errorMsg);
27126
+ }
27111
27127
  if (!isRetryableError(null, response.status)) {
27112
27128
  throw new Error(errorMsg);
27113
27129
  }
@@ -27157,6 +27173,10 @@ class HarmonyApiClient {
27157
27173
  } catch {
27158
27174
  errorMsg = text || `API error: ${response.status}`;
27159
27175
  }
27176
+ if (response.status === 401) {
27177
+ this.onUnauthorized?.();
27178
+ throw new HarmonyUnauthorizedError(errorMsg);
27179
+ }
27160
27180
  if (!isRetryableError(null, response.status)) {
27161
27181
  throw new Error(errorMsg);
27162
27182
  }
@@ -28088,23 +28108,25 @@ var BATCH_SIZE = 100;
28088
28108
  var CONCURRENCY_LIMIT = 5;
28089
28109
  var BOILERPLATE_PATTERNS = [
28090
28110
  /^todo:?$/i,
28091
- /^placeholder/i,
28111
+ /^placeholder(\s+\d+|:)?$/i,
28092
28112
  /^\.\.\.$/,
28093
- /^untitled/i,
28094
- /^(note|memo|draft)\s*\d*$/i,
28113
+ /^untitled(\s+\d+|:)?$/i,
28114
+ /^(note|memo|draft)\s+\d+$/i,
28095
28115
  /^task transition:/i
28096
28116
  ];
28097
- function isBoilerplate(title, content) {
28117
+ function isBoilerplateTitle(title) {
28098
28118
  const t = title.trim();
28099
- const c = content.trim();
28100
- if (c.length === 0)
28101
- return true;
28102
28119
  for (const pat of BOILERPLATE_PATTERNS) {
28103
28120
  if (pat.test(t))
28104
28121
  return true;
28105
28122
  }
28106
28123
  return false;
28107
28124
  }
28125
+ function isBoilerplate(title, content) {
28126
+ if (content.trim().length === 0)
28127
+ return true;
28128
+ return isBoilerplateTitle(title);
28129
+ }
28108
28130
  function scoreEntity(entity, relationCount, archiveBelow, deleteBelow, staleDraftAgeDays) {
28109
28131
  const now = Date.now();
28110
28132
  const ageDays = (now - Date.parse(entity.created_at)) / MS_PER_DAY;
@@ -28186,8 +28208,12 @@ function scoreEntity(entity, relationCount, archiveBelow, deleteBelow, staleDraf
28186
28208
  legacy = true;
28187
28209
  legacyReasons.push("no graph presence");
28188
28210
  }
28211
+ const boilerplateTitle = isBoilerplateTitle(entity.title);
28189
28212
  let bucket;
28190
- if (score < deleteBelow)
28213
+ if (boilerplateTitle && deleteBelow > 0) {
28214
+ bucket = "delete";
28215
+ reasons.push("boilerplate title override");
28216
+ } else if (score < deleteBelow)
28191
28217
  bucket = "delete";
28192
28218
  else if (score < archiveBelow)
28193
28219
  bucket = "archive";
package/dist/index.js CHANGED
@@ -24812,16 +24812,28 @@ async function requestWithBearer(apiUrl, bearerToken, method, path, body) {
24812
24812
  return result;
24813
24813
  }
24814
24814
 
24815
+ class HarmonyUnauthorizedError extends Error {
24816
+ constructor(message = "Invalid or expired credentials") {
24817
+ super(message);
24818
+ this.name = "HarmonyUnauthorizedError";
24819
+ }
24820
+ }
24821
+
24815
24822
  class HarmonyApiClient {
24816
24823
  apiKey;
24817
24824
  apiUrl;
24825
+ onUnauthorized;
24818
24826
  constructor(options) {
24819
24827
  this.apiKey = options?.apiKey ?? getApiKey();
24820
24828
  this.apiUrl = options?.apiUrl ?? getApiUrl();
24829
+ this.onUnauthorized = options?.onUnauthorized;
24821
24830
  }
24822
24831
  getApiUrl() {
24823
24832
  return this.apiUrl;
24824
24833
  }
24834
+ setApiKey(apiKey) {
24835
+ this.apiKey = apiKey;
24836
+ }
24825
24837
  async request(method, path, body, options) {
24826
24838
  await requestSemaphore.acquire();
24827
24839
  try {
@@ -24868,6 +24880,10 @@ class HarmonyApiClient {
24868
24880
  }
24869
24881
  if (!response.ok) {
24870
24882
  const errorMsg = data?.error || (looksLikeJson ? null : `API error: ${response.status} (non-JSON response)`) || `API error: ${response.status}`;
24883
+ if (response.status === 401) {
24884
+ this.onUnauthorized?.();
24885
+ throw new HarmonyUnauthorizedError(errorMsg);
24886
+ }
24871
24887
  if (!isRetryableError(null, response.status)) {
24872
24888
  throw new Error(errorMsg);
24873
24889
  }
@@ -24917,6 +24933,10 @@ class HarmonyApiClient {
24917
24933
  } catch {
24918
24934
  errorMsg = text || `API error: ${response.status}`;
24919
24935
  }
24936
+ if (response.status === 401) {
24937
+ this.onUnauthorized?.();
24938
+ throw new HarmonyUnauthorizedError(errorMsg);
24939
+ }
24920
24940
  if (!isRetryableError(null, response.status)) {
24921
24941
  throw new Error(errorMsg);
24922
24942
  }
@@ -25848,23 +25868,25 @@ var BATCH_SIZE = 100;
25848
25868
  var CONCURRENCY_LIMIT = 5;
25849
25869
  var BOILERPLATE_PATTERNS = [
25850
25870
  /^todo:?$/i,
25851
- /^placeholder/i,
25871
+ /^placeholder(\s+\d+|:)?$/i,
25852
25872
  /^\.\.\.$/,
25853
- /^untitled/i,
25854
- /^(note|memo|draft)\s*\d*$/i,
25873
+ /^untitled(\s+\d+|:)?$/i,
25874
+ /^(note|memo|draft)\s+\d+$/i,
25855
25875
  /^task transition:/i
25856
25876
  ];
25857
- function isBoilerplate(title, content) {
25877
+ function isBoilerplateTitle(title) {
25858
25878
  const t = title.trim();
25859
- const c = content.trim();
25860
- if (c.length === 0)
25861
- return true;
25862
25879
  for (const pat of BOILERPLATE_PATTERNS) {
25863
25880
  if (pat.test(t))
25864
25881
  return true;
25865
25882
  }
25866
25883
  return false;
25867
25884
  }
25885
+ function isBoilerplate(title, content) {
25886
+ if (content.trim().length === 0)
25887
+ return true;
25888
+ return isBoilerplateTitle(title);
25889
+ }
25868
25890
  function scoreEntity(entity, relationCount, archiveBelow, deleteBelow, staleDraftAgeDays) {
25869
25891
  const now = Date.now();
25870
25892
  const ageDays = (now - Date.parse(entity.created_at)) / MS_PER_DAY;
@@ -25946,8 +25968,12 @@ function scoreEntity(entity, relationCount, archiveBelow, deleteBelow, staleDraf
25946
25968
  legacy = true;
25947
25969
  legacyReasons.push("no graph presence");
25948
25970
  }
25971
+ const boilerplateTitle = isBoilerplateTitle(entity.title);
25949
25972
  let bucket;
25950
- if (score < deleteBelow)
25973
+ if (boilerplateTitle && deleteBelow > 0) {
25974
+ bucket = "delete";
25975
+ reasons.push("boilerplate title override");
25976
+ } else if (score < deleteBelow)
25951
25977
  bucket = "delete";
25952
25978
  else if (score < archiveBelow)
25953
25979
  bucket = "archive";
@@ -1570,16 +1570,28 @@ async function requestWithBearer(apiUrl, bearerToken, method, path, body) {
1570
1570
  return result;
1571
1571
  }
1572
1572
 
1573
+ class HarmonyUnauthorizedError extends Error {
1574
+ constructor(message = "Invalid or expired credentials") {
1575
+ super(message);
1576
+ this.name = "HarmonyUnauthorizedError";
1577
+ }
1578
+ }
1579
+
1573
1580
  class HarmonyApiClient {
1574
1581
  apiKey;
1575
1582
  apiUrl;
1583
+ onUnauthorized;
1576
1584
  constructor(options) {
1577
1585
  this.apiKey = options?.apiKey ?? getApiKey();
1578
1586
  this.apiUrl = options?.apiUrl ?? getApiUrl();
1587
+ this.onUnauthorized = options?.onUnauthorized;
1579
1588
  }
1580
1589
  getApiUrl() {
1581
1590
  return this.apiUrl;
1582
1591
  }
1592
+ setApiKey(apiKey) {
1593
+ this.apiKey = apiKey;
1594
+ }
1583
1595
  async request(method, path, body, options) {
1584
1596
  await requestSemaphore.acquire();
1585
1597
  try {
@@ -1626,6 +1638,10 @@ class HarmonyApiClient {
1626
1638
  }
1627
1639
  if (!response.ok) {
1628
1640
  const errorMsg = data?.error || (looksLikeJson ? null : `API error: ${response.status} (non-JSON response)`) || `API error: ${response.status}`;
1641
+ if (response.status === 401) {
1642
+ this.onUnauthorized?.();
1643
+ throw new HarmonyUnauthorizedError(errorMsg);
1644
+ }
1629
1645
  if (!isRetryableError(null, response.status)) {
1630
1646
  throw new Error(errorMsg);
1631
1647
  }
@@ -1675,6 +1691,10 @@ class HarmonyApiClient {
1675
1691
  } catch {
1676
1692
  errorMsg = text || `API error: ${response.status}`;
1677
1693
  }
1694
+ if (response.status === 401) {
1695
+ this.onUnauthorized?.();
1696
+ throw new HarmonyUnauthorizedError(errorMsg);
1697
+ }
1678
1698
  if (!isRetryableError(null, response.status)) {
1679
1699
  throw new Error(errorMsg);
1680
1700
  }
@@ -2136,5 +2156,6 @@ export {
2136
2156
  resetClient,
2137
2157
  requestWithBearer,
2138
2158
  getClient,
2159
+ HarmonyUnauthorizedError,
2139
2160
  HarmonyApiClient
2140
2161
  };