@knowsuchagency/fulcrum 3.1.1 → 3.2.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/bin/fulcrum.js +34 -4
- package/package.json +1 -1
- package/server/index.js +137 -11
package/bin/fulcrum.js
CHANGED
|
@@ -1482,6 +1482,9 @@ class FulcrumClient {
|
|
|
1482
1482
|
async getEmail(id) {
|
|
1483
1483
|
return this.fetch(`/api/messaging/email/emails/${id}`);
|
|
1484
1484
|
}
|
|
1485
|
+
async getMessage(id) {
|
|
1486
|
+
return this.fetch(`/api/messaging/messages/${id}`);
|
|
1487
|
+
}
|
|
1485
1488
|
async searchEmails(criteria) {
|
|
1486
1489
|
return this.fetch("/api/messaging/email/search", {
|
|
1487
1490
|
method: "POST",
|
|
@@ -44207,6 +44210,13 @@ var init_registry = __esm(() => {
|
|
|
44207
44210
|
keywords: ["email", "fetch", "download", "imap", "uid", "message", "mail"],
|
|
44208
44211
|
defer_loading: false
|
|
44209
44212
|
},
|
|
44213
|
+
{
|
|
44214
|
+
name: "get_message",
|
|
44215
|
+
description: "Get details of a specific message by ID, including full content and metadata",
|
|
44216
|
+
category: "messaging",
|
|
44217
|
+
keywords: ["message", "get", "read", "channel", "whatsapp", "discord", "telegram", "slack", "chat"],
|
|
44218
|
+
defer_loading: false
|
|
44219
|
+
},
|
|
44210
44220
|
{
|
|
44211
44221
|
name: "message",
|
|
44212
44222
|
description: "Send a message to a messaging channel (WhatsApp, Discord, Telegram, Slack, Gmail)",
|
|
@@ -44307,7 +44317,7 @@ var init_registry = __esm(() => {
|
|
|
44307
44317
|
},
|
|
44308
44318
|
{
|
|
44309
44319
|
name: "create_calendar_event",
|
|
44310
|
-
description: "Create a new calendar event on a CalDAV calendar",
|
|
44320
|
+
description: "Create a new calendar event on a CalDAV or Google calendar.",
|
|
44311
44321
|
category: "caldav",
|
|
44312
44322
|
keywords: ["calendar", "event", "create", "new", "schedule", "appointment", "meeting"],
|
|
44313
44323
|
defer_loading: true
|
|
@@ -46185,6 +46195,24 @@ var init_memory_file = __esm(() => {
|
|
|
46185
46195
|
init_utils();
|
|
46186
46196
|
});
|
|
46187
46197
|
|
|
46198
|
+
// cli/src/mcp/tools/messaging.ts
|
|
46199
|
+
var registerMessagingTools = (server, client) => {
|
|
46200
|
+
server.tool("get_message", "Get details of a specific message by ID, including full content and metadata.", {
|
|
46201
|
+
id: exports_external.string().describe("Message ID")
|
|
46202
|
+
}, async ({ id }) => {
|
|
46203
|
+
try {
|
|
46204
|
+
const message = await client.getMessage(id);
|
|
46205
|
+
return formatSuccess(message);
|
|
46206
|
+
} catch (err) {
|
|
46207
|
+
return handleToolError(err);
|
|
46208
|
+
}
|
|
46209
|
+
});
|
|
46210
|
+
};
|
|
46211
|
+
var init_messaging = __esm(() => {
|
|
46212
|
+
init_zod2();
|
|
46213
|
+
init_utils();
|
|
46214
|
+
});
|
|
46215
|
+
|
|
46188
46216
|
// cli/src/mcp/tools/search.ts
|
|
46189
46217
|
var EntityTypeSchema, registerSearchTools = (server, client) => {
|
|
46190
46218
|
server.tool("search", 'Search across all Fulcrum entities (tasks, projects, messages, calendar events, memories, conversations) using full-text search. Supports boolean operators (AND, OR, NOT), phrase matching ("quoted phrases"), and prefix matching (term*). Returns results ranked by relevance.', {
|
|
@@ -46243,6 +46271,7 @@ function registerTools(server, client) {
|
|
|
46243
46271
|
registerSettingsTools(server, client);
|
|
46244
46272
|
registerBackupTools(server, client);
|
|
46245
46273
|
registerEmailTools(server, client);
|
|
46274
|
+
registerMessagingTools(server, client);
|
|
46246
46275
|
registerAssistantTools(server, client);
|
|
46247
46276
|
registerCaldavTools(server, client);
|
|
46248
46277
|
registerGmailTools(server, client);
|
|
@@ -46267,6 +46296,7 @@ var init_tools = __esm(() => {
|
|
|
46267
46296
|
init_gmail();
|
|
46268
46297
|
init_memory();
|
|
46269
46298
|
init_memory_file();
|
|
46299
|
+
init_messaging();
|
|
46270
46300
|
init_search();
|
|
46271
46301
|
init_types4();
|
|
46272
46302
|
});
|
|
@@ -46286,7 +46316,7 @@ async function runMcpServer(urlOverride, portOverride) {
|
|
|
46286
46316
|
const client = new FulcrumClient(urlOverride, portOverride);
|
|
46287
46317
|
const server = new McpServer({
|
|
46288
46318
|
name: "fulcrum",
|
|
46289
|
-
version: "3.
|
|
46319
|
+
version: "3.2.1"
|
|
46290
46320
|
});
|
|
46291
46321
|
registerTools(server, client);
|
|
46292
46322
|
const transport = new StdioServerTransport;
|
|
@@ -48635,7 +48665,7 @@ var marketplace_default = `{
|
|
|
48635
48665
|
"name": "fulcrum",
|
|
48636
48666
|
"source": "./",
|
|
48637
48667
|
"description": "Task orchestration for Claude Code",
|
|
48638
|
-
"version": "3.
|
|
48668
|
+
"version": "3.2.1",
|
|
48639
48669
|
"skills": [
|
|
48640
48670
|
"./skills/fulcrum"
|
|
48641
48671
|
],
|
|
@@ -49839,7 +49869,7 @@ function compareVersions(v1, v2) {
|
|
|
49839
49869
|
var package_default = {
|
|
49840
49870
|
name: "@knowsuchagency/fulcrum",
|
|
49841
49871
|
private: true,
|
|
49842
|
-
version: "3.
|
|
49872
|
+
version: "3.2.1",
|
|
49843
49873
|
description: "Harness Attention. Orchestrate Agents. Ship.",
|
|
49844
49874
|
license: "PolyForm-Perimeter-1.0.0",
|
|
49845
49875
|
type: "module",
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -1135470,6 +1135470,9 @@ function getChannelMessages(options = {}) {
|
|
|
1135470
1135470
|
const results = db2.select().from(channelMessages).where(whereClause).orderBy(desc(channelMessages.messageTimestamp)).limit(options.limit ?? 50).offset(options.offset ?? 0).all();
|
|
1135471
1135471
|
return results;
|
|
1135472
1135472
|
}
|
|
1135473
|
+
function getChannelMessageById(id) {
|
|
1135474
|
+
return db2.select().from(channelMessages).where(eq(channelMessages.id, id)).get();
|
|
1135475
|
+
}
|
|
1135473
1135476
|
function getChannelMessageCounts() {
|
|
1135474
1135477
|
const results = db2.select({
|
|
1135475
1135478
|
channelType: channelMessages.channelType,
|
|
@@ -1148027,6 +1148030,7 @@ ${attachment.data}`);
|
|
|
1148027
1148030
|
const resultMsg = message;
|
|
1148028
1148031
|
if (resultMsg.subtype?.startsWith("error_")) {
|
|
1148029
1148032
|
const errors2 = resultMsg.errors || ["Unknown error"];
|
|
1148033
|
+
state.claudeSessionId = undefined;
|
|
1148030
1148034
|
yield { type: "error", data: { message: errors2.join(", ") } };
|
|
1148031
1148035
|
}
|
|
1148032
1148036
|
if (resultMsg.structured_output) {
|
|
@@ -1148039,18 +1148043,21 @@ ${attachment.data}`);
|
|
|
1148039
1148043
|
});
|
|
1148040
1148044
|
}
|
|
1148041
1148045
|
}
|
|
1148042
|
-
|
|
1148043
|
-
|
|
1148044
|
-
|
|
1148045
|
-
|
|
1148046
|
-
|
|
1148047
|
-
|
|
1148048
|
-
|
|
1148049
|
-
|
|
1148046
|
+
if (currentText.trim()) {
|
|
1148047
|
+
addMessage(sessionId, {
|
|
1148048
|
+
role: "assistant",
|
|
1148049
|
+
content: currentText,
|
|
1148050
|
+
model: MODEL_MAP[effectiveModelId],
|
|
1148051
|
+
tokensIn,
|
|
1148052
|
+
tokensOut,
|
|
1148053
|
+
sessionId
|
|
1148054
|
+
});
|
|
1148055
|
+
}
|
|
1148050
1148056
|
yield { type: "done", data: {} };
|
|
1148051
1148057
|
} catch (err) {
|
|
1148052
1148058
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
1148053
1148059
|
log2.assistant.error("Assistant stream error", { sessionId, error: errorMsg });
|
|
1148060
|
+
state.claudeSessionId = undefined;
|
|
1148054
1148061
|
yield { type: "error", data: { message: errorMsg } };
|
|
1148055
1148062
|
} finally {
|
|
1148056
1148063
|
for (const tempPath of tempFiles) {
|
|
@@ -1150021,6 +1150028,38 @@ var init_opencode_channel_service = __esm(() => {
|
|
|
1150021
1150028
|
});
|
|
1150022
1150029
|
|
|
1150023
1150030
|
// server/services/channels/message-handler.ts
|
|
1150031
|
+
function recordObserverFailure() {
|
|
1150032
|
+
OBSERVER_CIRCUIT_BREAKER.failureCount++;
|
|
1150033
|
+
if (OBSERVER_CIRCUIT_BREAKER.failureCount >= OBSERVER_CIRCUIT_BREAKER.failureThreshold) {
|
|
1150034
|
+
if (OBSERVER_CIRCUIT_BREAKER.state !== "open") {
|
|
1150035
|
+
log2.messaging.warn("Observer circuit breaker OPEN \u2014 pausing observe-only processing", {
|
|
1150036
|
+
failures: OBSERVER_CIRCUIT_BREAKER.failureCount,
|
|
1150037
|
+
cooldownMs: OBSERVER_CIRCUIT_BREAKER.cooldownMs
|
|
1150038
|
+
});
|
|
1150039
|
+
}
|
|
1150040
|
+
OBSERVER_CIRCUIT_BREAKER.state = "open";
|
|
1150041
|
+
OBSERVER_CIRCUIT_BREAKER.nextProbeAt = Date.now() + OBSERVER_CIRCUIT_BREAKER.cooldownMs;
|
|
1150042
|
+
OBSERVER_CIRCUIT_BREAKER.cooldownMs = Math.min(OBSERVER_CIRCUIT_BREAKER.cooldownMs * 2, OBSERVER_CIRCUIT_BREAKER.maxCooldownMs);
|
|
1150043
|
+
}
|
|
1150044
|
+
}
|
|
1150045
|
+
function recordObserverSuccess() {
|
|
1150046
|
+
if (OBSERVER_CIRCUIT_BREAKER.state === "open") {
|
|
1150047
|
+
log2.messaging.info("Observer circuit breaker CLOSED \u2014 resuming normal processing", {
|
|
1150048
|
+
previousFailures: OBSERVER_CIRCUIT_BREAKER.failureCount
|
|
1150049
|
+
});
|
|
1150050
|
+
}
|
|
1150051
|
+
OBSERVER_CIRCUIT_BREAKER.failureCount = 0;
|
|
1150052
|
+
OBSERVER_CIRCUIT_BREAKER.state = "closed";
|
|
1150053
|
+
OBSERVER_CIRCUIT_BREAKER.nextProbeAt = 0;
|
|
1150054
|
+
OBSERVER_CIRCUIT_BREAKER.cooldownMs = 60000;
|
|
1150055
|
+
}
|
|
1150056
|
+
function isObserverCircuitOpen() {
|
|
1150057
|
+
if (OBSERVER_CIRCUIT_BREAKER.state !== "open")
|
|
1150058
|
+
return false;
|
|
1150059
|
+
if (Date.now() >= OBSERVER_CIRCUIT_BREAKER.nextProbeAt)
|
|
1150060
|
+
return false;
|
|
1150061
|
+
return true;
|
|
1150062
|
+
}
|
|
1150024
1150063
|
async function handleIncomingMessage(msg) {
|
|
1150025
1150064
|
const content = msg.content.trim();
|
|
1150026
1150065
|
const isObserveOnly = msg.metadata?.observeOnly === true;
|
|
@@ -1150268,12 +1150307,16 @@ function splitMessage(content, maxLength) {
|
|
|
1150268
1150307
|
return parts;
|
|
1150269
1150308
|
}
|
|
1150270
1150309
|
async function processObserveOnlyMessage(msg) {
|
|
1150310
|
+
if (isObserverCircuitOpen()) {
|
|
1150311
|
+
return;
|
|
1150312
|
+
}
|
|
1150271
1150313
|
const observeSessionKey = `observe-${msg.connectionId}`;
|
|
1150272
1150314
|
const { session: session3 } = getOrCreateSession(msg.connectionId, observeSessionKey, "Observer", undefined, msg.channelType);
|
|
1150273
1150315
|
const settings = getSettings();
|
|
1150274
1150316
|
const observerProvider = settings.assistant.observerProvider ?? settings.assistant.provider;
|
|
1150275
1150317
|
if (observerProvider === "opencode") {
|
|
1150276
1150318
|
try {
|
|
1150319
|
+
let hadError = false;
|
|
1150277
1150320
|
const stream2 = _deps.streamOpencodeObserverMessage(session3.id, msg.content, {
|
|
1150278
1150321
|
channelType: msg.channelType,
|
|
1150279
1150322
|
senderId: msg.senderId,
|
|
@@ -1150281,15 +1150324,21 @@ async function processObserveOnlyMessage(msg) {
|
|
|
1150281
1150324
|
});
|
|
1150282
1150325
|
for await (const event of stream2) {
|
|
1150283
1150326
|
if (event.type === "error") {
|
|
1150327
|
+
hadError = true;
|
|
1150284
1150328
|
const errorMsg = event.data.message;
|
|
1150285
1150329
|
log2.messaging.error("Error in OpenCode observe-only processing", { error: errorMsg });
|
|
1150286
1150330
|
}
|
|
1150287
1150331
|
}
|
|
1150332
|
+
if (hadError)
|
|
1150333
|
+
recordObserverFailure();
|
|
1150334
|
+
else
|
|
1150335
|
+
recordObserverSuccess();
|
|
1150288
1150336
|
} catch (err) {
|
|
1150289
1150337
|
log2.messaging.error("Error processing observe-only message via OpenCode", {
|
|
1150290
1150338
|
connectionId: msg.connectionId,
|
|
1150291
1150339
|
error: String(err)
|
|
1150292
1150340
|
});
|
|
1150341
|
+
recordObserverFailure();
|
|
1150293
1150342
|
}
|
|
1150294
1150343
|
return;
|
|
1150295
1150344
|
}
|
|
@@ -1150305,6 +1150354,7 @@ async function processObserveOnlyMessage(msg) {
|
|
|
1150305
1150354
|
};
|
|
1150306
1150355
|
const systemPrompt = getObserveOnlySystemPrompt(msg.channelType, context);
|
|
1150307
1150356
|
try {
|
|
1150357
|
+
let hadError = false;
|
|
1150308
1150358
|
const observerModelId = settings.assistant.observerModel;
|
|
1150309
1150359
|
const stream2 = _deps.streamMessage(session3.id, msg.content, {
|
|
1150310
1150360
|
systemPromptAdditions: systemPrompt,
|
|
@@ -1150313,18 +1150363,24 @@ async function processObserveOnlyMessage(msg) {
|
|
|
1150313
1150363
|
});
|
|
1150314
1150364
|
for await (const event of stream2) {
|
|
1150315
1150365
|
if (event.type === "error") {
|
|
1150366
|
+
hadError = true;
|
|
1150316
1150367
|
const errorMsg = event.data.message;
|
|
1150317
1150368
|
log2.messaging.error("Error in observe-only message processing", { error: errorMsg });
|
|
1150318
1150369
|
}
|
|
1150319
1150370
|
}
|
|
1150371
|
+
if (hadError)
|
|
1150372
|
+
recordObserverFailure();
|
|
1150373
|
+
else
|
|
1150374
|
+
recordObserverSuccess();
|
|
1150320
1150375
|
} catch (err) {
|
|
1150321
1150376
|
log2.messaging.error("Error processing observe-only message", {
|
|
1150322
1150377
|
connectionId: msg.connectionId,
|
|
1150323
1150378
|
error: String(err)
|
|
1150324
1150379
|
});
|
|
1150380
|
+
recordObserverFailure();
|
|
1150325
1150381
|
}
|
|
1150326
1150382
|
}
|
|
1150327
|
-
var _deps, SLACK_RESPONSE_SCHEMA, COMMANDS;
|
|
1150383
|
+
var _deps, SLACK_RESPONSE_SCHEMA, OBSERVER_CIRCUIT_BREAKER, COMMANDS;
|
|
1150328
1150384
|
var init_message_handler = __esm(() => {
|
|
1150329
1150385
|
init_logger3();
|
|
1150330
1150386
|
init_channel_manager();
|
|
@@ -1150351,6 +1150407,14 @@ var init_message_handler = __esm(() => {
|
|
|
1150351
1150407
|
},
|
|
1150352
1150408
|
required: ["body"]
|
|
1150353
1150409
|
};
|
|
1150410
|
+
OBSERVER_CIRCUIT_BREAKER = {
|
|
1150411
|
+
failureCount: 0,
|
|
1150412
|
+
failureThreshold: 3,
|
|
1150413
|
+
state: "closed",
|
|
1150414
|
+
nextProbeAt: 0,
|
|
1150415
|
+
cooldownMs: 60000,
|
|
1150416
|
+
maxCooldownMs: 600000
|
|
1150417
|
+
};
|
|
1150354
1150418
|
COMMANDS = {
|
|
1150355
1150419
|
RESET: ["/reset", "/new", "/clear"],
|
|
1150356
1150420
|
HELP: ["/help", "/?"],
|
|
@@ -1251641,6 +1251705,13 @@ var toolRegistry = [
|
|
|
1251641
1251705
|
keywords: ["email", "fetch", "download", "imap", "uid", "message", "mail"],
|
|
1251642
1251706
|
defer_loading: false
|
|
1251643
1251707
|
},
|
|
1251708
|
+
{
|
|
1251709
|
+
name: "get_message",
|
|
1251710
|
+
description: "Get details of a specific message by ID, including full content and metadata",
|
|
1251711
|
+
category: "messaging",
|
|
1251712
|
+
keywords: ["message", "get", "read", "channel", "whatsapp", "discord", "telegram", "slack", "chat"],
|
|
1251713
|
+
defer_loading: false
|
|
1251714
|
+
},
|
|
1251644
1251715
|
{
|
|
1251645
1251716
|
name: "message",
|
|
1251646
1251717
|
description: "Send a message to a messaging channel (WhatsApp, Discord, Telegram, Slack, Gmail)",
|
|
@@ -1251741,7 +1251812,7 @@ var toolRegistry = [
|
|
|
1251741
1251812
|
},
|
|
1251742
1251813
|
{
|
|
1251743
1251814
|
name: "create_calendar_event",
|
|
1251744
|
-
description: "Create a new calendar event on a CalDAV calendar",
|
|
1251815
|
+
description: "Create a new calendar event on a CalDAV or Google calendar.",
|
|
1251745
1251816
|
category: "caldav",
|
|
1251746
1251817
|
keywords: ["calendar", "event", "create", "new", "schedule", "appointment", "meeting"],
|
|
1251747
1251818
|
defer_loading: true
|
|
@@ -1253559,6 +1253630,20 @@ var registerMemoryFileTools = (server2, client3) => {
|
|
|
1253559
1253630
|
});
|
|
1253560
1253631
|
};
|
|
1253561
1253632
|
|
|
1253633
|
+
// cli/src/mcp/tools/messaging.ts
|
|
1253634
|
+
var registerMessagingTools = (server2, client3) => {
|
|
1253635
|
+
server2.tool("get_message", "Get details of a specific message by ID, including full content and metadata.", {
|
|
1253636
|
+
id: exports_external.string().describe("Message ID")
|
|
1253637
|
+
}, async ({ id }) => {
|
|
1253638
|
+
try {
|
|
1253639
|
+
const message = await client3.getMessage(id);
|
|
1253640
|
+
return formatSuccess(message);
|
|
1253641
|
+
} catch (err) {
|
|
1253642
|
+
return handleToolError(err);
|
|
1253643
|
+
}
|
|
1253644
|
+
});
|
|
1253645
|
+
};
|
|
1253646
|
+
|
|
1253562
1253647
|
// cli/src/mcp/tools/search.ts
|
|
1253563
1253648
|
var EntityTypeSchema = exports_external.enum(["tasks", "projects", "messages", "events", "memories", "conversations"]);
|
|
1253564
1253649
|
var registerSearchTools = (server2, client3) => {
|
|
@@ -1253613,6 +1253698,7 @@ function registerTools(server2, client3) {
|
|
|
1253613
1253698
|
registerSettingsTools(server2, client3);
|
|
1253614
1253699
|
registerBackupTools(server2, client3);
|
|
1253615
1253700
|
registerEmailTools(server2, client3);
|
|
1253701
|
+
registerMessagingTools(server2, client3);
|
|
1253616
1253702
|
registerAssistantTools(server2, client3);
|
|
1253617
1253703
|
registerCaldavTools(server2, client3);
|
|
1253618
1253704
|
registerGmailTools(server2, client3);
|
|
@@ -1254202,6 +1254288,9 @@ class FulcrumClient {
|
|
|
1254202
1254288
|
async getEmail(id) {
|
|
1254203
1254289
|
return this.fetch(`/api/messaging/email/emails/${id}`);
|
|
1254204
1254290
|
}
|
|
1254291
|
+
async getMessage(id) {
|
|
1254292
|
+
return this.fetch(`/api/messaging/messages/${id}`);
|
|
1254293
|
+
}
|
|
1254205
1254294
|
async searchEmails(criteria) {
|
|
1254206
1254295
|
return this.fetch("/api/messaging/email/search", {
|
|
1254207
1254296
|
method: "POST",
|
|
@@ -1254442,7 +1254531,7 @@ mcpRoutes.all("/", async (c) => {
|
|
|
1254442
1254531
|
});
|
|
1254443
1254532
|
const server2 = new McpServer({
|
|
1254444
1254533
|
name: "fulcrum",
|
|
1254445
|
-
version: "3.
|
|
1254534
|
+
version: "3.2.1"
|
|
1254446
1254535
|
});
|
|
1254447
1254536
|
const client3 = new FulcrumClient(`http://localhost:${port}`);
|
|
1254448
1254537
|
registerTools(server2, client3);
|
|
@@ -1255107,6 +1255196,7 @@ var assistant_default = assistantRoutes;
|
|
|
1255107
1255196
|
// server/routes/messaging.ts
|
|
1255108
1255197
|
init_channels();
|
|
1255109
1255198
|
init_email_storage();
|
|
1255199
|
+
init_message_storage();
|
|
1255110
1255200
|
init_logger3();
|
|
1255111
1255201
|
var app23 = new Hono2;
|
|
1255112
1255202
|
app23.get("/channels", (c) => {
|
|
@@ -1255504,6 +1255594,19 @@ app23.post("/email/fetch", async (c) => {
|
|
|
1255504
1255594
|
return c.json({ error: String(err) }, 500);
|
|
1255505
1255595
|
}
|
|
1255506
1255596
|
});
|
|
1255597
|
+
app23.get("/messages/:id", (c) => {
|
|
1255598
|
+
try {
|
|
1255599
|
+
const id = c.req.param("id");
|
|
1255600
|
+
const message = getChannelMessageById(id);
|
|
1255601
|
+
if (!message) {
|
|
1255602
|
+
return c.json({ error: "Message not found" }, 404);
|
|
1255603
|
+
}
|
|
1255604
|
+
return c.json(message);
|
|
1255605
|
+
} catch (err) {
|
|
1255606
|
+
log2.messaging.error("Failed to get message", { error: String(err) });
|
|
1255607
|
+
return c.json({ error: String(err) }, 500);
|
|
1255608
|
+
}
|
|
1255609
|
+
});
|
|
1255507
1255610
|
app23.post("/send", async (c) => {
|
|
1255508
1255611
|
try {
|
|
1255509
1255612
|
const body = await c.req.json();
|
|
@@ -1255751,6 +1255854,7 @@ init_settings();
|
|
|
1255751
1255854
|
init_logger3();
|
|
1255752
1255855
|
init_ical_helpers();
|
|
1255753
1255856
|
init_caldav_account_manager();
|
|
1255857
|
+
init_google_calendar_manager();
|
|
1255754
1255858
|
var logger9 = createLogger("CalDAV");
|
|
1255755
1255859
|
function migrateFromSettings() {
|
|
1255756
1255860
|
const settings = getSettings();
|
|
@@ -1256056,6 +1256160,20 @@ async function createEvent(input) {
|
|
|
1256056
1256160
|
if (!calendar2) {
|
|
1256057
1256161
|
throw new Error(`Calendar not found: ${input.calendarId}`);
|
|
1256058
1256162
|
}
|
|
1256163
|
+
if (calendar2.googleAccountId) {
|
|
1256164
|
+
await googleCalendarManager.createEvent(calendar2.id, {
|
|
1256165
|
+
summary: input.summary,
|
|
1256166
|
+
dtstart: input.dtstart,
|
|
1256167
|
+
dtend: input.dtend,
|
|
1256168
|
+
description: input.description,
|
|
1256169
|
+
location: input.location,
|
|
1256170
|
+
allDay: input.allDay
|
|
1256171
|
+
});
|
|
1256172
|
+
const created = db2.select().from(caldavEvents).where(eq(caldavEvents.calendarId, input.calendarId)).orderBy(desc(caldavEvents.createdAt)).limit(1).get();
|
|
1256173
|
+
if (!created)
|
|
1256174
|
+
throw new Error("Failed to retrieve created Google Calendar event");
|
|
1256175
|
+
return created;
|
|
1256176
|
+
}
|
|
1256059
1256177
|
const client4 = calendar2.accountId ? accountManager.getClient(calendar2.accountId) : null;
|
|
1256060
1256178
|
if (!client4) {
|
|
1256061
1256179
|
throw new Error("CalDAV account not connected for this calendar");
|
|
@@ -1256112,6 +1256230,10 @@ async function updateEvent(id, updates) {
|
|
|
1256112
1256230
|
throw new Error(`Event not found: ${id}`);
|
|
1256113
1256231
|
}
|
|
1256114
1256232
|
const calendar2 = db2.select().from(caldavCalendars).where(eq(caldavCalendars.id, event.calendarId)).get();
|
|
1256233
|
+
if (calendar2?.googleAccountId) {
|
|
1256234
|
+
await googleCalendarManager.updateEvent(id, updates);
|
|
1256235
|
+
return db2.select().from(caldavEvents).where(eq(caldavEvents.id, id)).get();
|
|
1256236
|
+
}
|
|
1256115
1256237
|
const client4 = calendar2?.accountId ? accountManager.getClient(calendar2.accountId) : null;
|
|
1256116
1256238
|
if (!client4) {
|
|
1256117
1256239
|
throw new Error("CalDAV account not connected for this calendar");
|
|
@@ -1256158,6 +1256280,10 @@ async function deleteEvent(id) {
|
|
|
1256158
1256280
|
throw new Error(`Event not found: ${id}`);
|
|
1256159
1256281
|
}
|
|
1256160
1256282
|
const calendar2 = db2.select().from(caldavCalendars).where(eq(caldavCalendars.id, event.calendarId)).get();
|
|
1256283
|
+
if (calendar2?.googleAccountId) {
|
|
1256284
|
+
await googleCalendarManager.deleteEvent(id);
|
|
1256285
|
+
return;
|
|
1256286
|
+
}
|
|
1256161
1256287
|
const client4 = calendar2?.accountId ? accountManager.getClient(calendar2.accountId) : null;
|
|
1256162
1256288
|
if (!client4) {
|
|
1256163
1256289
|
throw new Error("CalDAV account not connected for this calendar");
|