> apple-notes-sdk-patterns
Apply production-ready patterns for Apple Notes JXA/AppleScript automation. Trigger: "apple notes patterns".
curl "https://skillshub.wtf/jeremylongshore/claude-code-plugins-plus-skills/apple-notes-sdk-patterns?format=md"Apple Notes SDK Patterns
Overview
Production patterns for Apple Notes automation: JXA wrapper class, error handling, batch operations, and cross-account support.
Instructions
Step 1: JXA Client Wrapper (Node.js)
// src/notes-client.ts
import { execSync } from "child_process";
class AppleNotesClient {
private runJxa(script: string): string {
const escaped = script.replace(/'/g, "\\'");
return execSync(`osascript -l JavaScript -e '${escaped}'`, {
encoding: "utf8",
timeout: 30000,
}).trim();
}
listNotes(folder?: string, limit: number = 50): Array<{ id: string; title: string; modified: string }> {
const script = folder
? `const Notes = Application("Notes"); const f = Notes.defaultAccount.folders().find(f => f.name() === "${folder}"); (f ? f.notes() : []).slice(0, ${limit}).map(n => JSON.stringify({id: n.id(), title: n.name(), modified: n.modificationDate().toISOString()})).join("\\n")`
: `const Notes = Application("Notes"); Notes.defaultAccount.notes().slice(0, ${limit}).map(n => JSON.stringify({id: n.id(), title: n.name(), modified: n.modificationDate().toISOString()})).join("\\n")`;
return this.runJxa(script).split("\n").filter(Boolean).map(l => JSON.parse(l));
}
createNote(title: string, body: string, folder?: string): string {
const folderPart = folder
? `let f = account.folders().find(f => f.name() === "${folder}"); if (!f) { f = Notes.Folder({name: "${folder}"}); account.folders.push(f); }`
: "let f = account.folders[0];";
return this.runJxa(`
const Notes = Application("Notes");
const account = Notes.defaultAccount;
${folderPart}
const note = Notes.Note({name: ${JSON.stringify(title)}, body: ${JSON.stringify(body)}});
f.notes.push(note);
note.id();
`);
}
searchNotes(query: string): Array<{ title: string; folder: string }> {
const result = this.runJxa(`
const Notes = Application("Notes");
const q = "${query}".toLowerCase();
Notes.defaultAccount.notes().filter(n =>
n.name().toLowerCase().includes(q) || n.body().toLowerCase().includes(q)
).slice(0, 20).map(n => JSON.stringify({title: n.name(), folder: n.container().name()})).join("\\n");
`);
return result.split("\n").filter(Boolean).map(l => JSON.parse(l));
}
}
export { AppleNotesClient };
Step 2: Batch Operations with Throttling
async function batchCreateNotes(
client: AppleNotesClient,
notes: Array<{ title: string; body: string; folder?: string }>,
delayMs: number = 500,
): Promise<string[]> {
const ids: string[] = [];
for (const note of notes) {
const id = client.createNote(note.title, note.body, note.folder);
ids.push(id);
await new Promise(r => setTimeout(r, delayMs));
}
return ids;
}
Output
- Type-safe JXA client wrapper for Node.js
- List, create, search operations via osascript
- Batch operations with throttling
Resources
> related_skills --same-repo
> fathom-cost-tuning
Optimize Fathom API usage and plan selection. Trigger with phrases like "fathom cost", "fathom pricing", "fathom plan".
> fathom-core-workflow-b
Sync Fathom meeting data to CRM and build automated follow-up workflows. Use when integrating Fathom with Salesforce, HubSpot, or custom CRMs, or creating automated post-meeting email summaries. Trigger with phrases like "fathom crm sync", "fathom salesforce", "fathom follow-up", "fathom post-meeting workflow".
> fathom-core-workflow-a
Build a meeting analytics pipeline with Fathom transcripts and summaries. Use when extracting insights from meetings, building CRM sync, or creating automated meeting follow-up workflows. Trigger with phrases like "fathom analytics", "fathom meeting pipeline", "fathom transcript analysis", "fathom action items sync".
> fathom-common-errors
Diagnose and fix Fathom API errors including auth failures and missing data. Use when API calls fail, transcripts are empty, or webhooks are not firing. Trigger with phrases like "fathom error", "fathom not working", "fathom api failure", "fix fathom".