apple-notes-mcp 2.8.34 → 2.8.35

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.
Files changed (3) hide show
  1. package/README.md +31 -1
  2. package/build/index.js +627 -174
  3. package/package.json +1 -1
package/build/index.js CHANGED
@@ -108,7 +108,7 @@ var require_code = __commonJS({
108
108
  }
109
109
  exports._ = _;
110
110
  var plus = new _Code("+");
111
- function str(strs, ...args) {
111
+ function str2(strs, ...args) {
112
112
  const expr = [safeStringify(strs[0])];
113
113
  let i = 0;
114
114
  while (i < args.length) {
@@ -119,7 +119,7 @@ var require_code = __commonJS({
119
119
  optimize(expr);
120
120
  return new _Code(expr);
121
121
  }
122
- exports.str = str;
122
+ exports.str = str2;
123
123
  function addCodeArg(code, arg) {
124
124
  if (arg instanceof _Code)
125
125
  code.push(...arg._items);
@@ -162,7 +162,7 @@ var require_code = __commonJS({
162
162
  return;
163
163
  }
164
164
  function strConcat(c1, c2) {
165
- return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 : str`${c1}${c2}`;
165
+ return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 : str2`${c1}${c2}`;
166
166
  }
167
167
  exports.strConcat = strConcat;
168
168
  function interpolate(x) {
@@ -417,11 +417,11 @@ var require_codegen = __commonJS({
417
417
  const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
418
418
  return `${varKind} ${this.name}${rhs};` + _n;
419
419
  }
420
- optimizeNames(names, constants4) {
420
+ optimizeNames(names, constants5) {
421
421
  if (!names[this.name.str])
422
422
  return;
423
423
  if (this.rhs)
424
- this.rhs = optimizeExpr(this.rhs, names, constants4);
424
+ this.rhs = optimizeExpr(this.rhs, names, constants5);
425
425
  return this;
426
426
  }
427
427
  get names() {
@@ -438,10 +438,10 @@ var require_codegen = __commonJS({
438
438
  render({ _n }) {
439
439
  return `${this.lhs} = ${this.rhs};` + _n;
440
440
  }
441
- optimizeNames(names, constants4) {
441
+ optimizeNames(names, constants5) {
442
442
  if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
443
443
  return;
444
- this.rhs = optimizeExpr(this.rhs, names, constants4);
444
+ this.rhs = optimizeExpr(this.rhs, names, constants5);
445
445
  return this;
446
446
  }
447
447
  get names() {
@@ -502,8 +502,8 @@ var require_codegen = __commonJS({
502
502
  optimizeNodes() {
503
503
  return `${this.code}` ? this : void 0;
504
504
  }
505
- optimizeNames(names, constants4) {
506
- this.code = optimizeExpr(this.code, names, constants4);
505
+ optimizeNames(names, constants5) {
506
+ this.code = optimizeExpr(this.code, names, constants5);
507
507
  return this;
508
508
  }
509
509
  get names() {
@@ -532,12 +532,12 @@ var require_codegen = __commonJS({
532
532
  }
533
533
  return nodes.length > 0 ? this : void 0;
534
534
  }
535
- optimizeNames(names, constants4) {
535
+ optimizeNames(names, constants5) {
536
536
  const { nodes } = this;
537
537
  let i = nodes.length;
538
538
  while (i--) {
539
539
  const n = nodes[i];
540
- if (n.optimizeNames(names, constants4))
540
+ if (n.optimizeNames(names, constants5))
541
541
  continue;
542
542
  subtractNames(names, n.names);
543
543
  nodes.splice(i, 1);
@@ -590,12 +590,12 @@ var require_codegen = __commonJS({
590
590
  return void 0;
591
591
  return this;
592
592
  }
593
- optimizeNames(names, constants4) {
593
+ optimizeNames(names, constants5) {
594
594
  var _a;
595
- this.else = (_a = this.else) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants4);
596
- if (!(super.optimizeNames(names, constants4) || this.else))
595
+ this.else = (_a = this.else) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants5);
596
+ if (!(super.optimizeNames(names, constants5) || this.else))
597
597
  return;
598
- this.condition = optimizeExpr(this.condition, names, constants4);
598
+ this.condition = optimizeExpr(this.condition, names, constants5);
599
599
  return this;
600
600
  }
601
601
  get names() {
@@ -618,10 +618,10 @@ var require_codegen = __commonJS({
618
618
  render(opts) {
619
619
  return `for(${this.iteration})` + super.render(opts);
620
620
  }
621
- optimizeNames(names, constants4) {
622
- if (!super.optimizeNames(names, constants4))
621
+ optimizeNames(names, constants5) {
622
+ if (!super.optimizeNames(names, constants5))
623
623
  return;
624
- this.iteration = optimizeExpr(this.iteration, names, constants4);
624
+ this.iteration = optimizeExpr(this.iteration, names, constants5);
625
625
  return this;
626
626
  }
627
627
  get names() {
@@ -657,10 +657,10 @@ var require_codegen = __commonJS({
657
657
  render(opts) {
658
658
  return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
659
659
  }
660
- optimizeNames(names, constants4) {
661
- if (!super.optimizeNames(names, constants4))
660
+ optimizeNames(names, constants5) {
661
+ if (!super.optimizeNames(names, constants5))
662
662
  return;
663
- this.iterable = optimizeExpr(this.iterable, names, constants4);
663
+ this.iterable = optimizeExpr(this.iterable, names, constants5);
664
664
  return this;
665
665
  }
666
666
  get names() {
@@ -702,11 +702,11 @@ var require_codegen = __commonJS({
702
702
  (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNodes();
703
703
  return this;
704
704
  }
705
- optimizeNames(names, constants4) {
705
+ optimizeNames(names, constants5) {
706
706
  var _a, _b;
707
- super.optimizeNames(names, constants4);
708
- (_a = this.catch) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants4);
709
- (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants4);
707
+ super.optimizeNames(names, constants5);
708
+ (_a = this.catch) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants5);
709
+ (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants5);
710
710
  return this;
711
711
  }
712
712
  get names() {
@@ -1007,7 +1007,7 @@ var require_codegen = __commonJS({
1007
1007
  function addExprNames(names, from) {
1008
1008
  return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
1009
1009
  }
1010
- function optimizeExpr(expr, names, constants4) {
1010
+ function optimizeExpr(expr, names, constants5) {
1011
1011
  if (expr instanceof code_1.Name)
1012
1012
  return replaceName(expr);
1013
1013
  if (!canOptimize(expr))
@@ -1022,14 +1022,14 @@ var require_codegen = __commonJS({
1022
1022
  return items;
1023
1023
  }, []));
1024
1024
  function replaceName(n) {
1025
- const c = constants4[n.str];
1025
+ const c = constants5[n.str];
1026
1026
  if (c === void 0 || names[n.str] !== 1)
1027
1027
  return n;
1028
1028
  delete names[n.str];
1029
1029
  return c;
1030
1030
  }
1031
1031
  function canOptimize(e) {
1032
- return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants4[c.str] !== void 0);
1032
+ return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants5[c.str] !== void 0);
1033
1033
  }
1034
1034
  }
1035
1035
  function subtractNames(names, from) {
@@ -1124,22 +1124,22 @@ var require_util = __commonJS({
1124
1124
  return (0, codegen_1._)`${topSchemaRef}${schemaPath}${(0, codegen_1.getProperty)(keyword)}`;
1125
1125
  }
1126
1126
  exports.schemaRefOrVal = schemaRefOrVal;
1127
- function unescapeFragment(str) {
1128
- return unescapeJsonPointer(decodeURIComponent(str));
1127
+ function unescapeFragment(str2) {
1128
+ return unescapeJsonPointer(decodeURIComponent(str2));
1129
1129
  }
1130
1130
  exports.unescapeFragment = unescapeFragment;
1131
- function escapeFragment(str) {
1132
- return encodeURIComponent(escapeJsonPointer(str));
1131
+ function escapeFragment(str2) {
1132
+ return encodeURIComponent(escapeJsonPointer(str2));
1133
1133
  }
1134
1134
  exports.escapeFragment = escapeFragment;
1135
- function escapeJsonPointer(str) {
1136
- if (typeof str == "number")
1137
- return `${str}`;
1138
- return str.replace(/~/g, "~0").replace(/\//g, "~1");
1135
+ function escapeJsonPointer(str2) {
1136
+ if (typeof str2 == "number")
1137
+ return `${str2}`;
1138
+ return str2.replace(/~/g, "~0").replace(/\//g, "~1");
1139
1139
  }
1140
1140
  exports.escapeJsonPointer = escapeJsonPointer;
1141
- function unescapeJsonPointer(str) {
1142
- return str.replace(/~1/g, "/").replace(/~0/g, "~");
1141
+ function unescapeJsonPointer(str2) {
1142
+ return str2.replace(/~1/g, "/").replace(/~0/g, "~");
1143
1143
  }
1144
1144
  exports.unescapeJsonPointer = unescapeJsonPointer;
1145
1145
  function eachItem(xs, f) {
@@ -2164,8 +2164,8 @@ var require_json_schema_traverse = __commonJS({
2164
2164
  post(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
2165
2165
  }
2166
2166
  }
2167
- function escapeJsonPtr(str) {
2168
- return str.replace(/~/g, "~0").replace(/\//g, "~1");
2167
+ function escapeJsonPtr(str2) {
2168
+ return str2.replace(/~/g, "~0").replace(/\//g, "~1");
2169
2169
  }
2170
2170
  }
2171
2171
  });
@@ -3261,10 +3261,10 @@ var require_utils = __commonJS({
3261
3261
  isIPV6: true
3262
3262
  };
3263
3263
  }
3264
- function findToken(str, token) {
3264
+ function findToken(str2, token) {
3265
3265
  let ind = 0;
3266
- for (let i = 0; i < str.length; i++) {
3267
- if (str[i] === token) ind++;
3266
+ for (let i = 0; i < str2.length; i++) {
3267
+ if (str2[i] === token) ind++;
3268
3268
  }
3269
3269
  return ind;
3270
3270
  }
@@ -4267,7 +4267,7 @@ var require_core = __commonJS({
4267
4267
  var util_1 = require_util();
4268
4268
  var $dataRefSchema = require_data();
4269
4269
  var uri_1 = require_uri();
4270
- var defaultRegExp = (str, flags) => new RegExp(str, flags);
4270
+ var defaultRegExp = (str2, flags) => new RegExp(str2, flags);
4271
4271
  defaultRegExp.code = "new RegExp";
4272
4272
  var META_IGNORE_OPTIONS = ["removeAdditional", "useDefaults", "coerceTypes"];
4273
4273
  var EXT_SCOPE_NAMES = /* @__PURE__ */ new Set([
@@ -5062,16 +5062,16 @@ var require_ucs2length = __commonJS({
5062
5062
  "node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/runtime/ucs2length.js"(exports) {
5063
5063
  "use strict";
5064
5064
  Object.defineProperty(exports, "__esModule", { value: true });
5065
- function ucs2length(str) {
5066
- const len = str.length;
5065
+ function ucs2length(str2) {
5066
+ const len = str2.length;
5067
5067
  let length = 0;
5068
5068
  let pos = 0;
5069
5069
  let value;
5070
5070
  while (pos < len) {
5071
5071
  length++;
5072
- value = str.charCodeAt(pos++);
5072
+ value = str2.charCodeAt(pos++);
5073
5073
  if (value >= 55296 && value <= 56319 && pos < len) {
5074
- value = str.charCodeAt(pos);
5074
+ value = str2.charCodeAt(pos);
5075
5075
  if ((value & 64512) === 56320)
5076
5076
  pos++;
5077
5077
  }
@@ -6954,8 +6954,8 @@ var require_formats = __commonJS({
6954
6954
  }
6955
6955
  var DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
6956
6956
  var DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
6957
- function date3(str) {
6958
- const matches = DATE.exec(str);
6957
+ function date3(str2) {
6958
+ const matches = DATE.exec(str2);
6959
6959
  if (!matches)
6960
6960
  return false;
6961
6961
  const year = +matches[1];
@@ -6974,8 +6974,8 @@ var require_formats = __commonJS({
6974
6974
  }
6975
6975
  var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
6976
6976
  function getTime(strictTimeZone) {
6977
- return function time3(str) {
6978
- const matches = TIME.exec(str);
6977
+ return function time3(str2) {
6978
+ const matches = TIME.exec(str2);
6979
6979
  if (!matches)
6980
6980
  return false;
6981
6981
  const hr = +matches[1];
@@ -7021,8 +7021,8 @@ var require_formats = __commonJS({
7021
7021
  var DATE_TIME_SEPARATOR = /t|\s/i;
7022
7022
  function getDateTime(strictTimeZone) {
7023
7023
  const time3 = getTime(strictTimeZone);
7024
- return function date_time(str) {
7025
- const dateTime = str.split(DATE_TIME_SEPARATOR);
7024
+ return function date_time(str2) {
7025
+ const dateTime = str2.split(DATE_TIME_SEPARATOR);
7026
7026
  return dateTime.length === 2 && date3(dateTime[0]) && time3(dateTime[1]);
7027
7027
  };
7028
7028
  }
@@ -7047,13 +7047,13 @@ var require_formats = __commonJS({
7047
7047
  }
7048
7048
  var NOT_URI_FRAGMENT = /\/|:/;
7049
7049
  var URI = /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
7050
- function uri(str) {
7051
- return NOT_URI_FRAGMENT.test(str) && URI.test(str);
7050
+ function uri(str2) {
7051
+ return NOT_URI_FRAGMENT.test(str2) && URI.test(str2);
7052
7052
  }
7053
7053
  var BYTE = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gm;
7054
- function byte(str) {
7054
+ function byte(str2) {
7055
7055
  BYTE.lastIndex = 0;
7056
- return BYTE.test(str);
7056
+ return BYTE.test(str2);
7057
7057
  }
7058
7058
  var MIN_INT32 = -(2 ** 31);
7059
7059
  var MAX_INT32 = 2 ** 31 - 1;
@@ -7067,11 +7067,11 @@ var require_formats = __commonJS({
7067
7067
  return true;
7068
7068
  }
7069
7069
  var Z_ANCHOR = /[^\\]\\Z/;
7070
- function regex(str) {
7071
- if (Z_ANCHOR.test(str))
7070
+ function regex(str2) {
7071
+ if (Z_ANCHOR.test(str2))
7072
7072
  return false;
7073
7073
  try {
7074
- new RegExp(str);
7074
+ new RegExp(str2);
7075
7075
  return true;
7076
7076
  } catch (e) {
7077
7077
  return false;
@@ -7422,7 +7422,7 @@ var require_DOMException = __commonJS({
7422
7422
  "INVALID_NODE_TYPE_ERR (24): the supplied node is invalid or has an invalid ancestor for this operation",
7423
7423
  "DATA_CLONE_ERR (25): the object can not be cloned."
7424
7424
  ];
7425
- var constants4 = {
7425
+ var constants5 = {
7426
7426
  INDEX_SIZE_ERR,
7427
7427
  DOMSTRING_SIZE_ERR: 2,
7428
7428
  // historical
@@ -7461,8 +7461,8 @@ var require_DOMException = __commonJS({
7461
7461
  this.name = names[code];
7462
7462
  }
7463
7463
  DOMException.prototype.__proto__ = Error.prototype;
7464
- for (c in constants4) {
7465
- v = { value: constants4[c] };
7464
+ for (c in constants5) {
7465
+ v = { value: constants5[c] };
7466
7466
  Object.defineProperty(DOMException, c, v);
7467
7467
  Object.defineProperty(DOMException.prototype, c, v);
7468
7468
  }
@@ -9206,12 +9206,12 @@ var require_DOMTokenList = __commonJS({
9206
9206
  if (strProp === clist._lastStringValue) {
9207
9207
  return toArray(clist);
9208
9208
  }
9209
- var str = strProp.replace(/(^[ \t\r\n\f]+)|([ \t\r\n\f]+$)/g, "");
9210
- if (str === "") {
9209
+ var str2 = strProp.replace(/(^[ \t\r\n\f]+)|([ \t\r\n\f]+$)/g, "");
9210
+ if (str2 === "") {
9211
9211
  return [];
9212
9212
  } else {
9213
9213
  var seen = /* @__PURE__ */ Object.create(null);
9214
- return str.split(/[ \t\r\n\f]+/g).filter(function(n) {
9214
+ return str2.split(/[ \t\r\n\f]+/g).filter(function(n) {
9215
9215
  var key = "$" + n;
9216
9216
  if (seen[key]) {
9217
9217
  return false;
@@ -9266,16 +9266,16 @@ var require_select = __commonJS({
9266
9266
  var nodeType = n.parentNode.nodeType;
9267
9267
  return nodeType === 1 || nodeType === 9;
9268
9268
  };
9269
- var unquote = function(str) {
9270
- if (!str) return str;
9271
- var ch = str[0];
9269
+ var unquote = function(str2) {
9270
+ if (!str2) return str2;
9271
+ var ch = str2[0];
9272
9272
  if (ch === '"' || ch === "'") {
9273
- if (str[str.length - 1] === ch) {
9274
- str = str.slice(1, -1);
9273
+ if (str2[str2.length - 1] === ch) {
9274
+ str2 = str2.slice(1, -1);
9275
9275
  } else {
9276
- str = str.slice(1);
9276
+ str2 = str2.slice(1);
9277
9277
  }
9278
- return str.replace(rules.str_escape, function(s) {
9278
+ return str2.replace(rules.str_escape, function(s) {
9279
9279
  var m = /^\\(?:([0-9A-Fa-f]+)|([\r\n\f]+))/.exec(s);
9280
9280
  if (!m) {
9281
9281
  return s.slice(1);
@@ -9289,14 +9289,14 @@ var require_select = __commonJS({
9289
9289
  String.fromCharCode(cp)
9290
9290
  );
9291
9291
  });
9292
- } else if (rules.ident.test(str)) {
9293
- return decodeid(str);
9292
+ } else if (rules.ident.test(str2)) {
9293
+ return decodeid(str2);
9294
9294
  } else {
9295
- return str;
9295
+ return str2;
9296
9296
  }
9297
9297
  };
9298
- var decodeid = function(str) {
9299
- return str.replace(rules.escape, function(s) {
9298
+ var decodeid = function(str2) {
9299
+ return str2.replace(rules.escape, function(s) {
9300
9300
  var m = /^\\([0-9A-Fa-f]+)/.exec(s);
9301
9301
  if (!m) {
9302
9302
  return s[1];
@@ -24465,14 +24465,14 @@ var require_turndown_cjs = __commonJS({
24465
24465
  } else if (node.nodeType === 1) {
24466
24466
  replacement = replacementForNode.call(self, node);
24467
24467
  }
24468
- return join17(output, replacement);
24468
+ return join18(output, replacement);
24469
24469
  }, "");
24470
24470
  }
24471
24471
  function postProcess(output) {
24472
24472
  var self = this;
24473
24473
  this.rules.forEach(function(rule) {
24474
24474
  if (typeof rule.append === "function") {
24475
- output = join17(output, rule.append(self.options));
24475
+ output = join18(output, rule.append(self.options));
24476
24476
  }
24477
24477
  });
24478
24478
  return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
@@ -24484,7 +24484,7 @@ var require_turndown_cjs = __commonJS({
24484
24484
  if (whitespace.leading || whitespace.trailing) content = content.trim();
24485
24485
  return whitespace.leading + rule.replacement(content, node, this.options) + whitespace.trailing;
24486
24486
  }
24487
- function join17(output, replacement) {
24487
+ function join18(output, replacement) {
24488
24488
  var s1 = trimTrailingNewlines(output);
24489
24489
  var s2 = trimLeadingNewlines(replacement);
24490
24490
  var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
@@ -28667,9 +28667,9 @@ function assertNever(_x) {
28667
28667
  }
28668
28668
  function assert(_) {
28669
28669
  }
28670
- function getEnumValues(entries) {
28671
- const numericValues = Object.values(entries).filter((v) => typeof v === "number");
28672
- const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
28670
+ function getEnumValues(entries2) {
28671
+ const numericValues = Object.values(entries2).filter((v) => typeof v === "number");
28672
+ const values = Object.entries(entries2).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
28673
28673
  return values;
28674
28674
  }
28675
28675
  function joinValues(array2, separator = "|") {
@@ -28755,14 +28755,14 @@ function promiseAllObject(promisesObj) {
28755
28755
  }
28756
28756
  function randomString(length = 10) {
28757
28757
  const chars = "abcdefghijklmnopqrstuvwxyz";
28758
- let str = "";
28758
+ let str2 = "";
28759
28759
  for (let i = 0; i < length; i++) {
28760
- str += chars[Math.floor(Math.random() * chars.length)];
28760
+ str2 += chars[Math.floor(Math.random() * chars.length)];
28761
28761
  }
28762
- return str;
28762
+ return str2;
28763
28763
  }
28764
- function esc(str) {
28765
- return JSON.stringify(str);
28764
+ function esc(str2) {
28765
+ return JSON.stringify(str2);
28766
28766
  }
28767
28767
  var captureStackTrace = Error.captureStackTrace ? Error.captureStackTrace : (..._args) => {
28768
28768
  };
@@ -28850,8 +28850,8 @@ var getParsedType2 = (data) => {
28850
28850
  };
28851
28851
  var propertyKeyTypes = /* @__PURE__ */ new Set(["string", "number", "symbol"]);
28852
28852
  var primitiveTypes = /* @__PURE__ */ new Set(["string", "number", "bigint", "boolean", "symbol", "undefined"]);
28853
- function escapeRegex(str) {
28854
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
28853
+ function escapeRegex(str2) {
28854
+ return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
28855
28855
  }
28856
28856
  function clone(inst, def, params) {
28857
28857
  const cl = new inst._zod.constr(def ?? inst._zod.def);
@@ -33039,10 +33039,10 @@ var ZodEnum2 = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
33039
33039
  };
33040
33040
  });
33041
33041
  function _enum(values, params) {
33042
- const entries = Array.isArray(values) ? Object.fromEntries(values.map((v) => [v, v])) : values;
33042
+ const entries2 = Array.isArray(values) ? Object.fromEntries(values.map((v) => [v, v])) : values;
33043
33043
  return new ZodEnum2({
33044
33044
  type: "enum",
33045
- entries,
33045
+ entries: entries2,
33046
33046
  ...util_exports.normalizeParams(params)
33047
33047
  });
33048
33048
  }
@@ -37774,12 +37774,12 @@ var UriTemplate = class _UriTemplate {
37774
37774
  * A template expression is a sequence of characters enclosed in curly braces,
37775
37775
  * like {foo} or {?bar}.
37776
37776
  */
37777
- static isTemplate(str) {
37778
- return /\{[^}\s]+\}/.test(str);
37777
+ static isTemplate(str2) {
37778
+ return /\{[^}\s]+\}/.test(str2);
37779
37779
  }
37780
- static validateLength(str, max, context) {
37781
- if (str.length > max) {
37782
- throw new Error(`${context} exceeds maximum length of ${max} characters (got ${str.length})`);
37780
+ static validateLength(str2, max, context) {
37781
+ if (str2.length > max) {
37782
+ throw new Error(`${context} exceeds maximum length of ${max} characters (got ${str2.length})`);
37783
37783
  }
37784
37784
  }
37785
37785
  get variableNames() {
@@ -37908,8 +37908,8 @@ var UriTemplate = class _UriTemplate {
37908
37908
  }
37909
37909
  return result;
37910
37910
  }
37911
- escapeRegExp(str) {
37912
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
37911
+ escapeRegExp(str2) {
37912
+ return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
37913
37913
  }
37914
37914
  partToRegExp(part) {
37915
37915
  const patterns = [];
@@ -39962,9 +39962,9 @@ var many = (f, n) => getFields(f, n).map((field) => {
39962
39962
  });
39963
39963
  function parseAudioRecording(data) {
39964
39964
  const root = decode(data);
39965
- const entries = many(root, 3);
39966
- if (entries.length === 0) throw new Error("No mergeable objects");
39967
- if (entries.length > 2e6) throw new Error("Recording too large");
39965
+ const entries2 = many(root, 3);
39966
+ if (entries2.length === 0) throw new Error("No mergeable objects");
39967
+ if (entries2.length > 2e6) throw new Error("Recording too large");
39968
39968
  const keys = getFields(root, 4).map((f) => stringValue(f) ?? "");
39969
39969
  const types = getFields(root, 5).map((f) => stringValue(f) ?? "");
39970
39970
  const uuids = getFields(root, 6).map(
@@ -39975,7 +39975,7 @@ function parseAudioRecording(data) {
39975
39975
  if (uuid2 && !uuidSlot.has(uuid2)) uuidSlot.set(uuid2, i);
39976
39976
  });
39977
39977
  const entry = (index) => {
39978
- const value = entries[index];
39978
+ const value = entries2[index];
39979
39979
  if (!value) throw new Error("Invalid object reference");
39980
39980
  return value;
39981
39981
  };
@@ -40017,7 +40017,7 @@ function parseAudioRecording(data) {
40017
40017
  const text = note && stringValue(getField(note, 2));
40018
40018
  return text?.replace(/\n+$/u, "") || void 0;
40019
40019
  };
40020
- const recordings = entries.map((e) => customMap(e)).filter((m) => m?.type === "com.apple.notes.ICTTAudioRecording");
40020
+ const recordings = entries2.map((e) => customMap(e)).filter((m) => m?.type === "com.apple.notes.ICTTAudioRecording");
40021
40021
  if (recordings.length !== 1) throw new Error("Expected exactly one audio recording object");
40022
40022
  const recording = recordings[0];
40023
40023
  const fragments = [];
@@ -40322,15 +40322,15 @@ function parseNoteTableCells(compressed) {
40322
40322
  }
40323
40323
  function decodeTable(compressed, strict) {
40324
40324
  const root = decodeMessage(gunzipSync4(compressed, { maxOutputLength: 16 * 1024 * 1024 }));
40325
- const data = sub2(sub2(root, 2), 3), entries = many2(data, 3);
40326
- if (entries.length > 1e5) throw new Error("Table too large");
40325
+ const data = sub2(sub2(root, 2), 3), entries2 = many2(data, 3);
40326
+ if (entries2.length > 1e5) throw new Error("Table too large");
40327
40327
  const keys = getFields(data, 4).map(stringValue), types = getFields(data, 5).map(stringValue), uuids = getFields(data, 6).map(hex);
40328
40328
  const entry = (index) => {
40329
- if (!entries[index]) throw new Error("Invalid table reference");
40330
- return entries[index];
40329
+ if (!entries2[index]) throw new Error("Invalid table reference");
40330
+ return entries2[index];
40331
40331
  };
40332
40332
  const uuidIndex = (index) => num(sub2(many2(sub2(entry(index), 13), 3)[0], 2), 2);
40333
- const roots = entries.filter((e) => {
40333
+ const roots = entries2.filter((e) => {
40334
40334
  const map = embeddedMessage(getField(e, 13));
40335
40335
  return map && types[num(map, 1)] === "com.apple.notes.ICTable";
40336
40336
  });
@@ -40392,7 +40392,7 @@ function decodeTable(compressed, strict) {
40392
40392
  values[ri][ci] = text.replace(/\n$/u, "");
40393
40393
  }
40394
40394
  }
40395
- const rtl = entries.some((e) => {
40395
+ const rtl = entries2.some((e) => {
40396
40396
  const map = embeddedMessage(getField(e, 13));
40397
40397
  return map && many2(map, 3).some(
40398
40398
  (m) => stringValue(getField(sub2(m, 2), 4)) === "CRTableColumnDirectionRightToLeft"
@@ -41036,6 +41036,22 @@ function cleanupTempDir(dir) {
41036
41036
  }
41037
41037
  }
41038
41038
 
41039
+ // src/utils/paperAttachments.ts
41040
+ import { execFileSync as execFileSync7 } from "node:child_process";
41041
+ import {
41042
+ closeSync as closeSync3,
41043
+ constants as constants3,
41044
+ fstatSync as fstatSync3,
41045
+ lstatSync as lstatSync3,
41046
+ mkdirSync as mkdirSync3,
41047
+ openSync as openSync3,
41048
+ readdirSync as readdirSync2,
41049
+ readSync as readSync2,
41050
+ unlinkSync as unlinkSync2,
41051
+ writeSync as writeSync2
41052
+ } from "node:fs";
41053
+ import { basename as basename2, dirname as dirname3, extname as extname2, join as join7 } from "node:path";
41054
+
41039
41055
  // src/utils/attachmentAssets.ts
41040
41056
  import { execFileSync as execFileSync6 } from "node:child_process";
41041
41057
  import {
@@ -41282,8 +41298,8 @@ function isDirectory(path7) {
41282
41298
  }
41283
41299
  function boundedEntries(dir, limit) {
41284
41300
  try {
41285
- const entries = readdirSync(dir);
41286
- return entries.length > limit ? null : entries.sort();
41301
+ const entries2 = readdirSync(dir);
41302
+ return entries2.length > limit ? null : entries2.sort();
41287
41303
  } catch {
41288
41304
  return null;
41289
41305
  }
@@ -41301,19 +41317,19 @@ function resolveAccountDir(containerDir, accountIdentifier) {
41301
41317
  const dir = realInside(join6(accountsReal, account), accountsReal);
41302
41318
  if (dir && isDirectory(dir)) return dir;
41303
41319
  }
41304
- const entries = (boundedEntries(accountsReal, 64) ?? []).filter(
41320
+ const entries2 = (boundedEntries(accountsReal, 64) ?? []).filter(
41305
41321
  (e) => isDirectory(join6(accountsReal, e))
41306
41322
  );
41307
- if (entries.length !== 1) return null;
41308
- return realInside(join6(accountsReal, entries[0]), accountsReal);
41323
+ if (entries2.length !== 1) return null;
41324
+ return realInside(join6(accountsReal, entries2[0]), accountsReal);
41309
41325
  }
41310
41326
  function generationRank(name) {
41311
41327
  const m = /^(\d+)_/.exec(name);
41312
41328
  return m ? Number(m[1]) : 0;
41313
41329
  }
41314
41330
  function generationDirs(base, accountDir) {
41315
- const entries = boundedEntries(base, MAX_GENERATION_DIRS) ?? [];
41316
- return entries.map((e) => realInside(join6(base, e), accountDir)).filter((p) => p !== null && isDirectory(p)).sort((a, b) => generationRank(basename(b)) - generationRank(basename(a)));
41331
+ const entries2 = boundedEntries(base, MAX_GENERATION_DIRS) ?? [];
41332
+ return entries2.map((e) => realInside(join6(base, e), accountDir)).filter((p) => p !== null && isDirectory(p)).sort((a, b) => generationRank(basename(b)) - generationRank(basename(a)));
41317
41333
  }
41318
41334
  function fallbackFiles(accountDir, rootName, identifier, generation, names) {
41319
41335
  const base = join6(accountDir, rootName, identifier);
@@ -41358,11 +41374,11 @@ function previewFileInBundle(bundle, accountDir) {
41358
41374
  function listPreviewEntries(accountDir) {
41359
41375
  return boundedEntries(join6(accountDir, "Previews"), MAX_PREVIEW_DIR_ENTRIES) ?? [];
41360
41376
  }
41361
- function previewPaths(accountDir, identifier, entries) {
41377
+ function previewPaths(accountDir, identifier, entries2) {
41362
41378
  const id2 = safeComponent(identifier);
41363
41379
  if (!id2) return [];
41364
41380
  const prefix = `${id2}-`.toLowerCase();
41365
- const candidates = entries.filter((name) => name.toLowerCase().startsWith(prefix)).filter((name) => {
41381
+ const candidates = entries2.filter((name) => name.toLowerCase().startsWith(prefix)).filter((name) => {
41366
41382
  const ext = extname(name).toLowerCase();
41367
41383
  return !ext || PREVIEW_IMAGE_SUFFIXES.has(ext) || /^\.\d+$/.test(ext);
41368
41384
  }).sort((a, b) => previewPixelArea(b) - previewPixelArea(a) || a.localeCompare(b));
@@ -41611,11 +41627,348 @@ function exportAttachmentAssets(assets, exportDir, options = {}) {
41611
41627
  return { exportDir: dir, results };
41612
41628
  }
41613
41629
 
41630
+ // src/utils/paperAttachments.ts
41631
+ var MAX_AXIS = 32768;
41632
+ var MAX_PREVIEW_DIR_ENTRIES2 = 1e5;
41633
+ var MAX_DIR_ENTRIES = 64;
41634
+ var HEADER_BYTES = 64 * 1024;
41635
+ var PNG_MAGIC = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
41636
+ var IMAGE_SUFFIXES = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg"]);
41637
+ var axisOk = (n) => Number.isInteger(n) && n > 0 && n <= MAX_AXIS;
41638
+ function parseImageHeader(buf) {
41639
+ if (buf.length >= 24 && buf.subarray(0, 8).equals(PNG_MAGIC)) {
41640
+ if (buf.readUInt32BE(8) !== 13 || buf.toString("latin1", 12, 16) !== "IHDR") return null;
41641
+ const width = buf.readUInt32BE(16);
41642
+ const height = buf.readUInt32BE(20);
41643
+ return axisOk(width) && axisOk(height) ? { format: "png", width, height } : null;
41644
+ }
41645
+ if (buf.length >= 4 && buf[0] === 255 && buf[1] === 216 && buf[2] === 255) {
41646
+ let offset = 2;
41647
+ while (offset + 4 <= buf.length) {
41648
+ if (buf[offset] !== 255) return null;
41649
+ const marker = buf[offset + 1];
41650
+ if (marker === 255) {
41651
+ offset++;
41652
+ continue;
41653
+ }
41654
+ const length = buf.readUInt16BE(offset + 2);
41655
+ if (length < 2) return null;
41656
+ const isFrame = marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204;
41657
+ if (isFrame) {
41658
+ if (offset + 9 > buf.length) return null;
41659
+ const height = buf.readUInt16BE(offset + 5);
41660
+ const width = buf.readUInt16BE(offset + 7);
41661
+ return axisOk(width) && axisOk(height) ? { format: "jpeg", width, height } : null;
41662
+ }
41663
+ offset += 2 + length;
41664
+ }
41665
+ }
41666
+ return null;
41667
+ }
41668
+ function readImageInfoFd(fd) {
41669
+ if (!fstatSync3(fd).isFile()) return null;
41670
+ const buf = Buffer.alloc(HEADER_BYTES);
41671
+ const read = readSync2(fd, buf, 0, buf.length, 0);
41672
+ return parseImageHeader(buf.subarray(0, read));
41673
+ }
41674
+ function readImageInfo(path7) {
41675
+ let fd;
41676
+ try {
41677
+ fd = openSync3(path7, constants3.O_RDONLY | constants3.O_NOFOLLOW);
41678
+ } catch {
41679
+ return null;
41680
+ }
41681
+ try {
41682
+ return readImageInfoFd(fd);
41683
+ } finally {
41684
+ closeSync3(fd);
41685
+ }
41686
+ }
41687
+ function buildDrawingRowsSql(notePk, columns) {
41688
+ if (!Number.isSafeInteger(notePk) || notePk < 0) throw new Error("Invalid note primary key");
41689
+ const col2 = (name) => columns.has(name) ? `a.${name}` : "NULL";
41690
+ const accountCols = [...columns].filter((c) => /^ZACCOUNT\d*$/.test(c)).sort();
41691
+ const account = accountCols.length ? `(SELECT acc.ZIDENTIFIER FROM ZICCLOUDSYNCINGOBJECT acc WHERE acc.Z_ENT = (SELECT Z_ENT FROM Z_PRIMARYKEY WHERE Z_NAME = 'ICAccount') AND acc.Z_PK IN (${[
41692
+ ...accountCols.map((c) => `a.${c}`),
41693
+ ...accountCols.map((c) => `n.${c}`)
41694
+ ].join(", ")}) LIMIT 1)` : "NULL";
41695
+ const deleted = columns.has("ZMARKEDFORDELETION") ? " AND COALESCE(a.ZMARKEDFORDELETION, 0) = 0" : "";
41696
+ const fields = [
41697
+ `'pk', a.Z_PK`,
41698
+ `'identifier', a.ZIDENTIFIER`,
41699
+ `'uti', a.ZTYPEUTI`,
41700
+ `'handwritingSummary', ${col2("ZHANDWRITINGSUMMARY")}`,
41701
+ `'fallbackImageGeneration', ${col2("ZFALLBACKIMAGEGENERATION")}`,
41702
+ `'accountIdentifier', ${account}`
41703
+ ].join(", ");
41704
+ return [
41705
+ "BEGIN;",
41706
+ `SELECT count(*) FROM ZICCLOUDSYNCINGOBJECT WHERE Z_PK = ${notePk} AND Z_ENT = (SELECT Z_ENT FROM Z_PRIMARYKEY WHERE Z_NAME = 'ICNote');`,
41707
+ `SELECT json_group_array(json_object(${fields})) FROM ZICCLOUDSYNCINGOBJECT a LEFT JOIN ZICCLOUDSYNCINGOBJECT n ON n.Z_PK = a.ZNOTE WHERE a.Z_ENT = (SELECT Z_ENT FROM Z_PRIMARYKEY WHERE Z_NAME = 'ICAttachment') AND a.ZNOTE = ${notePk} AND (a.ZTYPEUTI = 'com.apple.paper' OR a.ZTYPEUTI = 'com.apple.drawing' OR a.ZTYPEUTI LIKE 'com.apple.drawing.%')${deleted};`,
41708
+ "COMMIT;"
41709
+ ].join(" ");
41710
+ }
41711
+ function runSqlite4(dbPath2, sql) {
41712
+ try {
41713
+ return execFileSync7("/usr/bin/sqlite3", ["-readonly", dbPath2, sql], {
41714
+ encoding: "utf8",
41715
+ timeout: 1e4,
41716
+ maxBuffer: 16 * 1024 * 1024,
41717
+ stdio: ["pipe", "pipe", "pipe"]
41718
+ });
41719
+ } catch (error2) {
41720
+ const message = error2 instanceof Error ? error2.message : String(error2);
41721
+ if (/authorization denied|unable to open database/i.test(message)) {
41722
+ throw new AttachmentStoreError(
41723
+ "Full Disk Access is required to read drawing attachments. Grant it to the app that launches this server, then relaunch it (run the doctor tool to verify).",
41724
+ "no_fda"
41725
+ );
41726
+ }
41727
+ throw new AttachmentStoreError(`Failed to read drawing attachments: ${message}`, "query_error");
41728
+ }
41729
+ }
41730
+ var str = (v) => typeof v === "string" && v.length > 0 ? v : null;
41731
+ function parseDrawingRows(json2) {
41732
+ const raw = JSON.parse(json2 || "[]");
41733
+ if (!Array.isArray(raw)) throw new Error("Invalid drawing rows");
41734
+ const rows = [];
41735
+ for (const item of raw) {
41736
+ if (!item || typeof item !== "object") continue;
41737
+ const r = item;
41738
+ const identifier = str(r.identifier);
41739
+ const uti = str(r.uti);
41740
+ if (!Number.isSafeInteger(r.pk) || !identifier || !uti) continue;
41741
+ const summary = str(r.handwritingSummary);
41742
+ rows.push({
41743
+ pk: r.pk,
41744
+ identifier,
41745
+ uti,
41746
+ handwritingSummary: summary && summary.trim() ? summary : null,
41747
+ fallbackImageGeneration: str(r.fallbackImageGeneration),
41748
+ accountIdentifier: str(r.accountIdentifier)
41749
+ });
41750
+ }
41751
+ return rows.sort((a, b) => a.pk - b.pk);
41752
+ }
41753
+ function readDrawingRows(noteId3, dbPath2 = join7(NOTES_CONTAINER_DIR, "NoteStore.sqlite")) {
41754
+ const { pk } = parseNoteId2(noteId3);
41755
+ const columns = new Set(
41756
+ runSqlite4(
41757
+ dbPath2,
41758
+ "SELECT group_concat(name, ',') FROM pragma_table_info('ZICCLOUDSYNCINGOBJECT');"
41759
+ ).trim().split(",").filter(Boolean)
41760
+ );
41761
+ if (!columns.has("ZIDENTIFIER") || !columns.has("ZTYPEUTI") || !columns.has("ZNOTE")) {
41762
+ throw new AttachmentStoreError("Unsupported Notes database schema", "query_error");
41763
+ }
41764
+ const lines = runSqlite4(dbPath2, buildDrawingRowsSql(pk, columns)).split("\n");
41765
+ if (lines[0]?.trim() !== "1") {
41766
+ throw new AttachmentStoreError(
41767
+ `No note found in the database for ID "${noteId3}".`,
41768
+ "not_found"
41769
+ );
41770
+ }
41771
+ try {
41772
+ return parseDrawingRows(lines[1] ?? "[]");
41773
+ } catch {
41774
+ throw new AttachmentStoreError("Drawing rows could not be parsed", "query_error");
41775
+ }
41776
+ }
41777
+ function kindOf(path7) {
41778
+ try {
41779
+ const st = lstatSync3(path7);
41780
+ return st.isFile() ? "file" : st.isDirectory() ? "dir" : null;
41781
+ } catch {
41782
+ return null;
41783
+ }
41784
+ }
41785
+ function entries(dir, limit) {
41786
+ try {
41787
+ const list = readdirSync2(dir);
41788
+ return list.length > limit ? [] : list.sort();
41789
+ } catch {
41790
+ return [];
41791
+ }
41792
+ }
41793
+ var byGenerationDesc = (a, b) => generationRank(basename2(b)) - generationRank(basename2(a));
41794
+ function findFallbackImage(accountDir, identifier, generation) {
41795
+ const id2 = safeComponent(identifier);
41796
+ if (!id2) return null;
41797
+ const base = join7(accountDir, "FallbackImages", id2);
41798
+ const names = ["FallbackImage.png", "FallbackImage.jpg"];
41799
+ const candidates = [];
41800
+ const gen = safeComponent(generation);
41801
+ if (gen) for (const n of names) candidates.push(join7(base, gen, n));
41802
+ const gens = entries(base, MAX_DIR_ENTRIES).map((e) => join7(base, e)).sort(byGenerationDesc);
41803
+ for (const g of gens) for (const n of names) candidates.push(join7(g, n));
41804
+ for (const n of names) candidates.push(join7(base, n));
41805
+ candidates.push(join7(accountDir, "FallbackImages", `${id2}.png`));
41806
+ candidates.push(join7(accountDir, "FallbackImages", `${id2}.jpg`));
41807
+ for (const c of candidates) {
41808
+ const real = realInside(c, accountDir);
41809
+ if (real && kindOf(real) === "file") return real;
41810
+ }
41811
+ return null;
41812
+ }
41813
+ function findLargestPreview(accountDir, identifier) {
41814
+ const id2 = safeComponent(identifier);
41815
+ if (!id2) return null;
41816
+ const dir = join7(accountDir, "Previews");
41817
+ const prefix = `${id2}-`.toLowerCase();
41818
+ const names = entries(dir, MAX_PREVIEW_DIR_ENTRIES2).filter((n) => n.toLowerCase().startsWith(prefix)).filter((n) => {
41819
+ const ext = extname2(n).toLowerCase();
41820
+ return !ext || IMAGE_SUFFIXES.has(ext) || /^\.\d+$/.test(ext);
41821
+ }).sort((a, b) => previewPixelArea(b) - previewPixelArea(a) || a.localeCompare(b));
41822
+ for (const name of names) {
41823
+ const real = realInside(join7(dir, name), accountDir);
41824
+ if (!real) continue;
41825
+ const kind = kindOf(real);
41826
+ if (kind === "file") return real;
41827
+ if (kind !== "dir") continue;
41828
+ const gens = entries(real, MAX_DIR_ENTRIES).map((e) => realInside(join7(real, e), accountDir)).filter((p) => p !== null && kindOf(p) === "dir").sort(byGenerationDesc);
41829
+ for (const g of [...gens, real]) {
41830
+ const file = realInside(join7(g, "Preview.png"), accountDir);
41831
+ if (file && kindOf(file) === "file") return file;
41832
+ }
41833
+ }
41834
+ return null;
41835
+ }
41836
+ function describeDrawings(rows, containerDir = NOTES_CONTAINER_DIR) {
41837
+ return rows.map((row) => {
41838
+ const accountDir = resolveAccountDir(containerDir, row.accountIdentifier);
41839
+ const kind = row.uti === "com.apple.paper" ? "paper" : "drawing";
41840
+ const id2 = safeComponent(row.identifier);
41841
+ const fallbackImagePath = accountDir ? findFallbackImage(accountDir, row.identifier, row.fallbackImageGeneration) : null;
41842
+ const previewPath = accountDir ? findLargestPreview(accountDir, row.identifier) : null;
41843
+ const bundle = accountDir && id2 && kind === "paper" ? realInside(join7(accountDir, "Paper", "Bundles", `${id2}.bundle`), accountDir) : null;
41844
+ let raster = null;
41845
+ for (const [path7, source] of [
41846
+ [fallbackImagePath, "fallback"],
41847
+ [previewPath, "preview"]
41848
+ ]) {
41849
+ const info = path7 ? readImageInfo(path7) : null;
41850
+ if (path7 && info) {
41851
+ raster = { path: path7, source, ...info };
41852
+ break;
41853
+ }
41854
+ }
41855
+ return {
41856
+ pk: row.pk,
41857
+ identifier: row.identifier,
41858
+ uti: row.uti,
41859
+ kind,
41860
+ handwritingSummary: row.handwritingSummary,
41861
+ bundlePresent: bundle !== null && kindOf(bundle) === "dir",
41862
+ fallbackImagePath,
41863
+ previewPath,
41864
+ raster
41865
+ };
41866
+ });
41867
+ }
41868
+ function verifyWrittenImage(fd, path7, expected) {
41869
+ const check2 = readImageInfoFd(fd);
41870
+ if (!check2 || check2.format !== expected.format || check2.width !== expected.width || check2.height !== expected.height) {
41871
+ unlinkSync2(path7);
41872
+ throw new Error("The exported image failed validation and was removed.");
41873
+ }
41874
+ return check2;
41875
+ }
41876
+ function selectDrawing(drawings, noteId3, attachmentId) {
41877
+ if (attachmentId) {
41878
+ const wanted = attachmentId.toLowerCase();
41879
+ const found = drawings.find(
41880
+ (d) => d.identifier.toLowerCase() === wanted || attachmentCoreDataId(noteId3, d.pk).toLowerCase() === wanted
41881
+ );
41882
+ if (!found) throw new Error(`No Paper or drawing attachment "${attachmentId}" in this note.`);
41883
+ return found;
41884
+ }
41885
+ if (drawings.length === 0) throw new Error("This note has no Paper or drawing attachment.");
41886
+ if (drawings.length > 1) {
41887
+ throw new Error(
41888
+ `This note has ${drawings.length} Paper or drawing attachments; pass attachmentId (from list-paper-attachments) to choose one.`
41889
+ );
41890
+ }
41891
+ return drawings[0];
41892
+ }
41893
+ function exportDrawingRaster(drawing, savePath, containerDir = NOTES_CONTAINER_DIR) {
41894
+ if (!drawing.raster) {
41895
+ throw new Error(
41896
+ "Notes has no rendered image for this drawing on disk yet (open the note in Notes.app to let it render, then retry)."
41897
+ );
41898
+ }
41899
+ const abs = assertSafeSavePath(savePath);
41900
+ if (isInsideNotesContainer(abs, containerDir)) {
41901
+ throw new Error(`Refusing to write inside the Notes data container: "${abs}"`);
41902
+ }
41903
+ const ext = extname2(abs).toLowerCase();
41904
+ const expected = drawing.raster.format === "png" ? [".png"] : [".jpg", ".jpeg"];
41905
+ if (!expected.includes(ext)) {
41906
+ throw new Error(
41907
+ `The rendered image is ${drawing.raster.format.toUpperCase()}; savePath must end in ${expected.join(" or ")}.`
41908
+ );
41909
+ }
41910
+ mkdirSync3(dirname3(abs), { recursive: true });
41911
+ assertSafeSavePath(abs);
41912
+ if (isInsideNotesContainer(abs, containerDir)) {
41913
+ throw new Error(`Refusing to write inside the Notes data container: "${abs}"`);
41914
+ }
41915
+ const input = openSync3(drawing.raster.path, constants3.O_RDONLY | constants3.O_NOFOLLOW);
41916
+ let bytes = 0;
41917
+ try {
41918
+ if (!fstatSync3(input).isFile()) throw new Error("The rendered image is not a regular file");
41919
+ const header = Buffer.alloc(HEADER_BYTES);
41920
+ const headerLength = readSync2(input, header, 0, header.length, 0);
41921
+ const info = parseImageHeader(header.subarray(0, headerLength));
41922
+ if (!info || info.format !== drawing.raster.format) {
41923
+ throw new Error(
41924
+ "The rendered image changed or is not a valid PNG/JPEG; nothing was written."
41925
+ );
41926
+ }
41927
+ let output;
41928
+ try {
41929
+ output = openSync3(
41930
+ abs,
41931
+ constants3.O_RDWR | constants3.O_CREAT | constants3.O_EXCL | constants3.O_NOFOLLOW,
41932
+ 384
41933
+ );
41934
+ } catch (error2) {
41935
+ if (error2.code === "EEXIST") {
41936
+ throw new Error(`"${abs}" already exists; choose a new savePath.`);
41937
+ }
41938
+ throw error2;
41939
+ }
41940
+ try {
41941
+ const buffer = Buffer.allocUnsafe(1024 * 1024);
41942
+ let position = 0;
41943
+ for (; ; ) {
41944
+ const read = readSync2(input, buffer, 0, buffer.length, position);
41945
+ if (read === 0) break;
41946
+ position += read;
41947
+ let written = 0;
41948
+ while (written < read) written += writeSync2(output, buffer, written, read - written);
41949
+ }
41950
+ bytes = position;
41951
+ const check2 = verifyWrittenImage(output, abs, info);
41952
+ return { savedPath: abs, bytes, source: drawing.raster.source, ...check2 };
41953
+ } catch (error2) {
41954
+ try {
41955
+ unlinkSync2(abs);
41956
+ } catch {
41957
+ }
41958
+ throw error2;
41959
+ } finally {
41960
+ closeSync3(output);
41961
+ }
41962
+ } finally {
41963
+ closeSync3(input);
41964
+ }
41965
+ }
41966
+
41614
41967
  // src/services/appleNotesManager.ts
41615
41968
  var import_turndown = __toESM(require_turndown_cjs(), 1);
41616
41969
  import { existsSync as existsSync4 } from "fs";
41617
41970
  import { homedir as homedir7 } from "os";
41618
- import { join as join7 } from "path";
41971
+ import { join as join8 } from "path";
41619
41972
  var FIELD_SEP = "";
41620
41973
  var RECORD_SEP = "";
41621
41974
  var AS_FIELD_SEP = "(character id 31)";
@@ -41843,7 +42196,7 @@ function getNoteLinkFromDB(coreDataId2) {
41843
42196
  const match = coreDataId2.match(/\/p(\d+)$/);
41844
42197
  if (!match) return null;
41845
42198
  const pk = parseInt(match[1], 10);
41846
- const dbPath2 = join7(homedir7(), "Library/Group Containers/group.com.apple.notes/NoteStore.sqlite");
42199
+ const dbPath2 = join8(homedir7(), "Library/Group Containers/group.com.apple.notes/NoteStore.sqlite");
41847
42200
  if (!existsSync4(dbPath2)) return null;
41848
42201
  try {
41849
42202
  const { DatabaseSync } = __require("node:sqlite");
@@ -42840,7 +43193,7 @@ var AppleNotesManager = class {
42840
43193
  return [];
42841
43194
  }
42842
43195
  const recordSeparator = result.output.includes(RECORD_SEP) ? RECORD_SEP : "\n";
42843
- const entries = result.output.split(recordSeparator).map((line) => {
43196
+ const entries2 = result.output.split(recordSeparator).map((line) => {
42844
43197
  const parts = line.includes(FIELD_SEP) ? line.split(FIELD_SEP) : line.split(" ");
42845
43198
  return {
42846
43199
  id: (parts[0] || "").trim(),
@@ -42853,7 +43206,7 @@ var AppleNotesManager = class {
42853
43206
  account: (parts[4] || "").trim()
42854
43207
  };
42855
43208
  });
42856
- const byId = new Map(entries.map((e) => [e.id, e]));
43209
+ const byId = new Map(entries2.map((e) => [e.id, e]));
42857
43210
  const buildPath = (entry) => {
42858
43211
  const safeName = escapeFolderName(entry.name);
42859
43212
  if (!entry.parentId) return safeName;
@@ -42863,7 +43216,7 @@ var AppleNotesManager = class {
42863
43216
  }
42864
43217
  return safeName;
42865
43218
  };
42866
- return entries.map((entry) => ({
43219
+ return entries2.map((entry) => ({
42867
43220
  id: entry.id,
42868
43221
  name: buildPath(entry),
42869
43222
  account: entry.account || targetAccount || "",
@@ -43765,6 +44118,24 @@ var AppleNotesManager = class {
43765
44118
  cleanupTempDir(dir);
43766
44119
  }
43767
44120
  }
44121
+ /**
44122
+ * Lists a note's Paper (`com.apple.paper`) and classic drawing attachments
44123
+ * with Notes' rendered raster, read-only from NoteStore and the Notes group
44124
+ * container. Requires Full Disk Access.
44125
+ *
44126
+ * @throws PaperStoreError (`no_fda`, `invalid_id`, `not_found`, `query_error`)
44127
+ */
44128
+ listPaperAttachmentsById(noteId3) {
44129
+ return describeDrawings(readDrawingRows(noteId3));
44130
+ }
44131
+ /**
44132
+ * Copies Notes' rendered raster of one drawing to a new file. `attachmentId`
44133
+ * (identifier or AppleScript id) is required when the note has more than one.
44134
+ */
44135
+ exportPaperImageById(noteId3, savePath, attachmentId) {
44136
+ const drawing = selectDrawing(this.listPaperAttachmentsById(noteId3), noteId3, attachmentId);
44137
+ return { drawing, ...exportDrawingRaster(drawing, savePath) };
44138
+ }
43768
44139
  /**
43769
44140
  * Reads one note's attachments with their on-disk asset and preview paths,
43770
44141
  * in body order, from the NoteStore database and the Notes group container
@@ -44209,7 +44580,7 @@ var AppleNotesManager = class {
44209
44580
  };
44210
44581
 
44211
44582
  // src/utils/syncDetection.ts
44212
- import { execFileSync as execFileSync7 } from "child_process";
44583
+ import { execFileSync as execFileSync8 } from "child_process";
44213
44584
  import * as fs3 from "fs";
44214
44585
  import * as path3 from "path";
44215
44586
  import * as os3 from "os";
@@ -44254,7 +44625,7 @@ function getSyncStatus(useCache = true) {
44254
44625
  WHERE object.ZCLOUDSTATE = state.Z_PK
44255
44626
  );
44256
44627
  `;
44257
- const result = execFileSync7(
44628
+ const result = execFileSync8(
44258
44629
  "sqlite3",
44259
44630
  ["-readonly", NOTES_DB_PATH4, query.replace(/\n/g, " ")],
44260
44631
  {
@@ -44313,7 +44684,7 @@ function withSyncAwarenessSync(operation, fn) {
44313
44684
  }
44314
44685
 
44315
44686
  // src/utils/noteMetadata.ts
44316
- import { execFileSync as execFileSync8 } from "child_process";
44687
+ import { execFileSync as execFileSync9 } from "child_process";
44317
44688
  import * as fs4 from "fs";
44318
44689
  import * as path4 from "path";
44319
44690
  import * as os4 from "os";
@@ -44333,15 +44704,15 @@ var COLUMN_MAP = [
44333
44704
  { key: "widgetSnippet", column: "ZWIDGETSNIPPET", type: "text" },
44334
44705
  { key: "smartFolderQuery", column: "ZSMARTFOLDERQUERYJSON", type: "text" }
44335
44706
  ];
44336
- function runSqlite4(query) {
44337
- return execFileSync8("sqlite3", ["-readonly", NOTES_DB_PATH5, query], {
44707
+ function runSqlite5(query) {
44708
+ return execFileSync9("sqlite3", ["-readonly", NOTES_DB_PATH5, query], {
44338
44709
  encoding: "utf8",
44339
44710
  timeout: 5e3,
44340
44711
  stdio: ["pipe", "pipe", "pipe"]
44341
44712
  }).trim();
44342
44713
  }
44343
44714
  function presentColumns() {
44344
- const out = runSqlite4("PRAGMA table_info(ZICCLOUDSYNCINGOBJECT);");
44715
+ const out = runSqlite5("PRAGMA table_info(ZICCLOUDSYNCINGOBJECT);");
44345
44716
  const cols = /* @__PURE__ */ new Set();
44346
44717
  for (const line of out.split("\n")) {
44347
44718
  const name = line.split("|")[1];
@@ -44369,7 +44740,7 @@ function getNoteMetadata(noteId3) {
44369
44740
  return { metadata: {} };
44370
44741
  }
44371
44742
  const pairs = selected.map((c) => `'${c.key}', ${c.column}`).join(", ");
44372
- const row = runSqlite4(
44743
+ const row = runSqlite5(
44373
44744
  `SELECT json_object(${pairs}) FROM ZICCLOUDSYNCINGOBJECT WHERE Z_PK = ${pk};`
44374
44745
  );
44375
44746
  if (!row) {
@@ -44402,7 +44773,7 @@ function getNoteMetadata(noteId3) {
44402
44773
  }
44403
44774
 
44404
44775
  // src/utils/noteIdentifiers.ts
44405
- import { execFileSync as execFileSync9 } from "child_process";
44776
+ import { execFileSync as execFileSync10 } from "child_process";
44406
44777
  import * as fs5 from "fs";
44407
44778
  import * as os5 from "os";
44408
44779
  import * as path5 from "path";
@@ -44484,7 +44855,7 @@ function runJsonQuery(sql, dbPath2) {
44484
44855
  if (!fs5.existsSync(dbPath2)) throw new IdentifierResolutionError("no_fda", NO_FDA_MESSAGE);
44485
44856
  let out;
44486
44857
  try {
44487
- out = execFileSync9("sqlite3", ["-readonly", dbPath2, sql], {
44858
+ out = execFileSync10("sqlite3", ["-readonly", dbPath2, sql], {
44488
44859
  encoding: "utf8",
44489
44860
  timeout: 5e3,
44490
44861
  stdio: ["pipe", "pipe", "pipe"]
@@ -45174,7 +45545,7 @@ function positiveTextTerms(node, negated = false) {
45174
45545
  }
45175
45546
 
45176
45547
  // src/utils/noteQueryStore.ts
45177
- import { execFileSync as execFileSync10 } from "child_process";
45548
+ import { execFileSync as execFileSync11 } from "child_process";
45178
45549
  import * as fs6 from "fs";
45179
45550
  import * as os6 from "os";
45180
45551
  import * as path6 from "path";
@@ -45314,8 +45685,8 @@ function buildScanSql(available, options) {
45314
45685
  "COMMIT;"
45315
45686
  ].join(" ");
45316
45687
  }
45317
- function runSqlite5(dbPath2, query) {
45318
- return execFileSync10("sqlite3", ["-readonly", dbPath2, query], {
45688
+ function runSqlite6(dbPath2, query) {
45689
+ return execFileSync11("sqlite3", ["-readonly", dbPath2, query], {
45319
45690
  encoding: "utf8",
45320
45691
  timeout: 3e4,
45321
45692
  maxBuffer: 512 * 1024 * 1024,
@@ -45324,7 +45695,7 @@ function runSqlite5(dbPath2, query) {
45324
45695
  }
45325
45696
  function presentColumns2(dbPath2) {
45326
45697
  const cols = /* @__PURE__ */ new Set();
45327
- for (const line of runSqlite5(dbPath2, "PRAGMA table_info(ZICCLOUDSYNCINGOBJECT);").split("\n")) {
45698
+ for (const line of runSqlite6(dbPath2, "PRAGMA table_info(ZICCLOUDSYNCINGOBJECT);").split("\n")) {
45328
45699
  const name = line.split("|")[1];
45329
45700
  if (name) cols.add(name);
45330
45701
  }
@@ -45384,7 +45755,7 @@ function queryNotes(expression, options = {}) {
45384
45755
  let output;
45385
45756
  try {
45386
45757
  const available = presentColumns2(dbPath2);
45387
- output = runSqlite5(
45758
+ output = runSqlite6(
45388
45759
  dbPath2,
45389
45760
  buildScanSql(available, { scanLimit, includeDeleted, withBodies, withTags })
45390
45761
  );
@@ -45515,10 +45886,10 @@ function queryNotes(expression, options = {}) {
45515
45886
  import { spawnSync } from "child_process";
45516
45887
 
45517
45888
  // src/services/nativeTags.ts
45518
- import { execFileSync as execFileSync11 } from "node:child_process";
45889
+ import { execFileSync as execFileSync12 } from "node:child_process";
45519
45890
  import { mkdtempSync as mkdtempSync2, writeFileSync, rmSync as rmSync2 } from "node:fs";
45520
45891
  import { tmpdir as tmpdir2 } from "node:os";
45521
- import { join as join12 } from "node:path";
45892
+ import { join as join13 } from "node:path";
45522
45893
 
45523
45894
  // src/services/shortcutConsent.ts
45524
45895
  function shortcutConsentHint(shortcut) {
@@ -45594,7 +45965,7 @@ function addNativeTags(request, deps) {
45594
45965
  };
45595
45966
  }
45596
45967
  function listInstalledShortcuts() {
45597
- return execFileSync11("/usr/bin/shortcuts", ["list", "--show-identifiers"], {
45968
+ return execFileSync12("/usr/bin/shortcuts", ["list", "--show-identifiers"], {
45598
45969
  encoding: "utf8",
45599
45970
  timeout: 15e3,
45600
45971
  maxBuffer: 1024 * 1024,
@@ -45620,11 +45991,11 @@ function runNativeTagsShortcut(input) {
45620
45991
  const status = nativeTagsStatus();
45621
45992
  if (!status.installed)
45622
45993
  throw new Error(`Import the supplied ${status.shortcut}.shortcut in Shortcuts first`);
45623
- const directory = mkdtempSync2(join12(tmpdir2(), "apple-notes-native-tags-"));
45994
+ const directory = mkdtempSync2(join13(tmpdir2(), "apple-notes-native-tags-"));
45624
45995
  try {
45625
- const path7 = join12(directory, "request.json");
45996
+ const path7 = join13(directory, "request.json");
45626
45997
  writeFileSync(path7, JSON.stringify(input), { mode: 384 });
45627
- execFileSync11("/usr/bin/shortcuts", ["run", status.identifier, "--input-path", path7], {
45998
+ execFileSync12("/usr/bin/shortcuts", ["run", status.identifier, "--input-path", path7], {
45628
45999
  encoding: "utf8",
45629
46000
  timeout: 6e4,
45630
46001
  maxBuffer: 1024 * 1024,
@@ -45643,10 +46014,10 @@ function runNativeTagsShortcut(input) {
45643
46014
  }
45644
46015
 
45645
46016
  // src/services/backgroundNotes.ts
45646
- import { execFileSync as execFileSync12 } from "node:child_process";
46017
+ import { execFileSync as execFileSync13 } from "node:child_process";
45647
46018
  import { mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync2, rmSync as rmSync3 } from "node:fs";
45648
46019
  import { tmpdir as tmpdir3 } from "node:os";
45649
- import { join as join13 } from "node:path";
46020
+ import { join as join14 } from "node:path";
45650
46021
 
45651
46022
  // src/utils/appendMarkdown.ts
45652
46023
  var escape2 = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
@@ -45971,9 +46342,9 @@ function runBackgroundShortcut(input, status = backgroundStatus()) {
45971
46342
  throw new Error(
45972
46343
  `Install the supplied "${status.shortcut}" Shortcut once; Shortcuts must list it exactly once`
45973
46344
  );
45974
- const directory = mkdtempSync3(join13(tmpdir3(), "apple-notes-background-"));
46345
+ const directory = mkdtempSync3(join14(tmpdir3(), "apple-notes-background-"));
45975
46346
  try {
45976
- const file = join13(directory, "request.json");
46347
+ const file = join14(directory, "request.json");
45977
46348
  writeFileSync2(
45978
46349
  file,
45979
46350
  JSON.stringify({
@@ -45993,7 +46364,7 @@ function runBackgroundShortcut(input, status = backgroundStatus()) {
45993
46364
  { mode: 384 }
45994
46365
  );
45995
46366
  try {
45996
- execFileSync12("/usr/bin/shortcuts", ["run", status.identifier, "--input-path", file], {
46367
+ execFileSync13("/usr/bin/shortcuts", ["run", status.identifier, "--input-path", file], {
45997
46368
  encoding: "utf8",
45998
46369
  timeout: callTimeoutMs() ?? 6e4,
45999
46370
  maxBuffer: 1024 * 1024,
@@ -46318,7 +46689,7 @@ ${request.content}`
46318
46689
  }
46319
46690
 
46320
46691
  // src/services/capabilityMatrix.ts
46321
- import { execFileSync as execFileSync13 } from "node:child_process";
46692
+ import { execFileSync as execFileSync14 } from "node:child_process";
46322
46693
  import { release } from "node:os";
46323
46694
  var MACOS_SHORTCUTS_CLI = "12.0";
46324
46695
  var MACOS_MARKDOWN_IMPORT = "26.0";
@@ -46525,7 +46896,7 @@ function evaluateFeatures(env, features = FEATURES) {
46525
46896
  function readMacOSVersion() {
46526
46897
  if (process.platform !== "darwin") return null;
46527
46898
  try {
46528
- const out = execFileSync13("/usr/bin/sw_vers", ["-productVersion"], {
46899
+ const out = execFileSync14("/usr/bin/sw_vers", ["-productVersion"], {
46529
46900
  encoding: "utf8",
46530
46901
  timeout: 3e3,
46531
46902
  stdio: ["ignore", "pipe", "ignore"]
@@ -46679,12 +47050,12 @@ function formatDoctorReport(r) {
46679
47050
 
46680
47051
  // src/services/fileConfig.ts
46681
47052
  import { existsSync as existsSync9, readFileSync as readFileSync2 } from "fs";
46682
- import { join as join14 } from "path";
47053
+ import { join as join15 } from "path";
46683
47054
  import { homedir as homedir12 } from "os";
46684
47055
  function fileConfigPath(env = process.env) {
46685
47056
  const override = env.APPLE_NOTES_MCP_CONFIG_FILE;
46686
47057
  if (override && override.trim()) return override.trim();
46687
- return join14(homedir12(), "Library", "Application Support", "apple-notes-mcp", "config.json");
47058
+ return join15(homedir12(), "Library", "Application Support", "apple-notes-mcp", "config.json");
46688
47059
  }
46689
47060
  function loadFileConfig(env = process.env, path7 = fileConfigPath(env)) {
46690
47061
  const applied = [];
@@ -46987,10 +47358,10 @@ function createShutdown(stream, exit, timeoutMs = SHUTDOWN_DRAIN_TIMEOUT_MS) {
46987
47358
  }
46988
47359
 
46989
47360
  // src/utils/noteBlocks.ts
46990
- import { execFileSync as execFileSync14 } from "node:child_process";
47361
+ import { execFileSync as execFileSync15 } from "node:child_process";
46991
47362
  import { existsSync as existsSync10 } from "node:fs";
46992
47363
  import { homedir as homedir13 } from "node:os";
46993
- import { join as join15 } from "node:path";
47364
+ import { join as join16 } from "node:path";
46994
47365
  import { gunzipSync as gunzipSync7 } from "node:zlib";
46995
47366
  var NoteBlocksError = class extends Error {
46996
47367
  code;
@@ -47333,7 +47704,7 @@ function pageNoteBlocks(doc, { offset = 0, limit = 500, maxBytes = blocksMaxResp
47333
47704
  undecodedFields: doc.undecodedFields
47334
47705
  };
47335
47706
  }
47336
- var NOTES_DB_PATH8 = join15(
47707
+ var NOTES_DB_PATH8 = join16(
47337
47708
  homedir13(),
47338
47709
  "Library/Group Containers/group.com.apple.notes/NoteStore.sqlite"
47339
47710
  );
@@ -47349,7 +47720,7 @@ function readNoteBlocks(id2, { dbPath: dbPath2 = NOTES_DB_PATH8 } = {}) {
47349
47720
  const sql = "SELECT json_object('exists', (SELECT count(*) FROM ZICCLOUDSYNCINGOBJECT WHERE Z_PK = @pk AND Z_ENT = (SELECT Z_ENT FROM Z_PRIMARYKEY WHERE Z_NAME = 'ICNote')), 'data', (SELECT hex(ZDATA) FROM ZICNOTEDATA WHERE ZNOTE = @pk), 'encrypted', (SELECT ZCRYPTOINITIALIZATIONVECTOR IS NOT NULL FROM ZICNOTEDATA WHERE ZNOTE = @pk));";
47350
47721
  let output;
47351
47722
  try {
47352
- output = execFileSync14(
47723
+ output = execFileSync15(
47353
47724
  "/usr/bin/sqlite3",
47354
47725
  ["-readonly", "-cmd", ".parameter init", "-cmd", `.parameter set @pk ${pk}`, dbPath2, sql],
47355
47726
  {
@@ -47500,17 +47871,17 @@ function insertLink(request, deps) {
47500
47871
  // src/tools/directOperations.ts
47501
47872
  import { createHash as createHash2 } from "node:crypto";
47502
47873
  import {
47503
- closeSync as closeSync3,
47504
- constants as constants3,
47505
- fstatSync as fstatSync3,
47874
+ closeSync as closeSync4,
47875
+ constants as constants4,
47876
+ fstatSync as fstatSync4,
47506
47877
  mkdtempSync as mkdtempSync4,
47507
- openSync as openSync3,
47878
+ openSync as openSync4,
47508
47879
  readFileSync as readFileSync3,
47509
47880
  rmSync as rmSync4,
47510
47881
  writeFileSync as writeFileSync3
47511
47882
  } from "node:fs";
47512
47883
  import { tmpdir as tmpdir4 } from "node:os";
47513
- import { basename as basename2, extname as extname2, isAbsolute as isAbsolute3, join as join16 } from "node:path";
47884
+ import { basename as basename3, extname as extname3, isAbsolute as isAbsolute3, join as join17 } from "node:path";
47514
47885
  var noteId = exactIdInput(
47515
47886
  "ICNote",
47516
47887
  /^x-coredata:\/\/[0-9a-f-]+\/ICNote\/p\d+$/i,
@@ -47555,9 +47926,9 @@ function assertExistingContentPreserved(before, after) {
47555
47926
  }
47556
47927
  function localAttachment(path7) {
47557
47928
  if (!isAbsolute3(path7)) throw new Error("An absolute local file path is required");
47558
- const descriptor = openSync3(path7, constants3.O_RDONLY | constants3.O_NOFOLLOW);
47929
+ const descriptor = openSync4(path7, constants4.O_RDONLY | constants4.O_NOFOLLOW);
47559
47930
  try {
47560
- const stat = fstatSync3(descriptor);
47931
+ const stat = fstatSync4(descriptor);
47561
47932
  if (!stat.isFile() || stat.size === 0 || stat.size > 64 * 1024 * 1024)
47562
47933
  throw new Error("Attachment must be a nonempty regular file of at most 64 MiB");
47563
47934
  const bytes = readFileSync3(descriptor);
@@ -47565,7 +47936,7 @@ function localAttachment(path7) {
47565
47936
  throw new Error("Attachment changed while it was being read; try again");
47566
47937
  return bytes;
47567
47938
  } finally {
47568
- closeSync3(descriptor);
47939
+ closeSync4(descriptor);
47569
47940
  }
47570
47941
  }
47571
47942
  function registerDirectOperations(server2, manager) {
@@ -47678,7 +48049,7 @@ function registerDirectOperations(server2, manager) {
47678
48049
  );
47679
48050
  }
47680
48051
  function attachmentName(path7, filename) {
47681
- const source = basename2(path7);
48052
+ const source = basename3(path7);
47682
48053
  if (filename === void 0) return source;
47683
48054
  if (Buffer.byteLength(filename, "utf8") > 255)
47684
48055
  throw new Error("filename must be at most 255 bytes");
@@ -47686,9 +48057,9 @@ function attachmentName(path7, filename) {
47686
48057
  throw new Error(
47687
48058
  "filename must be one path component with no slash, colon, backslash, control character, leading dot, or surrounding spaces"
47688
48059
  );
47689
- if (extname2(filename).toLowerCase() !== extname2(source).toLowerCase())
48060
+ if (extname3(filename).toLowerCase() !== extname3(source).toLowerCase())
47690
48061
  throw new Error(
47691
- `filename must keep the source file's extension (${extname2(source) || "none"})`
48062
+ `filename must keep the source file's extension (${extname3(source) || "none"})`
47692
48063
  );
47693
48064
  return filename;
47694
48065
  }
@@ -47699,8 +48070,8 @@ function attachFile(manager, args) {
47699
48070
  if (before.hash !== expectedContentHash) throw new Error("Note revision changed");
47700
48071
  const bytes = localAttachment(path7);
47701
48072
  const beforeAttachments = manager.listAttachmentsById(id2);
47702
- const directory = mkdtempSync4(join16(tmpdir4(), "notes-attachment-add-"));
47703
- const temporaryFile = join16(directory, name);
48073
+ const directory = mkdtempSync4(join17(tmpdir4(), "notes-attachment-add-"));
48074
+ const temporaryFile = join17(directory, name);
47704
48075
  try {
47705
48076
  writeFileSync3(temporaryFile, bytes, { mode: 384 });
47706
48077
  if (readSnapshot(manager, id2).hash !== before.hash) throw new Error("Note revision changed");
@@ -48260,7 +48631,7 @@ function registerNativeOperations(server2, manager) {
48260
48631
  import { spawnSync as spawnSync2 } from "node:child_process";
48261
48632
  import { existsSync as existsSync11 } from "node:fs";
48262
48633
  import { release as release2 } from "node:os";
48263
- import { dirname as dirname3, resolve as resolve3 } from "node:path";
48634
+ import { dirname as dirname4, resolve as resolve3 } from "node:path";
48264
48635
  import { fileURLToPath } from "node:url";
48265
48636
  var OPTIONAL_BRIDGE_NOTE = "(optional \u2014 needed only for create-note format: markdown, macOS 26+)";
48266
48637
  var MARKDOWN_MIN_DARWIN_MAJOR = 25;
@@ -48283,7 +48654,7 @@ function setupShortcuts(checkOnly, dependencies = {}) {
48283
48654
  const result = spawnSync2("/usr/bin/open", [path7], { encoding: "utf8" });
48284
48655
  return result.status === 0 ? { ok: true } : { ok: false, error: result.stderr || result.error?.message || "open failed" };
48285
48656
  });
48286
- const baseDirectory = dependencies.baseDirectory || resolve3(dirname3(fileURLToPath(import.meta.url)), "../shortcuts");
48657
+ const baseDirectory = dependencies.baseDirectory || resolve3(dirname4(fileURLToPath(import.meta.url)), "../shortcuts");
48287
48658
  const osRelease = (dependencies.osRelease || release2)();
48288
48659
  const darwinMajor = Number.parseInt(osRelease.split(".")[0], 10);
48289
48660
  const items = shortcutFiles.map(({ name, file, optional: optional2 }) => {
@@ -50372,6 +50743,88 @@ registerTool(
50372
50743
  });
50373
50744
  }, "Error saving attachment")
50374
50745
  );
50746
+ function drawingView(noteId3, d) {
50747
+ const { pk, raster, ...rest } = d;
50748
+ return {
50749
+ attachmentId: attachmentCoreDataId(noteId3, pk),
50750
+ ...rest,
50751
+ raster: raster ? { source: raster.source, format: raster.format, width: raster.width, height: raster.height } : null
50752
+ };
50753
+ }
50754
+ registerTool(
50755
+ "list-paper-attachments",
50756
+ {
50757
+ description: "Use when: finding the Paper drawings (com.apple.paper) and classic drawings in one note, and whether Notes has a rendered image of each.\nReturns: per drawing its attachmentId, identifier, uti, kind (paper or drawing), handwritingSummary (Notes' recognized handwriting text, or null), bundlePresent, fallbackImagePath, previewPath, and raster {source, format, width, height} (the validated image export-paper-image would copy, or null).\nDo not use when: you want every attachment (list-attachments) or the image file itself (export-paper-image).\nSafety: read-only; reads NoteStore and the Notes data folder without opening Notes.app and requires Full Disk Access. Strokes are not decoded: Notes' Paper bundle has no public reader, so the raster is Notes' own rendering.",
50758
+ inputSchema: { id: noteIdInput },
50759
+ outputSchema: {
50760
+ attachments: external_exports.array(external_exports.object({}).passthrough()).optional(),
50761
+ count: external_exports.number().optional()
50762
+ },
50763
+ annotations: { readOnlyHint: true }
50764
+ },
50765
+ withErrorHandling(({ id: id2 }) => {
50766
+ const drawings = notesManager.listPaperAttachmentsById(id2).map((d) => drawingView(id2, d));
50767
+ if (drawings.length === 0) {
50768
+ return successResponse("This note has no Paper or drawing attachments.", {
50769
+ attachments: [],
50770
+ count: 0
50771
+ });
50772
+ }
50773
+ const lines = drawings.map(
50774
+ (d) => ` - ${d.kind} ${d.attachmentId}: ${d.raster ? `${d.raster.format.toUpperCase()} ${d.raster.width}x${d.raster.height} (${d.raster.source})` : "no rendered image on disk"}${d.handwritingSummary ? "; handwriting text stored" : ""}`
50775
+ );
50776
+ return successResponse(
50777
+ `Found ${drawings.length} Paper or drawing attachment(s):
50778
+ ${lines.join("\n")}`,
50779
+ { attachments: drawings, count: drawings.length }
50780
+ );
50781
+ }, "Error listing Paper attachments")
50782
+ );
50783
+ registerTool(
50784
+ "export-paper-image",
50785
+ {
50786
+ description: "Use when: saving Notes' rendered image of a Paper drawing or classic drawing to a file.\nReturns: savedPath, format (png or jpeg), width, height, bytes, source (fallback: Notes' full rendering; preview: its largest thumbnail, used only when no full rendering exists), and the drawing's attachmentId and handwritingSummary.\nDo not use when: the attachment is a photo or file (save-attachment or export-attachments).\nSafety: writes one new file; savePath must be absolute, under the home directory, a temp dir, or /Volumes, outside the Notes data folder, must not exist yet, and must end in the image's extension (.png, or .jpg/.jpeg). The image header is validated before and after copying. Pass attachmentId (from list-paper-attachments) when the note has more than one drawing. Requires Full Disk Access; Notes.app is not opened.",
50787
+ inputSchema: {
50788
+ noteId: noteIdInput,
50789
+ savePath: external_exports.string().min(1, "savePath is required").max(MAX.SAVE_PATH).describe(
50790
+ "Absolute path for the new image file (.png, or .jpg/.jpeg for a JPEG rendering)"
50791
+ ),
50792
+ attachmentId: external_exports.string().max(MAX.ATTACHMENT_ID).optional().describe(
50793
+ "Drawing to export (attachmentId or identifier from list-paper-attachments); required when the note has more than one"
50794
+ )
50795
+ },
50796
+ outputSchema: {
50797
+ savedPath: external_exports.string().optional(),
50798
+ format: external_exports.enum(["png", "jpeg"]).optional(),
50799
+ width: external_exports.number().optional(),
50800
+ height: external_exports.number().optional(),
50801
+ bytes: external_exports.number().optional(),
50802
+ source: external_exports.enum(["fallback", "preview"]).optional(),
50803
+ attachmentId: external_exports.string().optional(),
50804
+ identifier: external_exports.string().optional(),
50805
+ kind: external_exports.enum(["paper", "drawing"]).optional(),
50806
+ handwritingSummary: external_exports.string().nullable().optional()
50807
+ }
50808
+ },
50809
+ withErrorHandling(({ noteId: noteId3, savePath, attachmentId }) => {
50810
+ const r = notesManager.exportPaperImageById(noteId3, savePath, attachmentId);
50811
+ return successResponse(
50812
+ `Saved ${r.format.toUpperCase()} ${r.width}x${r.height} (${r.bytes} bytes, ${r.source === "fallback" ? "Notes' full rendering" : "largest preview"}) to ${r.savedPath}`,
50813
+ {
50814
+ savedPath: r.savedPath,
50815
+ format: r.format,
50816
+ width: r.width,
50817
+ height: r.height,
50818
+ bytes: r.bytes,
50819
+ source: r.source,
50820
+ attachmentId: attachmentCoreDataId(noteId3, r.drawing.pk),
50821
+ identifier: r.drawing.identifier,
50822
+ kind: r.drawing.kind,
50823
+ handwritingSummary: r.drawing.handwritingSummary
50824
+ }
50825
+ );
50826
+ }, "Error exporting Paper image")
50827
+ );
50375
50828
  registerTool(
50376
50829
  "export-attachments",
50377
50830
  {