Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:35:59 +08:00
commit 90883a4d25
287 changed files with 75058 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
#!/usr/bin/env osascript -l JavaScript
// Add contact to iCloud Contacts
// Usage: osascript -l JavaScript add_contact.js '{"name": "First Last", "phone": "123-456-7890", "email": "email@example.com", "organization": "Company"}'
//
// All fields except name are optional
function run(argv) {
if (argv.length === 0) {
return JSON.stringify({
error: "Missing parameters",
usage: 'osascript -l JavaScript add_contact.js \'{"name":"...", "phone":"...", "email":"..."}\''
});
}
let params;
try {
params = JSON.parse(argv[0]);
} catch (e) {
return JSON.stringify({
error: "Invalid JSON",
details: e.message
});
}
if (!params.name) {
return JSON.stringify({ error: "Missing name parameter" });
}
// Parse name into first/last
let nameParts = params.name.trim().split(/\s+/);
let firstName = nameParts[0] || "";
let lastName = nameParts.slice(1).join(" ") || "";
const Contacts = Application("Contacts");
try {
// Create new person
let person = Contacts.Person({
firstName: firstName,
lastName: lastName
});
// Add to contacts
Contacts.people.push(person);
// Add phone if provided
if (params.phone) {
let phone = Contacts.Phone({
label: "work",
value: params.phone.replace(/[^\d+()-\s]/g, "")
});
person.phones.push(phone);
}
// Add email if provided
if (params.email) {
let email = Contacts.Email({
label: "work",
value: params.email
});
person.emails.push(email);
}
// Add organization if provided
if (params.organization) {
person.organization = params.organization;
}
// Add note if provided
if (params.note) {
person.note = params.note;
}
// Save
Contacts.save();
return JSON.stringify({
success: true,
contact: {
firstName: firstName,
lastName: lastName,
phone: params.phone || null,
email: params.email || null,
organization: params.organization || null
}
});
} catch (e) {
return JSON.stringify({
error: "Failed to create contact",
details: e.message
});
}
}

View File

@@ -0,0 +1,85 @@
#!/usr/bin/env bun
// Trigger Geoffrey Export Inbox action in Drafts
// Usage: bun trigger_export.js
//
// This triggers the Drafts action and waits for the export file to be created.
// Returns the path to the export file.
const { execSync } = require("child_process");
const fs = require("fs");
const path = require("path");
// Export file location
const exportPath = path.join(
process.env.HOME,
"Library/Mobile Documents/iCloud~com~agiletortoise~Drafts5/Documents/geoffrey-export.json"
);
// Check if Drafts is running
try {
execSync('pgrep -x "Drafts"', { stdio: "pipe" });
} catch (e) {
console.error(JSON.stringify({
error: "Drafts is not running",
suggestion: "Please open Drafts and try again"
}));
process.exit(1);
}
// Get current file modification time (if exists)
let oldMtime = 0;
try {
const stats = fs.statSync(exportPath);
oldMtime = stats.mtimeMs;
} catch (e) {
// File doesn't exist yet, that's fine
}
// Trigger the export action
const actionUrl = "drafts://x-callback-url/runAction?action=" +
encodeURIComponent("Geoffrey Export Inbox");
try {
execSync(`open "${actionUrl}"`, { stdio: "pipe" });
} catch (e) {
console.error(JSON.stringify({
error: "Failed to trigger Drafts action",
details: e.message
}));
process.exit(1);
}
// Wait for the export file to be updated (max 10 seconds)
const maxWait = 10000;
const checkInterval = 500;
let waited = 0;
while (waited < maxWait) {
try {
const stats = fs.statSync(exportPath);
if (stats.mtimeMs > oldMtime) {
// File was updated, success!
const data = JSON.parse(fs.readFileSync(exportPath, "utf-8"));
console.log(JSON.stringify({
status: "success",
path: exportPath,
count: data.count,
exported: data.exported
}));
process.exit(0);
}
} catch (e) {
// File doesn't exist yet, keep waiting
}
// Sleep
execSync(`sleep ${checkInterval / 1000}`);
waited += checkInterval;
}
// Timeout
console.error(JSON.stringify({
error: "Timeout waiting for export file",
suggestion: "Check if the 'Geoffrey Export Inbox' action is installed in Drafts"
}));
process.exit(1);

View File

@@ -0,0 +1,94 @@
#!/usr/bin/env bun
// Trigger Geoffrey Process Draft action in Drafts
// Usage: bun trigger_process.js '<json-params>'
//
// JSON params:
// {
// "uuid": "ABC123",
// "destination": "omnifocus|obsidian|archive|trash",
// "project": "Project Name", // for omnifocus
// "tags": "Tag1,Tag2", // for omnifocus
// "dueDate": "2025-11-30", // for omnifocus
// "folder": "Geoffrey/Inbox" // for obsidian
// }
const { execSync } = require("child_process");
// Parse arguments
const args = process.argv.slice(2);
if (args.length === 0) {
console.error(JSON.stringify({
error: "Missing parameters",
usage: 'bun trigger_process.js \'{"uuid":"...","destination":"..."}\''
}));
process.exit(1);
}
let params;
try {
params = JSON.parse(args[0]);
} catch (e) {
console.error(JSON.stringify({
error: "Invalid JSON parameters",
details: e.message
}));
process.exit(1);
}
// Validate required parameters
if (!params.uuid) {
console.error(JSON.stringify({ error: "Missing uuid parameter" }));
process.exit(1);
}
if (!params.destination) {
console.error(JSON.stringify({ error: "Missing destination parameter" }));
process.exit(1);
}
const validDestinations = ["omnifocus", "obsidian", "archive", "trash"];
if (!validDestinations.includes(params.destination)) {
console.error(JSON.stringify({
error: "Invalid destination",
valid: validDestinations
}));
process.exit(1);
}
// Check if Drafts is running
try {
execSync('pgrep -x "Drafts"', { stdio: "pipe" });
} catch (e) {
console.error(JSON.stringify({
error: "Drafts is not running",
suggestion: "Please open Drafts and try again"
}));
process.exit(1);
}
// Build URL with JSON in text parameter
const jsonPayload = JSON.stringify(params);
const actionUrl = "drafts://x-callback-url/runAction?action=" +
encodeURIComponent("Geoffrey Process Draft") +
"&text=" + encodeURIComponent(jsonPayload);
// Trigger the action
try {
execSync(`open "${actionUrl}"`, { stdio: "pipe" });
// Give Drafts a moment to process
execSync("sleep 1");
console.log(JSON.stringify({
status: "success",
uuid: params.uuid,
destination: params.destination,
details: params
}));
} catch (e) {
console.error(JSON.stringify({
error: "Failed to trigger Drafts action",
details: e.message
}));
process.exit(1);
}