apple-notes-mcp 2.9.0 → 2.9.1
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 +16 -0
- package/build/index.js +209 -53
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -809,10 +809,26 @@ Deletes a note (moves to Recently Deleted in Notes.app).
|
|
|
809
809
|
| `id` | string | Yes | Exact CoreData note ID returned by a read or search |
|
|
810
810
|
| `expectedContentHash` | string | Yes | `contentHash` from the exact note version being deleted |
|
|
811
811
|
| `ifFolderId`, `ifAncestorFolderId`, `forbiddenAncestorFolderIds` | string, string, string[] | No | Folder preconditions; see [Folder scope guards](#folder-scope-guards) |
|
|
812
|
+
| `guardNoteId` | string | No | A second note (usually a verified copy) that must still be intact; needs Full Disk Access |
|
|
813
|
+
| `expectedGuardContentHash` | string | With `guardNoteId` | `contentHash` of the guard note from `get-note-content` |
|
|
814
|
+
| `requireActiveNoteId` | string | No | A second note that must still exist, be unlocked, stay outside Recently Deleted, and not be a Quick Note; its content is not fingerprinted. Needs Full Disk Access |
|
|
812
815
|
|
|
813
816
|
Title-only deletion is rejected. If the note changed after the supplied hash
|
|
814
817
|
was read, deletion is also rejected.
|
|
815
818
|
|
|
819
|
+
**Copy-then-retire.** To delete an original only while its copy is still good,
|
|
820
|
+
read both notes, verify the copy, and pass the copy as `guardNoteId` with its
|
|
821
|
+
`contentHash` as `expectedGuardContentHash`. The copy's revision is re-read just
|
|
822
|
+
before the delete, and its body, lock state, and folder are checked again
|
|
823
|
+
inside the delete AppleScript, with the same fail-closed Recently Deleted test
|
|
824
|
+
as the note being deleted. The guard note must not be a Quick Note, a flag only
|
|
825
|
+
the database holds, so the guard needs Full Disk Access. A copy the database
|
|
826
|
+
has not saved yet passes on the live checks alone. The pair is still not one
|
|
827
|
+
transaction: the rich revision (which also covers checklists and attachments)
|
|
828
|
+
is a pre-check, and the in-script check covers the body and state Notes.app
|
|
829
|
+
exposes. `requireActiveNoteId` is the narrower form for a destination you
|
|
830
|
+
wrote yourself rather than copied.
|
|
831
|
+
|
|
816
832
|
**Example - Using ID (recommended):**
|
|
817
833
|
```json
|
|
818
834
|
{
|
package/build/index.js
CHANGED
|
@@ -42140,6 +42140,19 @@ function trashFolderIdList() {
|
|
|
42140
42140
|
const ids = readTrashFolderIds().filter((id2) => FOLDER_ID_PATTERN.test(id2));
|
|
42141
42141
|
return `{${ids.map((id2) => `"${id2}"`).join(", ")}}`;
|
|
42142
42142
|
}
|
|
42143
|
+
function inRecentlyDeletedScript(containerVar, flagVar, trashIds) {
|
|
42144
|
+
return `
|
|
42145
|
+
set ${flagVar} to true
|
|
42146
|
+
try
|
|
42147
|
+
if (class of ${containerVar}) is folder then set ${flagVar} to false
|
|
42148
|
+
end try
|
|
42149
|
+
try
|
|
42150
|
+
if ${trashIds} contains (id of ${containerVar}) then set ${flagVar} to true
|
|
42151
|
+
end try
|
|
42152
|
+
try
|
|
42153
|
+
if (name of ${containerVar}) is "${RECENTLY_DELETED_FOLDER_NAME}" then set ${flagVar} to true
|
|
42154
|
+
end try`;
|
|
42155
|
+
}
|
|
42143
42156
|
function buildTrashNoteIdsCollector() {
|
|
42144
42157
|
return `
|
|
42145
42158
|
set __trashNoteIds to {}
|
|
@@ -43024,29 +43037,53 @@ var AppleNotesManager = class {
|
|
|
43024
43037
|
* Deletes one exact note only when its complete body still matches the body
|
|
43025
43038
|
* the caller reviewed. The comparison and delete are one AppleScript action,
|
|
43026
43039
|
* so a concurrent edit cannot slip between the guard and deletion.
|
|
43027
|
-
|
|
43028
|
-
|
|
43040
|
+
*
|
|
43041
|
+
* `guards` are other notes that must still be active when the delete runs
|
|
43042
|
+
* (the copy-then-retire guard of delete-note): each must exist, be unlocked,
|
|
43043
|
+
* and sit in a folder other than Recently Deleted, and one with
|
|
43044
|
+
* `expectedBody` must still have that body. They are checked in the same
|
|
43045
|
+
* script, just before the delete; `index` in a guard outcome points into
|
|
43046
|
+
* `guards`.
|
|
43047
|
+
*/
|
|
43048
|
+
deleteNoteByIdIfUnchanged(id2, expectedBody, scope2, guards = []) {
|
|
43029
43049
|
const safeId = sanitizeNoteId(id2);
|
|
43030
43050
|
validateLength(expectedBody, MAX_CONTENT_LENGTH, "Expected note content");
|
|
43031
43051
|
const safeExpectedBody = escapeHtmlForAppleScript(expectedBody);
|
|
43052
|
+
const trashIds = trashFolderIdList();
|
|
43053
|
+
const guardChecks = guards.map((guard, index) => {
|
|
43054
|
+
const safeGuardId = sanitizeNoteId(guard.id);
|
|
43055
|
+
const ref = `__guardRef${index}`;
|
|
43056
|
+
const folderVar = `__guardFolder${index}`;
|
|
43057
|
+
const inactive = (reason) => `return "SAFETY_GUARD_INACTIVE:${index}:${reason}"`;
|
|
43058
|
+
let bodyCheck = "";
|
|
43059
|
+
if (guard.expectedBody !== void 0) {
|
|
43060
|
+
validateLength(guard.expectedBody, MAX_CONTENT_LENGTH, "Expected guard note content");
|
|
43061
|
+
const safeGuardBody = escapeHtmlForAppleScript(guard.expectedBody);
|
|
43062
|
+
bodyCheck = `
|
|
43063
|
+
set __guardBody to body of ${ref}
|
|
43064
|
+
considering case
|
|
43065
|
+
if __guardBody is not "${safeGuardBody}" and __guardBody is not "${safeGuardBody}" & linefeed then return "SAFETY_GUARD_CONFLICT:${index}"
|
|
43066
|
+
end considering`;
|
|
43067
|
+
}
|
|
43068
|
+
return `
|
|
43069
|
+
if not (exists note id "${safeGuardId}") then ${inactive("missing")}
|
|
43070
|
+
set ${ref} to note id "${safeGuardId}"
|
|
43071
|
+
if password protected of ${ref} then ${inactive("locked")}
|
|
43072
|
+
set ${folderVar} to missing value
|
|
43073
|
+
try
|
|
43074
|
+
set ${folderVar} to container of ${ref}
|
|
43075
|
+
end try
|
|
43076
|
+
if ${folderVar} is missing value then ${inactive("folder unknown")}${inRecentlyDeletedScript(folderVar, "__guardInTrash", trashIds)}
|
|
43077
|
+
if __guardInTrash then ${inactive("in Recently Deleted")}${bodyCheck}`;
|
|
43078
|
+
}).join("");
|
|
43032
43079
|
const script = buildAppLevelScript(`
|
|
43033
43080
|
set noteRef to note id "${safeId}"${buildScopeGuardScript("noteRef", scope2)}
|
|
43034
43081
|
set originalFolder to missing value
|
|
43035
43082
|
try
|
|
43036
43083
|
set originalFolder to container of noteRef
|
|
43037
43084
|
end try
|
|
43038
|
-
if originalFolder is missing value then return "SAFETY_CONTAINER_UNKNOWN"
|
|
43039
|
-
|
|
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"
|
|
43085
|
+
if originalFolder is missing value then return "SAFETY_CONTAINER_UNKNOWN"${inRecentlyDeletedScript("originalFolder", "__inTrash", trashIds)}
|
|
43086
|
+
if __inTrash then return "SAFETY_IN_RECENTLY_DELETED"${guardChecks}
|
|
43050
43087
|
set currentBody to body of noteRef
|
|
43051
43088
|
considering case
|
|
43052
43089
|
if currentBody is not "${safeExpectedBody}" and currentBody is not "${safeExpectedBody}" & linefeed then return "SAFETY_CONFLICT"
|
|
@@ -43065,6 +43102,11 @@ var AppleNotesManager = class {
|
|
|
43065
43102
|
const deleteScopeFailure = parseScopeFailure(result.output);
|
|
43066
43103
|
if (deleteScopeFailure) return { status: "scope_conflict", reason: deleteScopeFailure };
|
|
43067
43104
|
const status = result.output.trim();
|
|
43105
|
+
const guardOutcome = /^SAFETY_GUARD_(CONFLICT|INACTIVE):(\d+)(?::(.+))?$/.exec(status);
|
|
43106
|
+
if (guardOutcome && Number(guardOutcome[2]) < guards.length) {
|
|
43107
|
+
const index = Number(guardOutcome[2]);
|
|
43108
|
+
return guardOutcome[1] === "CONFLICT" ? { status: "guard-conflict", index } : { status: "guard-inactive", index, reason: guardOutcome[3] ?? "inactive" };
|
|
43109
|
+
}
|
|
43068
43110
|
if (status === "SAFETY_CONFLICT") return { status: "conflict" };
|
|
43069
43111
|
if (status === "SAFETY_IN_RECENTLY_DELETED") return { status: "in-recently-deleted" };
|
|
43070
43112
|
if (status === "SAFETY_CONTAINER_UNKNOWN") return { status: "container-unknown" };
|
|
@@ -45568,6 +45610,23 @@ function toSpecialRow(row, uuid2, paths, accountNames, kind) {
|
|
|
45568
45610
|
if (kind === "locked" && row.hint) note.passwordHint = row.hint;
|
|
45569
45611
|
return note;
|
|
45570
45612
|
}
|
|
45613
|
+
var EXACT_NOTE_ID = /^x-coredata:\/\/([0-9A-F-]+)\/ICNote\/p(\d+)$/i;
|
|
45614
|
+
function quickNoteFlag(noteId3, dbPath2 = NOTES_DB_PATH7) {
|
|
45615
|
+
const match = EXACT_NOTE_ID.exec(noteId3);
|
|
45616
|
+
if (!match) throw new NoteStoreError(`Not an exact note id: ${noteId3}`, "invalid_input");
|
|
45617
|
+
const columns = readColumns(dbPath2);
|
|
45618
|
+
const sql = `SELECT json_object('uuid', (SELECT Z_UUID FROM Z_METADATA LIMIT 1), 'quick', (SELECT ${flag(columns, "n", "ZISSYSTEMPAPER")} FROM ZICCLOUDSYNCINGOBJECT n WHERE n.Z_PK = @pk AND n.Z_ENT = ${entity("ICNote")}));`;
|
|
45619
|
+
const [row] = parseJsonLines(
|
|
45620
|
+
runReadOnlySql(dbPath2, sql, { pk: { int: Number(match[2]) } })
|
|
45621
|
+
);
|
|
45622
|
+
if (row?.uuid?.toUpperCase() !== match[1].toUpperCase()) {
|
|
45623
|
+
throw new NoteStoreError(
|
|
45624
|
+
`Note id ${noteId3} belongs to a different Notes database.`,
|
|
45625
|
+
"invalid_input"
|
|
45626
|
+
);
|
|
45627
|
+
}
|
|
45628
|
+
return row.quick === null ? null : row.quick === 1;
|
|
45629
|
+
}
|
|
45571
45630
|
var TAG_REQUIRED = ["Z_PK", "Z_ENT", "ZFOLDER", "ZNOTE1", "ZTYPEUTI1", "ZALTTEXT", "ZIDENTIFIER"];
|
|
45572
45631
|
function buildTagInventorySql(columns, scoped) {
|
|
45573
45632
|
requireColumns(columns, TAG_REQUIRED, "list-native-tags");
|
|
@@ -52210,6 +52269,59 @@ function inRecentlyDeletedMessage(title) {
|
|
|
52210
52269
|
function revisionConflictMessage(title) {
|
|
52211
52270
|
return `Note "${title}" changed after it was read. Read it again and review the newer version before retrying.`;
|
|
52212
52271
|
}
|
|
52272
|
+
function quickNoteGuardRefusal(label, id2) {
|
|
52273
|
+
let quick;
|
|
52274
|
+
try {
|
|
52275
|
+
quick = quickNoteFlag(id2);
|
|
52276
|
+
} catch (error2) {
|
|
52277
|
+
const detail = error2 instanceof Error ? error2.message : String(error2);
|
|
52278
|
+
if (error2 instanceof NoteStoreError && error2.kind === "no_fda") {
|
|
52279
|
+
return `${label} note cannot be checked: the delete-note guard needs Full Disk Access to rule out a Quick Note. Nothing was deleted. ${detail}`;
|
|
52280
|
+
}
|
|
52281
|
+
return `${label} note could not be checked (${detail}). Nothing was deleted.`;
|
|
52282
|
+
}
|
|
52283
|
+
return quick ? `${label} note is a Quick Note; a guard must be an ordinary note. Nothing was deleted.` : null;
|
|
52284
|
+
}
|
|
52285
|
+
function prepareDeleteGuards(args) {
|
|
52286
|
+
const { id: id2, guardNoteId, expectedGuardContentHash, requireActiveNoteId } = args;
|
|
52287
|
+
if (guardNoteId === void 0 !== (expectedGuardContentHash === void 0)) {
|
|
52288
|
+
return { error: "Pass guardNoteId and expectedGuardContentHash together." };
|
|
52289
|
+
}
|
|
52290
|
+
if (guardNoteId === id2 || requireActiveNoteId === id2) {
|
|
52291
|
+
return { error: "A guard note must be a different note from the one being deleted." };
|
|
52292
|
+
}
|
|
52293
|
+
if (guardNoteId !== void 0 && guardNoteId === requireActiveNoteId) {
|
|
52294
|
+
return { error: "requireActiveNoteId repeats guardNoteId; pass only guardNoteId." };
|
|
52295
|
+
}
|
|
52296
|
+
const prepared = { guards: [], labels: [] };
|
|
52297
|
+
if (guardNoteId !== void 0) {
|
|
52298
|
+
const refusal = quickNoteGuardRefusal("Guard", guardNoteId);
|
|
52299
|
+
if (refusal) return { error: refusal };
|
|
52300
|
+
const guard = readExactNoteSnapshot(guardNoteId);
|
|
52301
|
+
if ("error" in guard) return { error: `Guard note: ${guard.error}` };
|
|
52302
|
+
if (guard.contentHash !== expectedGuardContentHash) {
|
|
52303
|
+
return {
|
|
52304
|
+
error: `Guard note "${guard.note.title}" changed after it was read. Verify the copy again before retiring the original. Nothing was deleted.`
|
|
52305
|
+
};
|
|
52306
|
+
}
|
|
52307
|
+
prepared.guards.push({ id: guardNoteId, expectedBody: guard.body });
|
|
52308
|
+
prepared.labels.push("Guard");
|
|
52309
|
+
prepared.guardContentHash = guard.contentHash;
|
|
52310
|
+
}
|
|
52311
|
+
if (requireActiveNoteId !== void 0) {
|
|
52312
|
+
const refusal = quickNoteGuardRefusal("Required active", requireActiveNoteId);
|
|
52313
|
+
if (refusal) return { error: refusal };
|
|
52314
|
+
const active = notesManager.getNoteById(requireActiveNoteId);
|
|
52315
|
+
if (!active)
|
|
52316
|
+
return { error: `Required active note with ID "${requireActiveNoteId}" not found.` };
|
|
52317
|
+
if (active.passwordProtected) {
|
|
52318
|
+
return { error: `Required active note "${active.title}" is password-protected.` };
|
|
52319
|
+
}
|
|
52320
|
+
prepared.guards.push({ id: requireActiveNoteId });
|
|
52321
|
+
prepared.labels.push("Required active");
|
|
52322
|
+
}
|
|
52323
|
+
return prepared;
|
|
52324
|
+
}
|
|
52213
52325
|
var folderNameSchema = {
|
|
52214
52326
|
name: external_exports.string().min(1, "Folder name is required").max(MAX.FOLDER),
|
|
52215
52327
|
account: external_exports.string().max(MAX.ACCOUNT).optional().describe(
|
|
@@ -53445,10 +53557,17 @@ registerTool(
|
|
|
53445
53557
|
registerTool(
|
|
53446
53558
|
"delete-note",
|
|
53447
53559
|
{
|
|
53448
|
-
description: "Use when: moving one exact note to Recently Deleted after reading and reviewing it.\nReturns: confirmation with the exact id.\nDo not use when: you only have a title or the note changed since review.\nSafety: requires id and expectedContentHash from get-note-content. The body comparison and delete happen in one AppleScript, so a newer edit is preserved. Refuses a note already in Recently Deleted, where a delete would be permanent. Optional ifFolderId, ifAncestorFolderId, and forbiddenAncestorFolderIds are re-checked inside that AppleScript too.",
|
|
53560
|
+
description: "Use when: moving one exact note to Recently Deleted after reading and reviewing it.\nReturns: confirmation with the exact id.\nDo not use when: you only have a title or the note changed since review.\nSafety: requires id and expectedContentHash from get-note-content. The body comparison and delete happen in one AppleScript, so a newer edit is preserved. Refuses a note already in Recently Deleted, where a delete would be permanent. Optional ifFolderId, ifAncestorFolderId, and forbiddenAncestorFolderIds are re-checked inside that AppleScript too. Copy-then-retire: pass guardNoteId and expectedGuardContentHash (the verified copy's contentHash) to delete only while the copy still has that revision, is unlocked, is outside Recently Deleted, and is not a Quick Note; requireActiveNoteId requires the same of a second note without fingerprinting it. The guard needs Full Disk Access to rule out a Quick Note. The copy's body, lock state, and folder are checked again inside the delete AppleScript, but the pair is not one transaction.",
|
|
53449
53561
|
inputSchema: {
|
|
53450
53562
|
id: noteIdInput,
|
|
53451
53563
|
expectedContentHash: expectedContentHashInput,
|
|
53564
|
+
guardNoteId: noteIdInput.optional().describe(
|
|
53565
|
+
"A second note (usually the verified copy) that must still match expectedGuardContentHash, be unlocked, stay outside Recently Deleted, and not be a Quick Note. Needs Full Disk Access"
|
|
53566
|
+
),
|
|
53567
|
+
expectedGuardContentHash: expectedContentHashInput.optional().describe("get-note-content contentHash of guardNoteId; required with guardNoteId"),
|
|
53568
|
+
requireActiveNoteId: noteIdInput.optional().describe(
|
|
53569
|
+
"A second note that must still exist, be unlocked, stay outside Recently Deleted, and not be a Quick Note. Its content is not fingerprinted. Needs Full Disk Access"
|
|
53570
|
+
),
|
|
53452
53571
|
timeoutSeconds: timeoutSecondsInput,
|
|
53453
53572
|
...scopeGuardInputs
|
|
53454
53573
|
},
|
|
@@ -53457,48 +53576,85 @@ registerTool(
|
|
|
53457
53576
|
id: external_exports.string().optional(),
|
|
53458
53577
|
title: external_exports.string().optional(),
|
|
53459
53578
|
wasShared: external_exports.boolean().optional(),
|
|
53460
|
-
previousContentHash: external_exports.string().optional()
|
|
53579
|
+
previousContentHash: external_exports.string().optional(),
|
|
53580
|
+
guardNoteId: external_exports.string().optional(),
|
|
53581
|
+
guardContentHash: external_exports.string().optional(),
|
|
53582
|
+
requireActiveNoteId: external_exports.string().optional()
|
|
53461
53583
|
}
|
|
53462
53584
|
},
|
|
53463
|
-
withErrorHandling(
|
|
53464
|
-
|
|
53465
|
-
|
|
53466
|
-
|
|
53467
|
-
|
|
53468
|
-
|
|
53469
|
-
|
|
53470
|
-
|
|
53471
|
-
|
|
53472
|
-
|
|
53473
|
-
if (result.status === "scope_conflict") {
|
|
53474
|
-
return errorResponse(scopeConflictMessage(result.reason));
|
|
53475
|
-
}
|
|
53476
|
-
if (result.status === "in-recently-deleted") {
|
|
53477
|
-
return errorResponse(inRecentlyDeletedMessage(snapshot.note.title));
|
|
53478
|
-
}
|
|
53479
|
-
if (result.status === "container-unknown") {
|
|
53480
|
-
return errorResponse(containerUnknownMessage(snapshot.note.title));
|
|
53481
|
-
}
|
|
53482
|
-
if (result.status === "not-deleted") {
|
|
53483
|
-
return errorResponse(NOT_DELETED_MESSAGE);
|
|
53484
|
-
}
|
|
53485
|
-
if (result.status !== "deleted") {
|
|
53486
|
-
return errorResponse(
|
|
53487
|
-
`The delete result for note "${snapshot.note.title}" is uncertain. Inspect exact ID ${id2} before retrying.`
|
|
53488
|
-
);
|
|
53489
|
-
}
|
|
53490
|
-
const sharedWarning = snapshot.note.shared ? "\n\n\u26A0\uFE0F This note was shared with collaborators. They will no longer have access." : "";
|
|
53491
|
-
return successResponse(
|
|
53492
|
-
`Note moved to Recently Deleted: "${snapshot.note.title}"${sharedWarning}`,
|
|
53493
|
-
{
|
|
53494
|
-
ok: true,
|
|
53585
|
+
withErrorHandling(
|
|
53586
|
+
({
|
|
53587
|
+
id: id2,
|
|
53588
|
+
expectedContentHash,
|
|
53589
|
+
guardNoteId,
|
|
53590
|
+
expectedGuardContentHash,
|
|
53591
|
+
requireActiveNoteId,
|
|
53592
|
+
...scopeArgs
|
|
53593
|
+
}) => {
|
|
53594
|
+
const prepared = prepareDeleteGuards({
|
|
53495
53595
|
id: id2,
|
|
53496
|
-
|
|
53497
|
-
|
|
53498
|
-
|
|
53596
|
+
guardNoteId,
|
|
53597
|
+
expectedGuardContentHash,
|
|
53598
|
+
requireActiveNoteId
|
|
53599
|
+
});
|
|
53600
|
+
if ("error" in prepared) return errorResponse(prepared.error);
|
|
53601
|
+
const snapshot = readExactNoteSnapshot(id2);
|
|
53602
|
+
if ("error" in snapshot) return errorResponse(snapshot.error);
|
|
53603
|
+
if (snapshot.contentHash !== expectedContentHash) {
|
|
53604
|
+
return errorResponse(revisionConflictMessage(snapshot.note.title));
|
|
53499
53605
|
}
|
|
53500
|
-
|
|
53501
|
-
|
|
53606
|
+
const result = notesManager.deleteNoteByIdIfUnchanged(
|
|
53607
|
+
id2,
|
|
53608
|
+
snapshot.body,
|
|
53609
|
+
scopeFrom(scopeArgs),
|
|
53610
|
+
prepared.guards
|
|
53611
|
+
);
|
|
53612
|
+
if (result.status === "guard-conflict") {
|
|
53613
|
+
return errorResponse(
|
|
53614
|
+
`${prepared.labels[result.index]} note changed just before the delete. Nothing was deleted; verify it again before retrying.`
|
|
53615
|
+
);
|
|
53616
|
+
}
|
|
53617
|
+
if (result.status === "guard-inactive") {
|
|
53618
|
+
return errorResponse(
|
|
53619
|
+
`${prepared.labels[result.index]} note is no longer active (${result.reason}). Nothing was deleted.`
|
|
53620
|
+
);
|
|
53621
|
+
}
|
|
53622
|
+
if (result.status === "conflict") {
|
|
53623
|
+
return errorResponse(revisionConflictMessage(snapshot.note.title));
|
|
53624
|
+
}
|
|
53625
|
+
if (result.status === "scope_conflict") {
|
|
53626
|
+
return errorResponse(scopeConflictMessage(result.reason));
|
|
53627
|
+
}
|
|
53628
|
+
if (result.status === "in-recently-deleted") {
|
|
53629
|
+
return errorResponse(inRecentlyDeletedMessage(snapshot.note.title));
|
|
53630
|
+
}
|
|
53631
|
+
if (result.status === "container-unknown") {
|
|
53632
|
+
return errorResponse(containerUnknownMessage(snapshot.note.title));
|
|
53633
|
+
}
|
|
53634
|
+
if (result.status === "not-deleted") {
|
|
53635
|
+
return errorResponse(NOT_DELETED_MESSAGE);
|
|
53636
|
+
}
|
|
53637
|
+
if (result.status !== "deleted") {
|
|
53638
|
+
return errorResponse(
|
|
53639
|
+
`The delete result for note "${snapshot.note.title}" is uncertain. Inspect exact ID ${id2} before retrying.`
|
|
53640
|
+
);
|
|
53641
|
+
}
|
|
53642
|
+
const sharedWarning = snapshot.note.shared ? "\n\n\u26A0\uFE0F This note was shared with collaborators. They will no longer have access." : "";
|
|
53643
|
+
return successResponse(
|
|
53644
|
+
`Note moved to Recently Deleted: "${snapshot.note.title}"${sharedWarning}`,
|
|
53645
|
+
{
|
|
53646
|
+
ok: true,
|
|
53647
|
+
id: id2,
|
|
53648
|
+
title: snapshot.note.title,
|
|
53649
|
+
wasShared: snapshot.note.shared ?? false,
|
|
53650
|
+
previousContentHash: expectedContentHash,
|
|
53651
|
+
...guardNoteId ? { guardNoteId, guardContentHash: prepared.guardContentHash } : {},
|
|
53652
|
+
...requireActiveNoteId ? { requireActiveNoteId } : {}
|
|
53653
|
+
}
|
|
53654
|
+
);
|
|
53655
|
+
},
|
|
53656
|
+
"Error deleting note"
|
|
53657
|
+
)
|
|
53502
53658
|
);
|
|
53503
53659
|
registerTool(
|
|
53504
53660
|
"move-note",
|
package/package.json
CHANGED