@knowsuchagency/fulcrum 2.9.0 → 2.10.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/README.md +5 -2
- package/bin/fulcrum.js +178 -7
- package/dist/assets/index-CuJCUrcM.css +1 -0
- package/dist/assets/{index-dMSLbxmc.js → index-DDg3hDUp.js} +168 -168
- package/dist/index.html +2 -2
- package/drizzle/0055_caldav_multi_account.sql +40 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/server/index.js +15556 -14491
- package/dist/assets/index-Lj1lLJpw.css +0 -1
package/README.md
CHANGED
|
@@ -156,11 +156,13 @@ Create documents with live preview. Generate charts and visualizations. The assi
|
|
|
156
156
|
|
|
157
157
|
### Calendar Integration
|
|
158
158
|
|
|
159
|
-
Connect
|
|
159
|
+
Connect multiple calendar accounts via CalDAV so the AI assistant knows your schedule. Copy events between calendars across accounts.
|
|
160
160
|
|
|
161
|
+
- **Multiple accounts** — Add as many CalDAV accounts as you need
|
|
161
162
|
- **Google Calendar** — OAuth2 flow, no password needed
|
|
162
163
|
- **Any CalDAV server** — Nextcloud, Radicale, Baikal, iCloud
|
|
163
|
-
- **Automatic sync** —
|
|
164
|
+
- **Automatic sync** — Each account syncs independently on a configurable interval
|
|
165
|
+
- **One-way event copying** — Copy events between calendars across accounts via configurable rules
|
|
164
166
|
- **Assistant awareness** — The AI assistant uses your calendar context for planning and scheduling
|
|
165
167
|
|
|
166
168
|
Enable in Settings → Calendar Integration.
|
|
@@ -247,6 +249,7 @@ Both plugins include an MCP server with 60+ tools:
|
|
|
247
249
|
| **Backup & Restore** | Snapshot database and settings; auto-safety-backup on restore |
|
|
248
250
|
| **Settings** | View and update configuration; manage notification channels |
|
|
249
251
|
| **Memory** | Store and search persistent knowledge with FTS5 full-text search |
|
|
252
|
+
| **Calendar** | Manage CalDAV accounts, sync calendars, configure event copy rules |
|
|
250
253
|
| **Assistant** | Send messages via channels; query sweep history |
|
|
251
254
|
|
|
252
255
|
Use `search_tools` to discover available tools by keyword or category.
|
package/bin/fulcrum.js
CHANGED
|
@@ -1518,8 +1518,39 @@ class FulcrumClient {
|
|
|
1518
1518
|
async getCaldavStatus() {
|
|
1519
1519
|
return this.fetch("/api/caldav/status");
|
|
1520
1520
|
}
|
|
1521
|
-
async listCalendars() {
|
|
1522
|
-
|
|
1521
|
+
async listCalendars(accountId) {
|
|
1522
|
+
const params = accountId ? `?accountId=${accountId}` : "";
|
|
1523
|
+
return this.fetch(`/api/caldav/calendars${params}`);
|
|
1524
|
+
}
|
|
1525
|
+
async listCaldavAccounts() {
|
|
1526
|
+
return this.fetch("/api/caldav/accounts");
|
|
1527
|
+
}
|
|
1528
|
+
async createCaldavAccount(input) {
|
|
1529
|
+
return this.fetch("/api/caldav/accounts", {
|
|
1530
|
+
method: "POST",
|
|
1531
|
+
body: JSON.stringify(input)
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
async deleteCaldavAccount(id) {
|
|
1535
|
+
return this.fetch(`/api/caldav/accounts/${id}`, { method: "DELETE" });
|
|
1536
|
+
}
|
|
1537
|
+
async syncCaldavAccount(id) {
|
|
1538
|
+
return this.fetch(`/api/caldav/accounts/${id}/sync`, { method: "POST" });
|
|
1539
|
+
}
|
|
1540
|
+
async listCaldavCopyRules() {
|
|
1541
|
+
return this.fetch("/api/caldav/copy-rules");
|
|
1542
|
+
}
|
|
1543
|
+
async createCaldavCopyRule(input) {
|
|
1544
|
+
return this.fetch("/api/caldav/copy-rules", {
|
|
1545
|
+
method: "POST",
|
|
1546
|
+
body: JSON.stringify(input)
|
|
1547
|
+
});
|
|
1548
|
+
}
|
|
1549
|
+
async deleteCaldavCopyRule(id) {
|
|
1550
|
+
return this.fetch(`/api/caldav/copy-rules/${id}`, { method: "DELETE" });
|
|
1551
|
+
}
|
|
1552
|
+
async executeCaldavCopyRule(id) {
|
|
1553
|
+
return this.fetch(`/api/caldav/copy-rules/${id}/execute`, { method: "POST" });
|
|
1523
1554
|
}
|
|
1524
1555
|
async syncCalendars() {
|
|
1525
1556
|
return this.fetch("/api/caldav/sync", { method: "POST" });
|
|
@@ -44097,6 +44128,62 @@ var init_registry = __esm(() => {
|
|
|
44097
44128
|
keywords: ["sweep", "last", "hourly", "morning", "evening", "ritual"],
|
|
44098
44129
|
defer_loading: false
|
|
44099
44130
|
},
|
|
44131
|
+
{
|
|
44132
|
+
name: "list_caldav_accounts",
|
|
44133
|
+
description: "List all CalDAV accounts configured for calendar sync",
|
|
44134
|
+
category: "caldav",
|
|
44135
|
+
keywords: ["caldav", "account", "list", "calendar", "google", "nextcloud"],
|
|
44136
|
+
defer_loading: true
|
|
44137
|
+
},
|
|
44138
|
+
{
|
|
44139
|
+
name: "create_caldav_account",
|
|
44140
|
+
description: "Create a new CalDAV account with basic authentication",
|
|
44141
|
+
category: "caldav",
|
|
44142
|
+
keywords: ["caldav", "account", "create", "add", "calendar", "connect"],
|
|
44143
|
+
defer_loading: true
|
|
44144
|
+
},
|
|
44145
|
+
{
|
|
44146
|
+
name: "delete_caldav_account",
|
|
44147
|
+
description: "Delete a CalDAV account and all its calendars and events",
|
|
44148
|
+
category: "caldav",
|
|
44149
|
+
keywords: ["caldav", "account", "delete", "remove", "disconnect"],
|
|
44150
|
+
defer_loading: true
|
|
44151
|
+
},
|
|
44152
|
+
{
|
|
44153
|
+
name: "sync_caldav_account",
|
|
44154
|
+
description: "Trigger a manual sync for a specific CalDAV account",
|
|
44155
|
+
category: "caldav",
|
|
44156
|
+
keywords: ["caldav", "account", "sync", "refresh", "calendar"],
|
|
44157
|
+
defer_loading: true
|
|
44158
|
+
},
|
|
44159
|
+
{
|
|
44160
|
+
name: "list_caldav_copy_rules",
|
|
44161
|
+
description: "List all CalDAV copy rules for one-way event replication between calendars",
|
|
44162
|
+
category: "caldav",
|
|
44163
|
+
keywords: ["caldav", "copy", "rule", "list", "replicate", "sync", "calendar"],
|
|
44164
|
+
defer_loading: true
|
|
44165
|
+
},
|
|
44166
|
+
{
|
|
44167
|
+
name: "create_caldav_copy_rule",
|
|
44168
|
+
description: "Create a copy rule to replicate events from one calendar to another",
|
|
44169
|
+
category: "caldav",
|
|
44170
|
+
keywords: ["caldav", "copy", "rule", "create", "replicate", "calendar"],
|
|
44171
|
+
defer_loading: true
|
|
44172
|
+
},
|
|
44173
|
+
{
|
|
44174
|
+
name: "delete_caldav_copy_rule",
|
|
44175
|
+
description: "Delete a CalDAV copy rule",
|
|
44176
|
+
category: "caldav",
|
|
44177
|
+
keywords: ["caldav", "copy", "rule", "delete", "remove"],
|
|
44178
|
+
defer_loading: true
|
|
44179
|
+
},
|
|
44180
|
+
{
|
|
44181
|
+
name: "execute_caldav_copy_rule",
|
|
44182
|
+
description: "Manually execute a copy rule to replicate events now",
|
|
44183
|
+
category: "caldav",
|
|
44184
|
+
keywords: ["caldav", "copy", "rule", "execute", "run", "replicate"],
|
|
44185
|
+
defer_loading: true
|
|
44186
|
+
},
|
|
44100
44187
|
{
|
|
44101
44188
|
name: "list_calendars",
|
|
44102
44189
|
description: "List all CalDAV calendars synced from the configured server",
|
|
@@ -45611,9 +45698,93 @@ var init_assistant = __esm(() => {
|
|
|
45611
45698
|
|
|
45612
45699
|
// cli/src/mcp/tools/caldav.ts
|
|
45613
45700
|
var registerCaldavTools = (server, client) => {
|
|
45614
|
-
server.tool("
|
|
45701
|
+
server.tool("list_caldav_accounts", "List all CalDAV accounts configured for calendar sync.", {}, async () => {
|
|
45702
|
+
try {
|
|
45703
|
+
const accounts = await client.listCaldavAccounts();
|
|
45704
|
+
return formatSuccess(accounts);
|
|
45705
|
+
} catch (err) {
|
|
45706
|
+
return handleToolError(err);
|
|
45707
|
+
}
|
|
45708
|
+
});
|
|
45709
|
+
server.tool("create_caldav_account", "Create a new CalDAV account with basic authentication.", {
|
|
45710
|
+
name: exports_external.string().describe("Display name for the account"),
|
|
45711
|
+
serverUrl: exports_external.string().describe("CalDAV server URL"),
|
|
45712
|
+
username: exports_external.string().describe("Username for authentication"),
|
|
45713
|
+
password: exports_external.string().describe("Password for authentication"),
|
|
45714
|
+
syncIntervalMinutes: exports_external.optional(exports_external.number()).describe("Sync interval in minutes (default: 15)")
|
|
45715
|
+
}, async (input) => {
|
|
45716
|
+
try {
|
|
45717
|
+
const account = await client.createCaldavAccount(input);
|
|
45718
|
+
return formatSuccess(account);
|
|
45719
|
+
} catch (err) {
|
|
45720
|
+
return handleToolError(err);
|
|
45721
|
+
}
|
|
45722
|
+
});
|
|
45723
|
+
server.tool("delete_caldav_account", "Delete a CalDAV account and all its calendars and events.", {
|
|
45724
|
+
id: exports_external.string().describe("Account ID to delete")
|
|
45725
|
+
}, async ({ id }) => {
|
|
45726
|
+
try {
|
|
45727
|
+
const result = await client.deleteCaldavAccount(id);
|
|
45728
|
+
return formatSuccess(result);
|
|
45729
|
+
} catch (err) {
|
|
45730
|
+
return handleToolError(err);
|
|
45731
|
+
}
|
|
45732
|
+
});
|
|
45733
|
+
server.tool("sync_caldav_account", "Trigger a manual sync for a specific CalDAV account.", {
|
|
45734
|
+
id: exports_external.string().describe("Account ID to sync")
|
|
45735
|
+
}, async ({ id }) => {
|
|
45736
|
+
try {
|
|
45737
|
+
const result = await client.syncCaldavAccount(id);
|
|
45738
|
+
return formatSuccess(result);
|
|
45739
|
+
} catch (err) {
|
|
45740
|
+
return handleToolError(err);
|
|
45741
|
+
}
|
|
45742
|
+
});
|
|
45743
|
+
server.tool("list_caldav_copy_rules", "List all CalDAV copy rules for one-way event replication between calendars.", {}, async () => {
|
|
45744
|
+
try {
|
|
45745
|
+
const rules = await client.listCaldavCopyRules();
|
|
45746
|
+
return formatSuccess(rules);
|
|
45747
|
+
} catch (err) {
|
|
45748
|
+
return handleToolError(err);
|
|
45749
|
+
}
|
|
45750
|
+
});
|
|
45751
|
+
server.tool("create_caldav_copy_rule", "Create a copy rule to replicate events from one calendar to another.", {
|
|
45752
|
+
sourceCalendarId: exports_external.string().describe("Source calendar ID"),
|
|
45753
|
+
destCalendarId: exports_external.string().describe("Destination calendar ID"),
|
|
45754
|
+
name: exports_external.optional(exports_external.string()).describe("Optional label for the rule")
|
|
45755
|
+
}, async (input) => {
|
|
45756
|
+
try {
|
|
45757
|
+
const rule = await client.createCaldavCopyRule(input);
|
|
45758
|
+
return formatSuccess(rule);
|
|
45759
|
+
} catch (err) {
|
|
45760
|
+
return handleToolError(err);
|
|
45761
|
+
}
|
|
45762
|
+
});
|
|
45763
|
+
server.tool("delete_caldav_copy_rule", "Delete a CalDAV copy rule.", {
|
|
45764
|
+
id: exports_external.string().describe("Copy rule ID to delete")
|
|
45765
|
+
}, async ({ id }) => {
|
|
45766
|
+
try {
|
|
45767
|
+
const result = await client.deleteCaldavCopyRule(id);
|
|
45768
|
+
return formatSuccess(result);
|
|
45769
|
+
} catch (err) {
|
|
45770
|
+
return handleToolError(err);
|
|
45771
|
+
}
|
|
45772
|
+
});
|
|
45773
|
+
server.tool("execute_caldav_copy_rule", "Manually execute a copy rule to replicate events now.", {
|
|
45774
|
+
id: exports_external.string().describe("Copy rule ID to execute")
|
|
45775
|
+
}, async ({ id }) => {
|
|
45776
|
+
try {
|
|
45777
|
+
const result = await client.executeCaldavCopyRule(id);
|
|
45778
|
+
return formatSuccess(result);
|
|
45779
|
+
} catch (err) {
|
|
45780
|
+
return handleToolError(err);
|
|
45781
|
+
}
|
|
45782
|
+
});
|
|
45783
|
+
server.tool("list_calendars", "List all CalDAV calendars synced from the configured server.", {
|
|
45784
|
+
accountId: exports_external.optional(exports_external.string()).describe("Filter by account ID")
|
|
45785
|
+
}, async ({ accountId }) => {
|
|
45615
45786
|
try {
|
|
45616
|
-
const calendars = await client.listCalendars();
|
|
45787
|
+
const calendars = await client.listCalendars(accountId);
|
|
45617
45788
|
return formatSuccess(calendars);
|
|
45618
45789
|
} catch (err) {
|
|
45619
45790
|
return handleToolError(err);
|
|
@@ -45800,7 +45971,7 @@ async function runMcpServer(urlOverride, portOverride) {
|
|
|
45800
45971
|
const client = new FulcrumClient(urlOverride, portOverride);
|
|
45801
45972
|
const server = new McpServer({
|
|
45802
45973
|
name: "fulcrum",
|
|
45803
|
-
version: "2.
|
|
45974
|
+
version: "2.10.0"
|
|
45804
45975
|
});
|
|
45805
45976
|
registerTools(server, client);
|
|
45806
45977
|
const transport = new StdioServerTransport;
|
|
@@ -48149,7 +48320,7 @@ var marketplace_default = `{
|
|
|
48149
48320
|
"name": "fulcrum",
|
|
48150
48321
|
"source": "./",
|
|
48151
48322
|
"description": "Task orchestration for Claude Code",
|
|
48152
|
-
"version": "2.
|
|
48323
|
+
"version": "2.10.0",
|
|
48153
48324
|
"skills": [
|
|
48154
48325
|
"./skills/fulcrum"
|
|
48155
48326
|
],
|
|
@@ -49337,7 +49508,7 @@ function compareVersions(v1, v2) {
|
|
|
49337
49508
|
var package_default = {
|
|
49338
49509
|
name: "@knowsuchagency/fulcrum",
|
|
49339
49510
|
private: true,
|
|
49340
|
-
version: "2.
|
|
49511
|
+
version: "2.10.0",
|
|
49341
49512
|
description: "Harness Attention. Orchestrate Agents. Ship.",
|
|
49342
49513
|
license: "PolyForm-Perimeter-1.0.0",
|
|
49343
49514
|
type: "module",
|