apple-notes-mcp 2.8.48 → 2.9.0

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/build/index.js CHANGED
@@ -2991,7 +2991,7 @@ var require_compile = __commonJS({
2991
2991
  const schOrFunc = root.refs[ref];
2992
2992
  if (schOrFunc)
2993
2993
  return schOrFunc;
2994
- let _sch = resolve5.call(this, root, ref);
2994
+ let _sch = resolve6.call(this, root, ref);
2995
2995
  if (_sch === void 0) {
2996
2996
  const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
2997
2997
  const { schemaId } = this.opts;
@@ -3018,7 +3018,7 @@ var require_compile = __commonJS({
3018
3018
  function sameSchemaEnv(s1, s2) {
3019
3019
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3020
3020
  }
3021
- function resolve5(root, ref) {
3021
+ function resolve6(root, ref) {
3022
3022
  let sch;
3023
3023
  while (typeof (sch = this.refs[ref]) == "string")
3024
3024
  ref = sch;
@@ -3843,7 +3843,7 @@ var require_fast_uri = __commonJS({
3843
3843
  }
3844
3844
  return uri;
3845
3845
  }
3846
- function resolve5(baseURI, relativeURI, options) {
3846
+ function resolve6(baseURI, relativeURI, options) {
3847
3847
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3848
3848
  const {
3849
3849
  parsed: baseParsed,
@@ -4205,7 +4205,7 @@ var require_fast_uri = __commonJS({
4205
4205
  var fastUri = {
4206
4206
  SCHEMES,
4207
4207
  normalize,
4208
- resolve: resolve5,
4208
+ resolve: resolve6,
4209
4209
  resolveComponent,
4210
4210
  equal,
4211
4211
  serialize,
@@ -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 join24(output, replacement);
24468
+ return join26(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 = join24(output, rule.append(self.options));
24475
+ output = join26(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 join24(output, replacement) {
24487
+ function join26(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);
@@ -36608,7 +36608,7 @@ var Protocol = class {
36608
36608
  return;
36609
36609
  }
36610
36610
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
36611
- await new Promise((resolve5) => setTimeout(resolve5, pollInterval));
36611
+ await new Promise((resolve6) => setTimeout(resolve6, pollInterval));
36612
36612
  options?.signal?.throwIfAborted();
36613
36613
  }
36614
36614
  } catch (error2) {
@@ -36625,7 +36625,7 @@ var Protocol = class {
36625
36625
  */
36626
36626
  request(request, resultSchema, options) {
36627
36627
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
36628
- return new Promise((resolve5, reject) => {
36628
+ return new Promise((resolve6, reject) => {
36629
36629
  const earlyReject = (error2) => {
36630
36630
  reject(error2);
36631
36631
  };
@@ -36703,7 +36703,7 @@ var Protocol = class {
36703
36703
  if (!parseResult.success) {
36704
36704
  reject(parseResult.error);
36705
36705
  } else {
36706
- resolve5(parseResult.data);
36706
+ resolve6(parseResult.data);
36707
36707
  }
36708
36708
  } catch (error2) {
36709
36709
  reject(error2);
@@ -36964,12 +36964,12 @@ var Protocol = class {
36964
36964
  }
36965
36965
  } catch {
36966
36966
  }
36967
- return new Promise((resolve5, reject) => {
36967
+ return new Promise((resolve6, reject) => {
36968
36968
  if (signal.aborted) {
36969
36969
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
36970
36970
  return;
36971
36971
  }
36972
- const timeoutId = setTimeout(resolve5, interval);
36972
+ const timeoutId = setTimeout(resolve6, interval);
36973
36973
  signal.addEventListener("abort", () => {
36974
36974
  clearTimeout(timeoutId);
36975
36975
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -38282,7 +38282,7 @@ var McpServer = class {
38282
38282
  let task = createTaskResult.task;
38283
38283
  const pollInterval = task.pollInterval ?? 5e3;
38284
38284
  while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
38285
- await new Promise((resolve5) => setTimeout(resolve5, pollInterval));
38285
+ await new Promise((resolve6) => setTimeout(resolve6, pollInterval));
38286
38286
  const updatedTask = await extra.taskStore.getTask(taskId);
38287
38287
  if (!updatedTask) {
38288
38288
  throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
@@ -38970,12 +38970,12 @@ var StdioServerTransport = class {
38970
38970
  this.onclose?.();
38971
38971
  }
38972
38972
  send(message) {
38973
- return new Promise((resolve5) => {
38973
+ return new Promise((resolve6) => {
38974
38974
  const json2 = serializeMessage(message);
38975
38975
  if (this._stdout.write(json2)) {
38976
- resolve5();
38976
+ resolve6();
38977
38977
  } else {
38978
- this._stdout.once("drain", resolve5);
38978
+ this._stdout.once("drain", resolve6);
38979
38979
  }
38980
38980
  });
38981
38981
  }
@@ -40820,13 +40820,13 @@ function buildSmartFolders(output) {
40820
40820
  if (lines.length < 4) throw new Error("Unexpected smart folder query output");
40821
40821
  const [storeUuid, rowsJson, foldersJson, tagsJson] = lines;
40822
40822
  if (!/^[0-9A-F-]+$/i.test(storeUuid)) throw new Error("Unexpected Notes store identifier");
40823
- const coreDataId2 = (entity3, pk) => `x-coredata://${storeUuid}/${entity3}/p${pk}`;
40823
+ const coreDataId3 = (entity3, pk) => `x-coredata://${storeUuid}/${entity3}/p${pk}`;
40824
40824
  const rows = JSON.parse(rowsJson);
40825
40825
  const folderRows = JSON.parse(foldersJson || "{}");
40826
40826
  const tagRows = JSON.parse(tagsJson || "[]");
40827
40827
  const folders = {};
40828
40828
  for (const [identifier, row] of Object.entries(folderRows)) {
40829
- folders[identifier] = { id: coreDataId2("ICFolder", row.pk), title: row.title };
40829
+ folders[identifier] = { id: coreDataId3("ICFolder", row.pk), title: row.title };
40830
40830
  }
40831
40831
  const tags = {};
40832
40832
  for (const tag of tagRows) {
@@ -40837,14 +40837,14 @@ function buildSmartFolders(output) {
40837
40837
  return rows.map((row) => {
40838
40838
  const decoded = decodeSmartFolderQuery(row.query, { folders, tags });
40839
40839
  return {
40840
- id: coreDataId2("ICFolder", row.pk),
40840
+ id: coreDataId3("ICFolder", row.pk),
40841
40841
  identifier: row.identifier,
40842
40842
  name: row.title,
40843
40843
  account: row.accountName,
40844
- accountId: row.accountPk === null ? null : coreDataId2("ICAccount", row.accountPk),
40844
+ accountId: row.accountPk === null ? null : coreDataId3("ICAccount", row.accountPk),
40845
40845
  accountIdentifier: row.accountIdentifier,
40846
40846
  parent: row.parentTitle,
40847
- parentId: row.parentPk === null ? null : coreDataId2("ICFolder", row.parentPk),
40847
+ parentId: row.parentPk === null ? null : coreDataId3("ICFolder", row.parentPk),
40848
40848
  parentIdentifier: row.parentIdentifier,
40849
40849
  match: decoded.match,
40850
40850
  filters: decoded.filters,
@@ -42453,8 +42453,8 @@ function folderDeleteFactsScript(id2) {
42453
42453
  end repeat
42454
42454
  set noteCount to count of notes of f`;
42455
42455
  }
42456
- function getNoteLinkFromDB(coreDataId2) {
42457
- const match = coreDataId2.match(/\/p(\d+)$/);
42456
+ function getNoteLinkFromDB(coreDataId3) {
42457
+ const match = coreDataId3.match(/\/p(\d+)$/);
42458
42458
  if (!match) return null;
42459
42459
  const pk = parseInt(match[1], 10);
42460
42460
  const dbPath2 = join9(homedir8(), "Library/Group Containers/group.com.apple.notes/NoteStore.sqlite");
@@ -43035,29 +43035,26 @@ var AppleNotesManager = class {
43035
43035
  try
43036
43036
  set originalFolder to container of noteRef
43037
43037
  end try
43038
- if originalFolder is not missing value then
43039
- set __inTrash to true
43040
- try
43041
- if (class of originalFolder) is folder then set __inTrash to false
43042
- end try
43043
- try
43044
- if ${trashFolderIdList()} contains (id of originalFolder) then set __inTrash to true
43045
- end try
43046
- try
43047
- if (name of originalFolder) is "${RECENTLY_DELETED_FOLDER_NAME}" then set __inTrash to true
43048
- end try
43049
- if __inTrash then return "SAFETY_IN_RECENTLY_DELETED"
43050
- end if
43038
+ if originalFolder is missing value then return "SAFETY_CONTAINER_UNKNOWN"
43039
+ set __inTrash to true
43040
+ try
43041
+ if (class of originalFolder) is folder then set __inTrash to false
43042
+ end try
43043
+ try
43044
+ if ${trashFolderIdList()} contains (id of originalFolder) then set __inTrash to true
43045
+ end try
43046
+ try
43047
+ if (name of originalFolder) is "${RECENTLY_DELETED_FOLDER_NAME}" then set __inTrash to true
43048
+ end try
43049
+ if __inTrash then return "SAFETY_IN_RECENTLY_DELETED"
43051
43050
  set currentBody to body of noteRef
43052
43051
  considering case
43053
43052
  if currentBody is not "${safeExpectedBody}" and currentBody is not "${safeExpectedBody}" & linefeed then return "SAFETY_CONFLICT"
43054
43053
  delete noteRef
43055
43054
  end considering
43056
- if originalFolder is not missing value then
43057
- try
43058
- if (id of notes of originalFolder) contains "${safeId}" then return "SAFETY_NOT_DELETED"
43059
- end try
43060
- end if
43055
+ try
43056
+ if (id of notes of originalFolder) contains "${safeId}" then return "SAFETY_NOT_DELETED"
43057
+ end try
43061
43058
  return "SAFETY_DELETED"
43062
43059
  `);
43063
43060
  const result = executeMutationAppleScript(script);
@@ -43070,6 +43067,7 @@ var AppleNotesManager = class {
43070
43067
  const status = result.output.trim();
43071
43068
  if (status === "SAFETY_CONFLICT") return { status: "conflict" };
43072
43069
  if (status === "SAFETY_IN_RECENTLY_DELETED") return { status: "in-recently-deleted" };
43070
+ if (status === "SAFETY_CONTAINER_UNKNOWN") return { status: "container-unknown" };
43073
43071
  if (status === "SAFETY_NOT_DELETED") return { status: "not-deleted" };
43074
43072
  return status === "SAFETY_DELETED" ? { status: "deleted" } : { status: "failed" };
43075
43073
  }
@@ -46602,13 +46600,13 @@ var escapeSegment = escapeFolderName;
46602
46600
  function resolveFolders(rows) {
46603
46601
  const byPk = new Map(rows.map((row) => [row.pk, row]));
46604
46602
  const resolved = /* @__PURE__ */ new Map();
46605
- const resolve5 = (pk, seen) => {
46603
+ const resolve6 = (pk, seen) => {
46606
46604
  const cached2 = resolved.get(pk);
46607
46605
  if (cached2) return cached2;
46608
46606
  const row = byPk.get(pk);
46609
46607
  if (!row || seen.has(pk)) return void 0;
46610
46608
  seen.add(pk);
46611
- const parent = row.parent !== null ? resolve5(row.parent, seen) : void 0;
46609
+ const parent = row.parent !== null ? resolve6(row.parent, seen) : void 0;
46612
46610
  const name = row.name ?? "";
46613
46611
  const path10 = parent ? `${parent.path}/${escapeSegment(name)}` : escapeSegment(name);
46614
46612
  const plainPath = parent ? `${parent.plainPath}/${name}` : name;
@@ -46622,7 +46620,7 @@ function resolveFolders(rows) {
46622
46620
  resolved.set(pk, info);
46623
46621
  return info;
46624
46622
  };
46625
- for (const row of rows) resolve5(row.pk, /* @__PURE__ */ new Set());
46623
+ for (const row of rows) resolve6(row.pk, /* @__PURE__ */ new Set());
46626
46624
  return resolved;
46627
46625
  }
46628
46626
  var coreDataMs = (seconds) => seconds === null || !Number.isFinite(seconds) ? void 0 : CORE_DATA_EPOCH_MS2 + seconds * 1e3;
@@ -47744,35 +47742,37 @@ var FEATURES = [
47744
47742
  { kind: "shortcut", name: markdownShortcutName }
47745
47743
  ]
47746
47744
  },
47747
- // Placeholders for features that need a native helper this server does not
47748
- // ship. They always report `not_implemented` so clients can detect them.
47745
+ // Placeholders for features that need a native WRITE helper, which this
47746
+ // server does not ship. The opt-in private helper is read-only (write
47747
+ // support was deliberately deferred), so enabling or installing it changes
47748
+ // nothing here: these always report `not_implemented`.
47749
47749
  {
47750
47750
  name: "checklistToggle",
47751
47751
  description: "Check or uncheck an existing checklist item in place",
47752
47752
  tools: [],
47753
47753
  minimumMacOSVersion: null,
47754
- requirements: [{ kind: "native_helper" }]
47754
+ requirements: [{ kind: "native_write_helper" }]
47755
47755
  },
47756
47756
  {
47757
47757
  name: "smartFolders",
47758
47758
  description: "Create or edit Smart Folders and their tag rules",
47759
47759
  tools: [],
47760
47760
  minimumMacOSVersion: null,
47761
- requirements: [{ kind: "native_helper" }]
47761
+ requirements: [{ kind: "native_write_helper" }]
47762
47762
  },
47763
47763
  {
47764
47764
  name: "paragraphLinks",
47765
47765
  description: "Link to a specific paragraph or heading inside a note",
47766
47766
  tools: [],
47767
47767
  minimumMacOSVersion: null,
47768
- requirements: [{ kind: "native_helper" }]
47768
+ requirements: [{ kind: "native_write_helper" }]
47769
47769
  },
47770
47770
  {
47771
47771
  name: "audioTranscription",
47772
47772
  description: "Transcribe audio recordings attached to a note",
47773
47773
  tools: [],
47774
47774
  minimumMacOSVersion: null,
47775
- requirements: [{ kind: "native_helper" }]
47775
+ requirements: [{ kind: "native_write_helper" }]
47776
47776
  }
47777
47777
  ];
47778
47778
  function requirementLabel(requirement) {
@@ -47820,7 +47820,7 @@ function evaluateFeature(feature, env) {
47820
47820
  failures.add("shortcut_not_installed");
47821
47821
  }
47822
47822
  break;
47823
- case "native_helper":
47823
+ case "native_write_helper":
47824
47824
  missing.push(label);
47825
47825
  failures.add("not_implemented");
47826
47826
  break;
@@ -51427,10 +51427,653 @@ function formatShortcutSetup(report) {
51427
51427
  return lines.join("\n");
51428
51428
  }
51429
51429
 
51430
+ // src/services/privateHelperBuild.ts
51431
+ import { spawnSync as spawnSync4 } from "node:child_process";
51432
+ import {
51433
+ chmodSync,
51434
+ existsSync as existsSync15,
51435
+ mkdirSync as mkdirSync6,
51436
+ mkdtempSync as mkdtempSync5,
51437
+ renameSync,
51438
+ rmSync as rmSync5,
51439
+ writeFileSync as writeFileSync4
51440
+ } from "node:fs";
51441
+ import { release as release3 } from "node:os";
51442
+ import { join as join25 } from "node:path";
51443
+
51444
+ // src/services/privateHelper.ts
51445
+ import { spawnSync as spawnSync3 } from "node:child_process";
51446
+ import { createHash as createHash4 } from "node:crypto";
51447
+ import { existsSync as existsSync14, readFileSync as readFileSync4 } from "node:fs";
51448
+ import { homedir as homedir19 } from "node:os";
51449
+ import { dirname as dirname6, join as join24, resolve as resolve5 } from "node:path";
51450
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
51451
+ var PRIVATE_HELPER_PROTOCOL = 1;
51452
+ var ENABLE_ENV = "APPLE_NOTES_MCP_ENABLE_PRIVATE";
51453
+ var HELPER_DIR_ENV = "APPLE_NOTES_MCP_PRIVATE_HELPER_DIR";
51454
+ var TIMEOUT_ENV = "APPLE_NOTES_MCP_PRIVATE_HELPER_TIMEOUT_MS";
51455
+ var READ_ONLY_ACTIONS = /* @__PURE__ */ new Set([
51456
+ "hello",
51457
+ "probe",
51458
+ "read_note_state"
51459
+ ]);
51460
+ var HELPER_BINARY_NAME = "apple-notes-private-helper";
51461
+ var HELPER_SOURCE_RELATIVE = "native/private-helper/apple-notes-private-helper.m";
51462
+ var MANIFEST_NAME = "manifest.json";
51463
+ var DEFAULT_TIMEOUT_MS2 = 2e4;
51464
+ var MAX_OUTPUT_BYTES = 4 * 1024 * 1024;
51465
+ var manifestSchema = external_exports.object({
51466
+ schemaVersion: external_exports.literal(1),
51467
+ protocolVersion: external_exports.number().int(),
51468
+ sourceSha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
51469
+ binarySha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
51470
+ builtAt: external_exports.string(),
51471
+ osVersion: external_exports.string(),
51472
+ compiler: external_exports.string()
51473
+ });
51474
+ function packageRoot(fromDir = dirname6(fileURLToPath2(import.meta.url))) {
51475
+ let dir = fromDir;
51476
+ for (; ; ) {
51477
+ const candidate = join24(dir, "package.json");
51478
+ if (existsSync14(candidate)) {
51479
+ try {
51480
+ const pkg = JSON.parse(readFileSync4(candidate, "utf8"));
51481
+ if (pkg.name === "apple-notes-mcp") return dir;
51482
+ } catch {
51483
+ }
51484
+ }
51485
+ const parent = dirname6(dir);
51486
+ if (parent === dir) return resolve5(fromDir, "..");
51487
+ dir = parent;
51488
+ }
51489
+ }
51490
+ function defaultDeps2(overrides = {}) {
51491
+ return {
51492
+ env: process.env,
51493
+ platform: process.platform,
51494
+ sourcePath: join24(packageRoot(), HELPER_SOURCE_RELATIVE),
51495
+ exists: existsSync14,
51496
+ readFile: (path10) => readFileSync4(path10),
51497
+ spawn: spawnSync3,
51498
+ ...overrides
51499
+ };
51500
+ }
51501
+ function privateHelperEnabled(env = process.env) {
51502
+ return env[ENABLE_ENV] === "1";
51503
+ }
51504
+ function helperInstallDir(env = process.env) {
51505
+ const override = env[HELPER_DIR_ENV]?.trim();
51506
+ if (override) return override;
51507
+ return join24(homedir19(), "Library", "Application Support", "apple-notes-mcp", "private-helper");
51508
+ }
51509
+ function sha256Hex(data) {
51510
+ return createHash4("sha256").update(data).digest("hex");
51511
+ }
51512
+ function inspectInstallation(deps = defaultDeps2()) {
51513
+ const installDir = helperInstallDir(deps.env);
51514
+ const binaryPath = join24(installDir, HELPER_BINARY_NAME);
51515
+ const base = {
51516
+ installDir,
51517
+ binaryPath,
51518
+ sourcePath: deps.sourcePath,
51519
+ expectedSourceSha256: null,
51520
+ manifest: null
51521
+ };
51522
+ const fail = (reason, detail) => ({
51523
+ ...base,
51524
+ ready: false,
51525
+ reason,
51526
+ detail
51527
+ });
51528
+ if (deps.platform !== "darwin") return fail("unsupported_platform", "macOS only");
51529
+ if (!deps.exists(deps.sourcePath))
51530
+ return fail("helper_not_installed", `Packaged helper source is missing: ${deps.sourcePath}`);
51531
+ base.expectedSourceSha256 = sha256Hex(deps.readFile(deps.sourcePath));
51532
+ const manifestPath = join24(installDir, MANIFEST_NAME);
51533
+ if (!deps.exists(binaryPath) || !deps.exists(manifestPath))
51534
+ return fail(
51535
+ "helper_not_installed",
51536
+ "The private helper is not built. Run `apple-notes-mcp setup --native-helper`."
51537
+ );
51538
+ let manifest;
51539
+ try {
51540
+ manifest = manifestSchema.parse(JSON.parse(deps.readFile(manifestPath).toString("utf8")));
51541
+ } catch (error2) {
51542
+ return fail(
51543
+ "helper_manifest_invalid",
51544
+ `Unreadable helper manifest (${error2 instanceof Error ? error2.message : String(error2)}). Run \`apple-notes-mcp setup --native-helper\`.`
51545
+ );
51546
+ }
51547
+ base.manifest = manifest;
51548
+ if (manifest.sourceSha256 !== base.expectedSourceSha256 || manifest.protocolVersion !== PRIVATE_HELPER_PROTOCOL)
51549
+ return fail(
51550
+ "helper_stale",
51551
+ "The installed helper was built from a different helper source or protocol than this apple-notes-mcp version ships. Run `apple-notes-mcp setup --native-helper` again."
51552
+ );
51553
+ if (sha256Hex(deps.readFile(binaryPath)) !== manifest.binarySha256)
51554
+ return fail(
51555
+ "helper_modified",
51556
+ "The helper binary does not match the checksum recorded when it was built. Run `apple-notes-mcp setup --native-helper` to rebuild it."
51557
+ );
51558
+ return { ...base, ready: true, reason: null, detail: null };
51559
+ }
51560
+ var PrivateHelperError = class extends Error {
51561
+ constructor(code, message, details = {}) {
51562
+ super(message);
51563
+ this.code = code;
51564
+ this.details = details;
51565
+ this.name = "PrivateHelperError";
51566
+ }
51567
+ code;
51568
+ details;
51569
+ };
51570
+ var errorSchema = external_exports.object({
51571
+ status: external_exports.literal("error"),
51572
+ code: external_exports.string(),
51573
+ message: external_exports.string()
51574
+ }).passthrough();
51575
+ var featureSchema = external_exports.object({
51576
+ available: external_exports.boolean(),
51577
+ reason: external_exports.string().nullable(),
51578
+ missing: external_exports.array(external_exports.string())
51579
+ });
51580
+ var helloSchema = external_exports.object({
51581
+ status: external_exports.literal("ok"),
51582
+ protocolVersion: external_exports.number().int(),
51583
+ sourceSha256: external_exports.string(),
51584
+ readOnly: external_exports.literal(true),
51585
+ actions: external_exports.array(external_exports.string())
51586
+ }).passthrough();
51587
+ var probeSchema = external_exports.object({
51588
+ status: external_exports.literal("ok"),
51589
+ protocolVersion: external_exports.number().int(),
51590
+ readOnly: external_exports.literal(true),
51591
+ os: external_exports.object({ version: external_exports.string(), notesAppVersion: external_exports.string().nullable() }).passthrough(),
51592
+ framework: external_exports.object({ loaded: external_exports.boolean(), error: external_exports.string().nullable() }).passthrough(),
51593
+ store: external_exports.object({
51594
+ kind: external_exports.enum(["live", "copy"]).nullable(),
51595
+ opened: external_exports.boolean(),
51596
+ reason: external_exports.string().nullable(),
51597
+ noteRows: external_exports.number().int().nullable()
51598
+ }).passthrough(),
51599
+ syncHostRunning: external_exports.boolean(),
51600
+ features: external_exports.object({ readNoteState: featureSchema }).passthrough()
51601
+ }).passthrough();
51602
+ var cloudSyncSchema = external_exports.object({
51603
+ available: external_exports.boolean(),
51604
+ inICloudAccount: external_exports.boolean(),
51605
+ currentLocalVersion: external_exports.number().int().optional(),
51606
+ latestVersionSyncedToCloud: external_exports.number().int().optional(),
51607
+ uploadPending: external_exports.boolean().optional()
51608
+ }).passthrough();
51609
+ var noteStateSchema = external_exports.object({
51610
+ status: external_exports.literal("ok"),
51611
+ identifier: external_exports.string(),
51612
+ objectURI: external_exports.string(),
51613
+ title: external_exports.string().nullable(),
51614
+ modificationDate: external_exports.string().nullable(),
51615
+ folderIdentifier: external_exports.string().nullable(),
51616
+ passwordProtected: external_exports.boolean(),
51617
+ deletedOrInTrash: external_exports.boolean(),
51618
+ sharedViaICloud: external_exports.boolean(),
51619
+ editable: external_exports.boolean(),
51620
+ revision: external_exports.string().regex(/^r1:[a-f0-9]{64}$/),
51621
+ cloudSync: cloudSyncSchema,
51622
+ syncHostRunning: external_exports.boolean()
51623
+ }).passthrough();
51624
+ function callPrivateHelper(action, fields = {}, deps = defaultDeps2(), options = {}) {
51625
+ if (!READ_ONLY_ACTIONS.has(action))
51626
+ throw new PrivateHelperError(
51627
+ "unknown_action",
51628
+ `The private helper is read-only; "${action}" is not a supported action.`
51629
+ );
51630
+ if (!options.allowDisabled && !privateHelperEnabled(deps.env))
51631
+ throw new PrivateHelperError(
51632
+ "disabled",
51633
+ `The private helper is off. Set ${ENABLE_ENV}=1 to opt in.`
51634
+ );
51635
+ let binaryPath = options.binaryPath;
51636
+ if (!binaryPath) {
51637
+ const install = inspectInstallation(deps);
51638
+ if (!install.ready)
51639
+ throw new PrivateHelperError(install.reason || "helper_not_installed", install.detail || "");
51640
+ binaryPath = install.binaryPath;
51641
+ }
51642
+ const timeout = Number.parseInt(deps.env[TIMEOUT_ENV] || "", 10) || DEFAULT_TIMEOUT_MS2;
51643
+ const result = deps.spawn(binaryPath, [], {
51644
+ input: JSON.stringify({ protocol: PRIVATE_HELPER_PROTOCOL, action, ...fields }),
51645
+ encoding: "utf8",
51646
+ timeout,
51647
+ killSignal: "SIGKILL",
51648
+ maxBuffer: MAX_OUTPUT_BYTES,
51649
+ env: deps.env
51650
+ });
51651
+ const errno = result.error?.code;
51652
+ if (errno === "ETIMEDOUT" || result.signal && result.status === null)
51653
+ throw new PrivateHelperError("timeout", `The helper did not answer within ${timeout} ms.`);
51654
+ if (result.error)
51655
+ throw new PrivateHelperError(
51656
+ "helper_unreachable",
51657
+ `Could not run the helper: ${result.error.message}`
51658
+ );
51659
+ const stdout = String(result.stdout ?? "").trim();
51660
+ let parsed;
51661
+ try {
51662
+ parsed = JSON.parse(stdout);
51663
+ } catch {
51664
+ throw new PrivateHelperError(
51665
+ "invalid_response",
51666
+ `The helper exited with status ${result.status} and no JSON response.`
51667
+ );
51668
+ }
51669
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
51670
+ throw new PrivateHelperError("invalid_response", "The helper response is not a JSON object");
51671
+ const object3 = parsed;
51672
+ if (result.status !== 0 || object3.status === "error") {
51673
+ const error2 = errorSchema.safeParse(object3);
51674
+ if (!error2.success)
51675
+ throw new PrivateHelperError(
51676
+ "invalid_response",
51677
+ `The helper failed with an unrecognized error shape (exit ${result.status})`
51678
+ );
51679
+ const { status: _status, code, message, ...details } = error2.data;
51680
+ void _status;
51681
+ throw new PrivateHelperError(code, message, details);
51682
+ }
51683
+ return object3;
51684
+ }
51685
+ function parseOrThrow(schema, value) {
51686
+ const parsed = schema.safeParse(value);
51687
+ if (!parsed.success)
51688
+ throw new PrivateHelperError(
51689
+ "invalid_response",
51690
+ `Unexpected helper response: ${parsed.error.issues.map((i) => i.path.join(".") + " " + i.message).join("; ")}`
51691
+ );
51692
+ return parsed.data;
51693
+ }
51694
+ var UUID = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i;
51695
+ function assertNoteIdentifier(identifier) {
51696
+ if (!UUID.test(identifier))
51697
+ throw new PrivateHelperError("invalid_request", "identifier must be a Notes UUID");
51698
+ }
51699
+ function probePrivateHelper(deps = defaultDeps2()) {
51700
+ return parseOrThrow(probeSchema, callPrivateHelper("probe", {}, deps));
51701
+ }
51702
+ function readNoteState(identifier, deps = defaultDeps2()) {
51703
+ assertNoteIdentifier(identifier);
51704
+ return parseOrThrow(noteStateSchema, callPrivateHelper("read_note_state", { identifier }, deps));
51705
+ }
51706
+ function featureFromProbe(feature) {
51707
+ if (!feature) return { available: false, reason: "private_api_unavailable", detail: null };
51708
+ if (feature.available) return { available: true, reason: null, detail: null };
51709
+ const reason = feature.reason === "store_unavailable" || feature.reason === "disabled" ? feature.reason : "private_api_unavailable";
51710
+ return {
51711
+ available: false,
51712
+ reason,
51713
+ detail: feature.missing.length ? `missing: ${feature.missing.join(", ")}` : feature.reason
51714
+ };
51715
+ }
51716
+ function privateHelperCapabilities(deps = defaultDeps2()) {
51717
+ const enabled = privateHelperEnabled(deps.env);
51718
+ const installation = inspectInstallation(deps);
51719
+ const off = (reason, detail) => ({
51720
+ available: false,
51721
+ reason,
51722
+ detail
51723
+ });
51724
+ const both = (status) => ({ readNoteState: status });
51725
+ if (installation.reason === "unsupported_platform")
51726
+ return {
51727
+ enabled,
51728
+ readOnly: true,
51729
+ installation,
51730
+ probe: null,
51731
+ features: both(off("unsupported_platform", null))
51732
+ };
51733
+ if (!enabled)
51734
+ return {
51735
+ enabled,
51736
+ readOnly: true,
51737
+ installation,
51738
+ probe: null,
51739
+ features: both(off("disabled", `Set ${ENABLE_ENV}=1 to opt in to the private helper.`))
51740
+ };
51741
+ if (!installation.ready)
51742
+ return {
51743
+ enabled,
51744
+ readOnly: true,
51745
+ installation,
51746
+ probe: null,
51747
+ features: both(off(installation.reason || "helper_not_installed", installation.detail))
51748
+ };
51749
+ let probe;
51750
+ try {
51751
+ probe = probePrivateHelper(deps);
51752
+ } catch (error2) {
51753
+ const detail = error2 instanceof Error ? error2.message : String(error2);
51754
+ return {
51755
+ enabled,
51756
+ readOnly: true,
51757
+ installation,
51758
+ probe: null,
51759
+ features: both(off("helper_unreachable", detail))
51760
+ };
51761
+ }
51762
+ return {
51763
+ enabled,
51764
+ readOnly: true,
51765
+ installation,
51766
+ probe,
51767
+ features: { readNoteState: featureFromProbe(probe.features.readNoteState) }
51768
+ };
51769
+ }
51770
+
51771
+ // src/services/privateHelperBuild.ts
51772
+ function defaultBuildDeps() {
51773
+ return {
51774
+ ...defaultDeps2(),
51775
+ osVersion: () => {
51776
+ const r = spawnSync4("/usr/bin/sw_vers", ["-productVersion"], { encoding: "utf8" });
51777
+ return r.status === 0 ? r.stdout.trim() : `Darwin ${release3()}`;
51778
+ },
51779
+ now: () => /* @__PURE__ */ new Date()
51780
+ };
51781
+ }
51782
+ function compileArguments(sourcePath, outputPath, sourceSha) {
51783
+ return [
51784
+ "clang",
51785
+ "-fobjc-arc",
51786
+ "-O2",
51787
+ "-Wall",
51788
+ "-framework",
51789
+ "Foundation",
51790
+ "-framework",
51791
+ "CoreData",
51792
+ "-framework",
51793
+ "AppKit",
51794
+ // Embedded so `hello` can prove which source the binary came from.
51795
+ `-DHELPER_SOURCE_SHA256="${sourceSha}"`,
51796
+ "-o",
51797
+ outputPath,
51798
+ sourcePath
51799
+ ];
51800
+ }
51801
+ function buildPrivateHelper(checkOnly, deps = defaultBuildDeps()) {
51802
+ const steps = [];
51803
+ const done = (ok) => ({
51804
+ ok,
51805
+ checkOnly,
51806
+ steps,
51807
+ installation: inspectInstallation(deps)
51808
+ });
51809
+ if (checkOnly) {
51810
+ const installation2 = inspectInstallation(deps);
51811
+ steps.push({
51812
+ step: "inspect installed helper",
51813
+ ok: installation2.ready,
51814
+ detail: installation2.ready ? installation2.binaryPath : installation2.detail || void 0
51815
+ });
51816
+ return { ok: installation2.ready, checkOnly, steps, installation: installation2 };
51817
+ }
51818
+ if (deps.platform !== "darwin") {
51819
+ steps.push({ step: "platform", ok: false, detail: "macOS only" });
51820
+ return done(false);
51821
+ }
51822
+ if (!deps.exists(deps.sourcePath)) {
51823
+ steps.push({ step: "locate source", ok: false, detail: deps.sourcePath });
51824
+ return done(false);
51825
+ }
51826
+ const source = deps.readFile(deps.sourcePath);
51827
+ const sourceSha = sha256Hex(source);
51828
+ steps.push({
51829
+ step: "locate source",
51830
+ ok: true,
51831
+ detail: `${deps.sourcePath} (sha256 ${sourceSha})`
51832
+ });
51833
+ const clang = deps.spawn("/usr/bin/xcrun", ["--find", "clang"], { encoding: "utf8" });
51834
+ if (clang.status !== 0) {
51835
+ steps.push({
51836
+ step: "find compiler",
51837
+ ok: false,
51838
+ detail: "No clang found. Install the Command Line Tools with `xcode-select --install`."
51839
+ });
51840
+ return done(false);
51841
+ }
51842
+ const clangVersion = deps.spawn("/usr/bin/xcrun", ["clang", "--version"], { encoding: "utf8" });
51843
+ const compiler = String(clangVersion.stdout || "").split("\n")[0] || "clang";
51844
+ steps.push({ step: "find compiler", ok: true, detail: compiler });
51845
+ const installDir = helperInstallDir(deps.env);
51846
+ mkdirSync6(installDir, { recursive: true, mode: 448 });
51847
+ const staging = mkdtempSync5(join25(installDir, ".staging-"));
51848
+ try {
51849
+ const stagedBinary = join25(staging, HELPER_BINARY_NAME);
51850
+ const compile = deps.spawn(
51851
+ "/usr/bin/xcrun",
51852
+ compileArguments(deps.sourcePath, stagedBinary, sourceSha),
51853
+ {
51854
+ encoding: "utf8",
51855
+ timeout: 18e4
51856
+ }
51857
+ );
51858
+ if (compile.status !== 0) {
51859
+ steps.push({
51860
+ step: "compile",
51861
+ ok: false,
51862
+ detail: String(compile.stderr || compile.error?.message || "clang failed").slice(0, 4e3)
51863
+ });
51864
+ return done(false);
51865
+ }
51866
+ steps.push({ step: "compile", ok: true });
51867
+ const sign = deps.spawn(
51868
+ "/usr/bin/codesign",
51869
+ ["--force", "--sign", "-", "--identifier", "apple-notes-mcp.private-helper", stagedBinary],
51870
+ { encoding: "utf8" }
51871
+ );
51872
+ if (sign.status !== 0) {
51873
+ steps.push({
51874
+ step: "ad-hoc sign",
51875
+ ok: false,
51876
+ detail: String(sign.stderr || "codesign failed")
51877
+ });
51878
+ return done(false);
51879
+ }
51880
+ steps.push({ step: "ad-hoc sign", ok: true });
51881
+ let hello;
51882
+ try {
51883
+ hello = helloSchema.parse(
51884
+ callPrivateHelper("hello", {}, deps, { allowDisabled: true, binaryPath: stagedBinary })
51885
+ );
51886
+ } catch (error2) {
51887
+ steps.push({
51888
+ step: "handshake",
51889
+ ok: false,
51890
+ detail: error2 instanceof Error ? error2.message : String(error2)
51891
+ });
51892
+ return done(false);
51893
+ }
51894
+ if (hello.protocolVersion !== PRIVATE_HELPER_PROTOCOL || hello.sourceSha256 !== sourceSha) {
51895
+ steps.push({
51896
+ step: "handshake",
51897
+ ok: false,
51898
+ detail: `helper reported protocol ${hello.protocolVersion}, source ${hello.sourceSha256}`
51899
+ });
51900
+ return done(false);
51901
+ }
51902
+ const writeActions = hello.actions.filter((action) => !READ_ONLY_ACTIONS.has(action));
51903
+ if (writeActions.length) {
51904
+ steps.push({
51905
+ step: "handshake",
51906
+ ok: false,
51907
+ detail: `helper offers non-read-only actions (${writeActions.join(", ")}); refusing to install`
51908
+ });
51909
+ return done(false);
51910
+ }
51911
+ steps.push({
51912
+ step: "handshake",
51913
+ ok: true,
51914
+ detail: `protocol ${hello.protocolVersion}, read-only`
51915
+ });
51916
+ const manifest = {
51917
+ schemaVersion: 1,
51918
+ protocolVersion: hello.protocolVersion,
51919
+ sourceSha256: sourceSha,
51920
+ binarySha256: sha256Hex(deps.readFile(stagedBinary)),
51921
+ builtAt: deps.now().toISOString(),
51922
+ osVersion: deps.osVersion(),
51923
+ compiler
51924
+ };
51925
+ chmodSync(stagedBinary, 448);
51926
+ renameSync(stagedBinary, join25(installDir, HELPER_BINARY_NAME));
51927
+ writeFileSync4(join25(installDir, MANIFEST_NAME), JSON.stringify(manifest, null, 2) + "\n", {
51928
+ mode: 384
51929
+ });
51930
+ steps.push({ step: "install", ok: true, detail: installDir });
51931
+ } finally {
51932
+ if (existsSync15(staging)) rmSync5(staging, { recursive: true, force: true });
51933
+ }
51934
+ const installation = inspectInstallation(deps);
51935
+ steps.push({
51936
+ step: "verify installation",
51937
+ ok: installation.ready,
51938
+ detail: installation.ready ? void 0 : installation.detail || void 0
51939
+ });
51940
+ return { ok: installation.ready, checkOnly, steps, installation };
51941
+ }
51942
+ function formatHelperBuild(report) {
51943
+ const lines = ["Apple Notes MCP private helper", ""];
51944
+ for (const step of report.steps)
51945
+ lines.push(`${step.ok ? "\u2713" : "\u2717"} ${step.step}${step.detail ? `: ${step.detail}` : ""}`);
51946
+ lines.push("");
51947
+ if (report.ok) {
51948
+ lines.push(`Installed at ${report.installation.binaryPath}.`);
51949
+ lines.push(
51950
+ "The helper stays off until you set APPLE_NOTES_MCP_ENABLE_PRIVATE=1 for the MCP server, and it needs the same Full Disk Access grant as the server's database reads."
51951
+ );
51952
+ } else if (report.checkOnly) {
51953
+ lines.push("Run `apple-notes-mcp setup --native-helper` to build it.");
51954
+ } else {
51955
+ lines.push("The helper was not installed. Fix the failed step above and run setup again.");
51956
+ }
51957
+ return lines.join("\n");
51958
+ }
51959
+
51960
+ // src/tools/privateHelperTools.ts
51961
+ var coreDataId2 = external_exports.string().regex(/^x-coredata:\/\/[0-9A-F-]+\/ICNote\/p\d+$/i);
51962
+ var notesUuid = external_exports.string().regex(UUID_PATTERN);
51963
+ function resolveIdentifier(manager, args) {
51964
+ if (args.identifier && args.id)
51965
+ throw new PrivateHelperError("invalid_request", "Pass identifier or id, not both");
51966
+ if (args.identifier) return args.identifier;
51967
+ if (!args.id) throw new PrivateHelperError("invalid_request", "identifier or id is required");
51968
+ const link = manager.getNoteLinkById(args.id);
51969
+ const match = link?.match(/identifier=([0-9A-F-]{36})$/i);
51970
+ if (!match)
51971
+ throw new PrivateHelperError(
51972
+ "not_found",
51973
+ "Could not resolve that id to a Notes UUID (needs Full Disk Access); pass identifier instead"
51974
+ );
51975
+ return match[1];
51976
+ }
51977
+ function envelopeCode(helperCode, message) {
51978
+ switch (helperCode) {
51979
+ case "not_found":
51980
+ return "not_found";
51981
+ case "timeout":
51982
+ return "timeout_indeterminate";
51983
+ case "invalid_request":
51984
+ case "invalid_json":
51985
+ case "input_too_large":
51986
+ case "unknown_action":
51987
+ return "validation_error";
51988
+ case "store_unavailable":
51989
+ return /Full Disk Access/i.test(message) ? "full_disk_access_missing" : "operation_failed";
51990
+ case "disabled":
51991
+ case "unsupported_platform":
51992
+ case "unsupported_note":
51993
+ case "private_api_unavailable":
51994
+ case "protocol_mismatch":
51995
+ case "helper_not_installed":
51996
+ case "helper_stale":
51997
+ case "helper_modified":
51998
+ case "helper_manifest_invalid":
51999
+ return "unsupported";
52000
+ default:
52001
+ return "operation_failed";
52002
+ }
52003
+ }
52004
+ function helperErrorResult(error2) {
52005
+ if (!(error2 instanceof PrivateHelperError)) {
52006
+ const message2 = error2 instanceof Error ? error2.message : String(error2);
52007
+ return errorResult(`native helper: ${message2}`, error2);
52008
+ }
52009
+ const message = `native helper (${error2.code}): ${error2.message}`;
52010
+ return errorResult(
52011
+ message,
52012
+ new CodedError(message, {
52013
+ ...error2.details,
52014
+ code: envelopeCode(error2.code, error2.message),
52015
+ helperCode: error2.code,
52016
+ committed: false
52017
+ })
52018
+ );
52019
+ }
52020
+ function registerPrivateHelperTools(server2, manager, depsFactory = () => defaultDeps2()) {
52021
+ function tool(name, description, inputSchema, annotations, handler) {
52022
+ server2.registerTool(
52023
+ name,
52024
+ {
52025
+ description,
52026
+ inputSchema,
52027
+ annotations,
52028
+ outputSchema: external_exports.object({ ok: external_exports.boolean().optional() }).passthrough()
52029
+ },
52030
+ (async (args) => {
52031
+ try {
52032
+ const result = { ok: true, ...handler(args, depsFactory()) };
52033
+ return {
52034
+ content: [{ type: "text", text: JSON.stringify(result) }],
52035
+ structuredContent: result
52036
+ };
52037
+ } catch (error2) {
52038
+ return helperErrorResult(error2);
52039
+ }
52040
+ })
52041
+ );
52042
+ }
52043
+ tool(
52044
+ "native-helper-status",
52045
+ "Use when: checking whether the opt-in, read-only native private helper is enabled, built, current, and working on this macOS before calling native-note-state.\nReturns: enabled flag, installation state (path, manifest, stale/modified checks), the live probe (macOS and Notes versions, framework, store access), and per-feature availability with a machine reason.\nDo not use when: checking the Shortcuts bridges (native-tags-status, get-capabilities).\nSafety: read-only. The helper is read-only by design (write support was deliberately deferred by the maintainer); the probe opens the Notes store read-only and only when the helper is enabled and installed.",
52046
+ {},
52047
+ { readOnlyHint: true, openWorldHint: false },
52048
+ (_args, deps) => {
52049
+ const capabilities = privateHelperCapabilities(deps);
52050
+ return {
52051
+ ...capabilities,
52052
+ ...capabilities.installation.ready ? {} : { setupCommand: "apple-notes-mcp setup --native-helper" }
52053
+ };
52054
+ }
52055
+ );
52056
+ tool(
52057
+ "native-note-state",
52058
+ "Use when: you need a note's native title, modification date, folder identifier, lock/trash/shared/editable flags, or iCloud upload state as Notes' own data model reports them.\nReturns: identifier, title, modificationDate, folderIdentifier, lock/trash/shared/editable flags, `revision` (an opaque change token; compare two reads to detect a change), and cloudSync versions.\nDo not use when: reading note content (get-note-content, get-note-markdown).\nSafety: read-only; the helper opens the store with Core Data's read-only option and has no write action. Requires APPLE_NOTES_MCP_ENABLE_PRIVATE=1 and a built helper.",
52059
+ {
52060
+ identifier: notesUuid.optional().describe("Notes UUID (the notes://showNote identifier)"),
52061
+ id: coreDataId2.optional().describe("x-coredata note id; resolved to a UUID via the database")
52062
+ },
52063
+ { readOnlyHint: true, openWorldHint: false },
52064
+ (args, deps) => ({ ...readNoteState(resolveIdentifier(manager, args), deps) })
52065
+ );
52066
+ }
52067
+
51430
52068
  // src/index.ts
51431
52069
  loadFileConfig();
51432
52070
  var require2 = createRequire(import.meta.url);
51433
52071
  var { version: version2 } = require2("../package.json");
52072
+ if (process.argv[2] === "setup" && process.argv.slice(3).includes("--native-helper")) {
52073
+ const report = buildPrivateHelper(process.argv.slice(3).includes("--check"));
52074
+ process.stdout.write(formatHelperBuild(report) + "\n");
52075
+ process.exit(report.ok ? 0 : 1);
52076
+ }
51434
52077
  if (process.argv[2] === "setup") {
51435
52078
  const report = setupShortcuts(process.argv.slice(3).includes("--check"));
51436
52079
  process.stdout.write(formatShortcutSetup(report) + "\n");
@@ -51446,6 +52089,7 @@ registerDirectOperations(server, notesManager);
51446
52089
  registerFolderDelete(server, notesManager);
51447
52090
  registerNativeTagsBridge(server, notesManager);
51448
52091
  registerNativeOperations(server, notesManager);
52092
+ registerPrivateHelperTools(server, notesManager);
51449
52093
  function successResponse(message, structured) {
51450
52094
  const res = { content: [{ type: "text", text: message }] };
51451
52095
  if (structured) res.structuredContent = structured;
@@ -51557,6 +52201,9 @@ function readExactNoteSnapshot(id2) {
51557
52201
  return { note, body, rich, contentHash: richContentHash(body, rich) };
51558
52202
  }
51559
52203
  var NOT_DELETED_MESSAGE = "Notes.app accepted the delete, but the note is still in its original folder, so it was not moved to Recently Deleted. Nothing was deleted; read the note again before retrying.";
52204
+ function containerUnknownMessage(title) {
52205
+ return `Could not read which folder note "${title}" is in, so it may already be in Recently Deleted, where deleting it would remove it permanently. Nothing was deleted. Retry in a moment; if it keeps failing, quit and reopen Notes.app, then retry.`;
52206
+ }
51560
52207
  function inRecentlyDeletedMessage(title) {
51561
52208
  return `Note "${title}" is already in Recently Deleted, where deleting it would remove it permanently. Nothing was deleted. Remove it from Recently Deleted in Notes.app if that is intended.`;
51562
52209
  }
@@ -52829,6 +53476,9 @@ registerTool(
52829
53476
  if (result.status === "in-recently-deleted") {
52830
53477
  return errorResponse(inRecentlyDeletedMessage(snapshot.note.title));
52831
53478
  }
53479
+ if (result.status === "container-unknown") {
53480
+ return errorResponse(containerUnknownMessage(snapshot.note.title));
53481
+ }
52832
53482
  if (result.status === "not-deleted") {
52833
53483
  return errorResponse(NOT_DELETED_MESSAGE);
52834
53484
  }
@@ -53509,6 +54159,9 @@ registerTool(
53509
54159
  if (result.status === "in-recently-deleted") {
53510
54160
  return { id: id2, success: false, error: inRecentlyDeletedMessage(snapshot.note.title) };
53511
54161
  }
54162
+ if (result.status === "container-unknown") {
54163
+ return { id: id2, success: false, error: containerUnknownMessage(snapshot.note.title) };
54164
+ }
53512
54165
  if (result.status === "not-deleted")
53513
54166
  return { id: id2, success: false, error: NOT_DELETED_MESSAGE };
53514
54167
  return { id: id2, success: false, error: "Delete result uncertain; inspect this exact ID" };