apple-notes-mcp 2.8.39 → 2.8.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/build/index.js +37 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -555,6 +555,11 @@ changed after this read. With Full Disk Access, embedded URLs omitted by
|
|
|
555
555
|
AppleScript are restored and returned in `links`. The response also reports
|
|
556
556
|
actual `nativeTags`, `richContentComplete`, and `writable`. Textual `hashtags`
|
|
557
557
|
remain a separate field and are not proof that Notes registered native tags.
|
|
558
|
+
`writable` is also false when the note uses formatting that AppleScript's HTML
|
|
559
|
+
does not carry (superscript, subscript, non-left paragraph alignment, or
|
|
560
|
+
highlight): a full-body `update-note` would silently drop it, so it is refused
|
|
561
|
+
and the `warning` names the formatting. `append-to-note` with `scopeText` still
|
|
562
|
+
works through the native path, which verifies existing formatting.
|
|
558
563
|
|
|
559
564
|
**⚠️ The returned body can be lossy — do not write it back verbatim.** Inline
|
|
560
565
|
base64 images larger than `APPLE_NOTES_MCP_MAX_INLINE_IMAGE_BYTES` (default
|
package/build/index.js
CHANGED
|
@@ -39275,21 +39275,13 @@ var WIRE_TYPE = {
|
|
|
39275
39275
|
};
|
|
39276
39276
|
function decodeVarint(buf, offset) {
|
|
39277
39277
|
let result = 0;
|
|
39278
|
-
let shift = 0;
|
|
39279
|
-
|
|
39280
|
-
while (pos < buf.length) {
|
|
39281
|
-
const byte = buf[pos];
|
|
39278
|
+
for (let pos = offset, shift = 0; pos < buf.length && shift < 28; shift += 7) {
|
|
39279
|
+
const byte = buf[pos++];
|
|
39282
39280
|
result |= (byte & 127) << shift;
|
|
39283
|
-
pos
|
|
39284
|
-
if ((byte & 128) === 0) {
|
|
39285
|
-
return [result, pos];
|
|
39286
|
-
}
|
|
39287
|
-
shift += 7;
|
|
39288
|
-
if (shift > 35) {
|
|
39289
|
-
throw new Error(`Varint too long at offset ${offset}`);
|
|
39290
|
-
}
|
|
39281
|
+
if ((byte & 128) === 0) return [result, pos];
|
|
39291
39282
|
}
|
|
39292
|
-
|
|
39283
|
+
const [value, next] = decodeVarint64(buf, offset);
|
|
39284
|
+
return [Number(BigInt.asIntN(64, value)), next];
|
|
39293
39285
|
}
|
|
39294
39286
|
function decodeMessage(buf, options = {}) {
|
|
39295
39287
|
const fields = [];
|
|
@@ -39306,7 +39298,7 @@ function decodeMessage(buf, options = {}) {
|
|
|
39306
39298
|
} else if (wireType === WIRE_TYPE.LENGTH_DELIMITED) {
|
|
39307
39299
|
let length;
|
|
39308
39300
|
[length, offset] = decodeVarint(buf, offset);
|
|
39309
|
-
if (offset + length > buf.length) {
|
|
39301
|
+
if (length < 0 || offset + length > buf.length) {
|
|
39310
39302
|
break;
|
|
39311
39303
|
}
|
|
39312
39304
|
const value = buf.slice(offset, offset + length);
|
|
@@ -39623,6 +39615,12 @@ import { createHash } from "node:crypto";
|
|
|
39623
39615
|
import { homedir as homedir2 } from "node:os";
|
|
39624
39616
|
import { join as join2 } from "node:path";
|
|
39625
39617
|
import { gunzipSync as gunzipSync2 } from "node:zlib";
|
|
39618
|
+
var HTML_LOSSY_ORDER = [
|
|
39619
|
+
"superscript",
|
|
39620
|
+
"subscript",
|
|
39621
|
+
"alignment",
|
|
39622
|
+
"highlight"
|
|
39623
|
+
];
|
|
39626
39624
|
var dbPath = join2(homedir2(), "Library/Group Containers/group.com.apple.notes/NoteStore.sqlite");
|
|
39627
39625
|
var safeUrl = (url) => /^(?:https?:\/\/|notes:\/\/|applenotes:|mailto:)/i.test(url) && !Array.from(url).some((char) => char.charCodeAt(0) < 32);
|
|
39628
39626
|
var escapeAttribute = (text2) => text2.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
@@ -39643,6 +39641,7 @@ function styleValue(field) {
|
|
|
39643
39641
|
else if (wire === 5) offset += 4;
|
|
39644
39642
|
else if (wire === 2) {
|
|
39645
39643
|
[length, offset] = decodeVarint(data, offset);
|
|
39644
|
+
if (length < 0) return Buffer.from(data).toString("hex");
|
|
39646
39645
|
offset += length;
|
|
39647
39646
|
} else return Buffer.from(data).toString("hex");
|
|
39648
39647
|
if (offset > data.length) return Buffer.from(data).toString("hex");
|
|
@@ -39669,6 +39668,7 @@ function parseRichNote(data, nativeTags = []) {
|
|
|
39669
39668
|
let position = 0;
|
|
39670
39669
|
let hasNativeObjects = false;
|
|
39671
39670
|
let hasChecklist = false;
|
|
39671
|
+
const lossy = /* @__PURE__ */ new Set();
|
|
39672
39672
|
for (const run of getFields(body, 5)) {
|
|
39673
39673
|
const fields = embeddedMessage(run);
|
|
39674
39674
|
if (!fields) throw new Error("Invalid Notes attribute run");
|
|
@@ -39686,6 +39686,13 @@ function parseRichNote(data, nativeTags = []) {
|
|
|
39686
39686
|
fields.filter((f) => f.fieldNumber >= 2 && f.fieldNumber <= 12 || f.fieldNumber === 14).map((f) => [f.fieldNumber, styleValue(f)])
|
|
39687
39687
|
)
|
|
39688
39688
|
});
|
|
39689
|
+
if (/[^\s\ufffc]/u.test(text2.slice(position, position + length))) {
|
|
39690
|
+
const baseline = varintValue(getField(fields, 8)) ?? 0;
|
|
39691
|
+
if (baseline > 0) lossy.add("superscript");
|
|
39692
|
+
if (baseline < 0) lossy.add("subscript");
|
|
39693
|
+
if (paragraph && (varintValue(getField(paragraph, 2)) ?? 0) !== 0) lossy.add("alignment");
|
|
39694
|
+
if (varintValue(getField(fields, 14))) lossy.add("highlight");
|
|
39695
|
+
}
|
|
39689
39696
|
const url = stringValue(getField(fields, 9));
|
|
39690
39697
|
if (url) {
|
|
39691
39698
|
if (!safeUrl(url)) throw new Error("Unsupported link scheme in note");
|
|
@@ -39737,7 +39744,8 @@ function parseRichNote(data, nativeTags = []) {
|
|
|
39737
39744
|
revision: createHash("sha256").update(data).digest("hex"),
|
|
39738
39745
|
objects,
|
|
39739
39746
|
checklistItems,
|
|
39740
|
-
styleRuns
|
|
39747
|
+
styleRuns,
|
|
39748
|
+
...lossy.size ? { htmlLossyFormatting: HTML_LOSSY_ORDER.filter((f) => lossy.has(f)) } : {}
|
|
39741
39749
|
};
|
|
39742
39750
|
}
|
|
39743
39751
|
function readRichNote(id2) {
|
|
@@ -39854,17 +39862,26 @@ function enrichNoteRead(id2, rawBody) {
|
|
|
39854
39862
|
const rich = readRichNote(id2);
|
|
39855
39863
|
metadata = rich;
|
|
39856
39864
|
const content = restoreNoteLinks(rawBody, rich);
|
|
39857
|
-
const
|
|
39865
|
+
const complete = !rich.hasNativeObjects && !rich.hasChecklist;
|
|
39866
|
+
const lossy = rich.htmlLossyFormatting ?? [];
|
|
39867
|
+
const writable = complete && lossy.length === 0;
|
|
39868
|
+
const warnings = [];
|
|
39869
|
+
if (!complete)
|
|
39870
|
+
warnings.push(
|
|
39871
|
+
"Native tags, inline objects or checklists are present. Their state is not writable through AppleScript; full-body edits are blocked to preserve them."
|
|
39872
|
+
);
|
|
39873
|
+
if (lossy.length)
|
|
39874
|
+
warnings.push(
|
|
39875
|
+
`This note uses formatting that Notes' AppleScript HTML does not carry (${lossy.join(", ")}); a full-body edit would silently drop it, so full-body edits are blocked. Edit it in Notes.app, or use append-to-note with scopeText, which appends natively and verifies existing formatting.`
|
|
39876
|
+
);
|
|
39858
39877
|
return {
|
|
39859
39878
|
content,
|
|
39860
39879
|
links: rich.links,
|
|
39861
39880
|
nativeTags: rich.nativeTags,
|
|
39862
|
-
complete
|
|
39881
|
+
complete,
|
|
39863
39882
|
writable,
|
|
39864
39883
|
revision: rich.revision,
|
|
39865
|
-
|
|
39866
|
-
warning: "Native tags, inline objects or checklists are present. Their state is not writable through AppleScript; full-body edits are blocked to preserve them."
|
|
39867
|
-
} : {}
|
|
39884
|
+
...warnings.length ? { warning: warnings.join(" ") } : {}
|
|
39868
39885
|
};
|
|
39869
39886
|
} catch (err) {
|
|
39870
39887
|
const detail = err instanceof Error ? err.message : String(err);
|
package/package.json
CHANGED