@cfio/cohort-sync 0.8.0 → 0.8.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/dist/index.js +83 -83
- package/dist/openclaw.plugin.json +3 -3
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16,9 +16,9 @@ __export(keychain_exports, {
|
|
|
16
16
|
setCredential: () => setCredential
|
|
17
17
|
});
|
|
18
18
|
import { execFile } from "node:child_process";
|
|
19
|
-
import
|
|
19
|
+
import os4 from "node:os";
|
|
20
20
|
function assertMacOS(operation) {
|
|
21
|
-
if (
|
|
21
|
+
if (os4.platform() !== "darwin") {
|
|
22
22
|
throw new Error(
|
|
23
23
|
`cohort-sync: ${operation} requires macOS Keychain. On Linux/Windows, set your API key in OpenClaw config: plugins.entries.cohort-sync.config.apiKey`
|
|
24
24
|
);
|
|
@@ -100,6 +100,7 @@ var init_keychain = __esm({
|
|
|
100
100
|
|
|
101
101
|
// src/hooks.ts
|
|
102
102
|
import fs3 from "node:fs";
|
|
103
|
+
import os3 from "node:os";
|
|
103
104
|
import path3 from "node:path";
|
|
104
105
|
|
|
105
106
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.48/node_modules/@sinclair/typebox/build/esm/type/guard/value.mjs
|
|
@@ -2930,6 +2931,9 @@ async function fullSync(agentName, model, cfg, logger, openClawAgents) {
|
|
|
2930
2931
|
logger.info("cohort-sync: full sync complete");
|
|
2931
2932
|
}
|
|
2932
2933
|
|
|
2934
|
+
// src/convex-bridge.ts
|
|
2935
|
+
import { createHash } from "crypto";
|
|
2936
|
+
|
|
2933
2937
|
// ../../node_modules/.pnpm/convex@1.33.0_patch_hash=l43bztwr6e2lbmpd6ao6hmcg24_react@19.2.1/node_modules/convex/dist/esm/index.js
|
|
2934
2938
|
var version = "1.33.0";
|
|
2935
2939
|
|
|
@@ -7860,14 +7864,14 @@ var require_node_gyp_build = __commonJS({
|
|
|
7860
7864
|
"../common/temp/node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/node-gyp-build.js"(exports, module) {
|
|
7861
7865
|
var fs4 = __require("fs");
|
|
7862
7866
|
var path4 = __require("path");
|
|
7863
|
-
var
|
|
7867
|
+
var os5 = __require("os");
|
|
7864
7868
|
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
7865
7869
|
var vars = process.config && process.config.variables || {};
|
|
7866
7870
|
var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
|
|
7867
7871
|
var abi = process.versions.modules;
|
|
7868
7872
|
var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
|
|
7869
|
-
var arch = process.env.npm_config_arch ||
|
|
7870
|
-
var platform = process.env.npm_config_platform ||
|
|
7873
|
+
var arch = process.env.npm_config_arch || os5.arch();
|
|
7874
|
+
var platform = process.env.npm_config_platform || os5.platform();
|
|
7871
7875
|
var libc = process.env.LIBC || (isAlpine(platform) ? "musl" : "glibc");
|
|
7872
7876
|
var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
|
|
7873
7877
|
var uv = (process.versions.uv || "").split(".")[0];
|
|
@@ -10219,7 +10223,7 @@ var require_websocket = __commonJS({
|
|
|
10219
10223
|
var http = __require("http");
|
|
10220
10224
|
var net = __require("net");
|
|
10221
10225
|
var tls = __require("tls");
|
|
10222
|
-
var { randomBytes, createHash } = __require("crypto");
|
|
10226
|
+
var { randomBytes, createHash: createHash2 } = __require("crypto");
|
|
10223
10227
|
var { Duplex, Readable } = __require("stream");
|
|
10224
10228
|
var { URL: URL2 } = __require("url");
|
|
10225
10229
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -10876,7 +10880,7 @@ var require_websocket = __commonJS({
|
|
|
10876
10880
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
10877
10881
|
return;
|
|
10878
10882
|
}
|
|
10879
|
-
const digest =
|
|
10883
|
+
const digest = createHash2("sha1").update(key + GUID).digest("base64");
|
|
10880
10884
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
10881
10885
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
10882
10886
|
return;
|
|
@@ -11141,7 +11145,7 @@ var require_websocket_server = __commonJS({
|
|
|
11141
11145
|
var EventEmitter = __require("events");
|
|
11142
11146
|
var http = __require("http");
|
|
11143
11147
|
var { Duplex } = __require("stream");
|
|
11144
|
-
var { createHash } = __require("crypto");
|
|
11148
|
+
var { createHash: createHash2 } = __require("crypto");
|
|
11145
11149
|
var extension = require_extension();
|
|
11146
11150
|
var PerMessageDeflate = require_permessage_deflate();
|
|
11147
11151
|
var subprotocol = require_subprotocol();
|
|
@@ -11436,7 +11440,7 @@ var require_websocket_server = __commonJS({
|
|
|
11436
11440
|
);
|
|
11437
11441
|
}
|
|
11438
11442
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
11439
|
-
const digest =
|
|
11443
|
+
const digest = createHash2("sha1").update(key + GUID).digest("base64");
|
|
11440
11444
|
const headers = [
|
|
11441
11445
|
"HTTP/1.1 101 Switching Protocols",
|
|
11442
11446
|
"Upgrade: websocket",
|
|
@@ -11773,7 +11777,6 @@ function reverseResolveAgentName(cohortName, forwardMap) {
|
|
|
11773
11777
|
}
|
|
11774
11778
|
|
|
11775
11779
|
// src/commands.ts
|
|
11776
|
-
var cronRunNowPoll = null;
|
|
11777
11780
|
async function executeCommand(cmd, gwClient, cfg, resolveAgentName, logger) {
|
|
11778
11781
|
if (cmd.type === "restart") {
|
|
11779
11782
|
logger.info("cohort-sync: restart command, terminating in 500ms");
|
|
@@ -11806,41 +11809,7 @@ async function executeCommand(cmd, gwClient, cfg, resolveAgentName, logger) {
|
|
|
11806
11809
|
});
|
|
11807
11810
|
break;
|
|
11808
11811
|
case "cronRunNow": {
|
|
11809
|
-
|
|
11810
|
-
"cron.run",
|
|
11811
|
-
{ jobId: cmd.payload?.jobId }
|
|
11812
|
-
);
|
|
11813
|
-
if (runResult?.ok && runResult?.ran) {
|
|
11814
|
-
const jobId = cmd.payload?.jobId;
|
|
11815
|
-
let polls = 0;
|
|
11816
|
-
if (cronRunNowPoll) clearInterval(cronRunNowPoll);
|
|
11817
|
-
const pollInterval = setInterval(async () => {
|
|
11818
|
-
polls++;
|
|
11819
|
-
if (polls >= 15) {
|
|
11820
|
-
clearInterval(pollInterval);
|
|
11821
|
-
cronRunNowPoll = null;
|
|
11822
|
-
return;
|
|
11823
|
-
}
|
|
11824
|
-
try {
|
|
11825
|
-
if (!gwClient || !gwClient.isAlive()) {
|
|
11826
|
-
clearInterval(pollInterval);
|
|
11827
|
-
cronRunNowPoll = null;
|
|
11828
|
-
return;
|
|
11829
|
-
}
|
|
11830
|
-
const pollResult = await gwClient.request("cron.list");
|
|
11831
|
-
const freshJobs = Array.isArray(pollResult) ? pollResult : pollResult?.jobs ?? [];
|
|
11832
|
-
const job = freshJobs.find((j) => j.id === jobId);
|
|
11833
|
-
if (job && !job.state?.runningAtMs) {
|
|
11834
|
-
clearInterval(pollInterval);
|
|
11835
|
-
cronRunNowPoll = null;
|
|
11836
|
-
const mapped = freshJobs.map((j) => mapCronJob(j, resolveAgentName));
|
|
11837
|
-
await pushCronSnapshot(cfg.apiKey, mapped);
|
|
11838
|
-
}
|
|
11839
|
-
} catch {
|
|
11840
|
-
}
|
|
11841
|
-
}, 2e3);
|
|
11842
|
-
cronRunNowPoll = pollInterval;
|
|
11843
|
-
}
|
|
11812
|
+
await gwClient.request("cron.run", { jobId: cmd.payload?.jobId });
|
|
11844
11813
|
break;
|
|
11845
11814
|
}
|
|
11846
11815
|
case "cronCreate": {
|
|
@@ -11875,7 +11844,7 @@ async function executeCommand(cmd, gwClient, cfg, resolveAgentName, logger) {
|
|
|
11875
11844
|
}
|
|
11876
11845
|
if (gwClient.isAlive()) {
|
|
11877
11846
|
try {
|
|
11878
|
-
const snapResult = await gwClient.request("cron.list");
|
|
11847
|
+
const snapResult = await gwClient.request("cron.list", { includeDisabled: true });
|
|
11879
11848
|
const freshJobs = Array.isArray(snapResult) ? snapResult : snapResult?.jobs ?? [];
|
|
11880
11849
|
const mapped = freshJobs.map((j) => mapCronJob(j, resolveAgentName));
|
|
11881
11850
|
await pushCronSnapshot(cfg.apiKey, mapped);
|
|
@@ -11889,7 +11858,14 @@ async function executeCommand(cmd, gwClient, cfg, resolveAgentName, logger) {
|
|
|
11889
11858
|
}
|
|
11890
11859
|
|
|
11891
11860
|
// src/convex-bridge.ts
|
|
11861
|
+
function hashApiKey(key) {
|
|
11862
|
+
return createHash("sha256").update(key).digest("hex");
|
|
11863
|
+
}
|
|
11892
11864
|
function deriveConvexUrl(apiUrl) {
|
|
11865
|
+
const normalized = apiUrl.replace(/\/+$/, "");
|
|
11866
|
+
if (/^https?:\/\/api\.cohort\.bot$/i.test(normalized)) {
|
|
11867
|
+
return normalized.replace(/api\.cohort\.bot$/i, "ws.cohort.bot");
|
|
11868
|
+
}
|
|
11893
11869
|
return apiUrl.replace(/\.convex\.site\/?$/, ".convex.cloud");
|
|
11894
11870
|
}
|
|
11895
11871
|
var savedLogger = null;
|
|
@@ -11953,7 +11929,7 @@ async function pushTelemetry(apiKey, data) {
|
|
|
11953
11929
|
const c = getClient();
|
|
11954
11930
|
if (!c) return;
|
|
11955
11931
|
try {
|
|
11956
|
-
await c.mutation(upsertTelemetryFromPlugin, { apiKey, ...data });
|
|
11932
|
+
await c.mutation(upsertTelemetryFromPlugin, { apiKeyHash: hashApiKey(apiKey), ...data });
|
|
11957
11933
|
} catch (err) {
|
|
11958
11934
|
getLogger().error(`cohort-sync: pushTelemetry failed: ${err}`);
|
|
11959
11935
|
}
|
|
@@ -11962,7 +11938,7 @@ async function pushSessions(apiKey, agentName, sessions) {
|
|
|
11962
11938
|
const c = getClient();
|
|
11963
11939
|
if (!c) return;
|
|
11964
11940
|
try {
|
|
11965
|
-
await c.mutation(upsertSessionsFromPlugin, { apiKey, agentName, sessions });
|
|
11941
|
+
await c.mutation(upsertSessionsFromPlugin, { apiKeyHash: hashApiKey(apiKey), agentName, sessions });
|
|
11966
11942
|
} catch (err) {
|
|
11967
11943
|
getLogger().error(`cohort-sync: pushSessions failed: ${err}`);
|
|
11968
11944
|
}
|
|
@@ -11972,7 +11948,7 @@ async function pushActivity(apiKey, entries) {
|
|
|
11972
11948
|
const c = getClient();
|
|
11973
11949
|
if (!c) return;
|
|
11974
11950
|
try {
|
|
11975
|
-
await c.mutation(pushActivityFromPluginRef, { apiKey, entries });
|
|
11951
|
+
await c.mutation(pushActivityFromPluginRef, { apiKeyHash: hashApiKey(apiKey), entries });
|
|
11976
11952
|
} catch (err) {
|
|
11977
11953
|
getLogger().error(`cohort-sync: pushActivity failed: ${err}`);
|
|
11978
11954
|
}
|
|
@@ -11981,7 +11957,7 @@ async function pushCronSnapshot(apiKey, jobs) {
|
|
|
11981
11957
|
const c = getClient();
|
|
11982
11958
|
if (!c) return false;
|
|
11983
11959
|
try {
|
|
11984
|
-
await c.mutation(upsertCronSnapshotFromPluginRef, { apiKey, jobs });
|
|
11960
|
+
await c.mutation(upsertCronSnapshotFromPluginRef, { apiKeyHash: hashApiKey(apiKey), jobs });
|
|
11985
11961
|
return true;
|
|
11986
11962
|
} catch (err) {
|
|
11987
11963
|
getLogger().error(`cohort-sync: pushCronSnapshot failed: ${err}`);
|
|
@@ -11994,7 +11970,7 @@ async function callAddCommentFromPlugin(apiKey, args) {
|
|
|
11994
11970
|
throw new Error("Convex client not initialized \u2014 subscription may not be active");
|
|
11995
11971
|
}
|
|
11996
11972
|
return await c.mutation(addCommentFromPluginRef, {
|
|
11997
|
-
apiKey,
|
|
11973
|
+
apiKeyHash: hashApiKey(apiKey),
|
|
11998
11974
|
taskNumber: args.taskNumber,
|
|
11999
11975
|
agentName: args.agentName,
|
|
12000
11976
|
content: args.content,
|
|
@@ -12097,9 +12073,10 @@ async function startNotificationSubscription(port, cfg, hooksToken, logger) {
|
|
|
12097
12073
|
const openclawAgentId = reverseNameMap[agentName] ?? agentName;
|
|
12098
12074
|
logger.info(`cohort-sync: subscribing to notifications for agent "${agentName}" (openclawId: "${openclawAgentId}")`);
|
|
12099
12075
|
let processing = false;
|
|
12076
|
+
const apiKeyHash = hashApiKey(cfg.apiKey);
|
|
12100
12077
|
const unsubscribe = c.onUpdate(
|
|
12101
12078
|
getUndeliveredForPlugin,
|
|
12102
|
-
{ agent: agentName,
|
|
12079
|
+
{ agent: agentName, apiKeyHash },
|
|
12103
12080
|
async (notifications) => {
|
|
12104
12081
|
if (processing) return;
|
|
12105
12082
|
processing = true;
|
|
@@ -12110,7 +12087,7 @@ async function startNotificationSubscription(port, cfg, hooksToken, logger) {
|
|
|
12110
12087
|
logger.info(`cohort-sync: injected notification for task #${n.taskNumber} (${agentName})`);
|
|
12111
12088
|
await c.mutation(markDeliveredByPlugin, {
|
|
12112
12089
|
notificationId: n._id,
|
|
12113
|
-
|
|
12090
|
+
apiKeyHash
|
|
12114
12091
|
});
|
|
12115
12092
|
} catch (err) {
|
|
12116
12093
|
logger.warn(`cohort-sync: failed to inject notification ${n._id}: ${String(err)}`);
|
|
@@ -12134,9 +12111,10 @@ function startCommandSubscription(cfg, logger, resolveAgentName, gwClient) {
|
|
|
12134
12111
|
return null;
|
|
12135
12112
|
}
|
|
12136
12113
|
let processing = false;
|
|
12114
|
+
const apiKeyHash = hashApiKey(cfg.apiKey);
|
|
12137
12115
|
const unsubscribe = c.onUpdate(
|
|
12138
12116
|
getPendingCommandsForPlugin,
|
|
12139
|
-
{
|
|
12117
|
+
{ apiKeyHash },
|
|
12140
12118
|
async (commands) => {
|
|
12141
12119
|
if (processing) return;
|
|
12142
12120
|
if (commands.length === 0) return;
|
|
@@ -12147,7 +12125,7 @@ function startCommandSubscription(cfg, logger, resolveAgentName, gwClient) {
|
|
|
12147
12125
|
try {
|
|
12148
12126
|
await c.mutation(acknowledgeCommandRef, {
|
|
12149
12127
|
commandId: cmd._id,
|
|
12150
|
-
|
|
12128
|
+
apiKeyHash
|
|
12151
12129
|
});
|
|
12152
12130
|
await executeCommand(cmd, gwClient, cfg, resolveAgentName, logger);
|
|
12153
12131
|
if (cmd.type === "restart") return;
|
|
@@ -12156,7 +12134,7 @@ function startCommandSubscription(cfg, logger, resolveAgentName, gwClient) {
|
|
|
12156
12134
|
try {
|
|
12157
12135
|
await c.mutation(failCommandRef, {
|
|
12158
12136
|
commandId: cmd._id,
|
|
12159
|
-
|
|
12137
|
+
apiKeyHash,
|
|
12160
12138
|
reason: String(err).slice(0, 500)
|
|
12161
12139
|
});
|
|
12162
12140
|
} catch (failErr) {
|
|
@@ -12302,7 +12280,7 @@ function buildConnectFrame(id, token, pluginVersion, identity, nonce) {
|
|
|
12302
12280
|
clientId: "gateway-client",
|
|
12303
12281
|
clientMode: "backend",
|
|
12304
12282
|
role: "operator",
|
|
12305
|
-
scopes: ["operator.read", "operator.write"],
|
|
12283
|
+
scopes: ["operator.read", "operator.write", "operator.admin"],
|
|
12306
12284
|
signedAtMs,
|
|
12307
12285
|
token,
|
|
12308
12286
|
nonce,
|
|
@@ -12324,7 +12302,7 @@ function buildConnectFrame(id, token, pluginVersion, identity, nonce) {
|
|
|
12324
12302
|
mode: "backend"
|
|
12325
12303
|
},
|
|
12326
12304
|
role: "operator",
|
|
12327
|
-
scopes: ["operator.read", "operator.write"],
|
|
12305
|
+
scopes: ["operator.read", "operator.write", "operator.admin"],
|
|
12328
12306
|
auth: { token },
|
|
12329
12307
|
device: {
|
|
12330
12308
|
id: identity.deviceId,
|
|
@@ -13495,37 +13473,35 @@ async function fetchAgentContext(apiKey, apiUrl, logger) {
|
|
|
13495
13473
|
return POCKET_GUIDE;
|
|
13496
13474
|
}
|
|
13497
13475
|
}
|
|
13498
|
-
|
|
13476
|
+
function initGatewayClient(port, token, cfg, resolveAgentName, logger) {
|
|
13499
13477
|
const client2 = new GatewayClient(port, token, logger, PLUGIN_VERSION);
|
|
13500
|
-
await client2.connect();
|
|
13501
13478
|
persistentGwClient = client2;
|
|
13502
13479
|
gwClientInitialized = true;
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
diag("GW_CLIENT_SHUTDOWN_EVENT", {});
|
|
13507
|
-
logger.info("cohort-sync: gateway shutdown event received");
|
|
13508
|
-
});
|
|
13509
|
-
}
|
|
13510
|
-
client2.onReconnect = async () => {
|
|
13511
|
-
diag("GW_CLIENT_RECONNECTED_RESUBSCRIBE", {});
|
|
13480
|
+
const onConnected = async () => {
|
|
13481
|
+
diag("GW_CLIENT_CONNECTED", { methods: client2.availableMethods.size, events: client2.availableEvents.size });
|
|
13482
|
+
logger.info(`cohort-sync: gateway client connected (methods=${client2.availableMethods.size}, events=${client2.availableEvents.size})`);
|
|
13512
13483
|
registerCronEventHandlers(client2, cfg, resolveAgentName);
|
|
13484
|
+
if (client2.availableEvents.has("shutdown")) {
|
|
13485
|
+
client2.on("shutdown", () => {
|
|
13486
|
+
diag("GW_CLIENT_SHUTDOWN_EVENT", {});
|
|
13487
|
+
logger.info("cohort-sync: gateway shutdown event received");
|
|
13488
|
+
});
|
|
13489
|
+
}
|
|
13513
13490
|
try {
|
|
13514
|
-
const
|
|
13515
|
-
const
|
|
13516
|
-
const
|
|
13517
|
-
await pushCronSnapshot(cfg.apiKey,
|
|
13518
|
-
diag("
|
|
13491
|
+
const cronResult = await client2.request("cron.list", { includeDisabled: true });
|
|
13492
|
+
const jobs = Array.isArray(cronResult) ? cronResult : cronResult?.jobs ?? [];
|
|
13493
|
+
const mapped = jobs.map((j) => mapCronJob(j, resolveAgentName));
|
|
13494
|
+
await pushCronSnapshot(cfg.apiKey, mapped);
|
|
13495
|
+
diag("GW_CLIENT_CRON_PUSH", { count: mapped.length });
|
|
13519
13496
|
} catch (err) {
|
|
13520
|
-
diag("
|
|
13497
|
+
diag("GW_CLIENT_CRON_PUSH_FAILED", { error: String(err) });
|
|
13521
13498
|
}
|
|
13522
13499
|
};
|
|
13523
|
-
|
|
13524
|
-
|
|
13525
|
-
|
|
13526
|
-
|
|
13527
|
-
|
|
13528
|
-
diag("GW_CLIENT_INITIAL_CRON_PUSH", { count: mapped.length });
|
|
13500
|
+
client2.onReconnect = onConnected;
|
|
13501
|
+
client2.connect().then(() => onConnected()).catch((err) => {
|
|
13502
|
+
diag("GW_CLIENT_INITIAL_CONNECT_DEFERRED", { error: String(err) });
|
|
13503
|
+
logger.warn(`cohort-sync: GW connect will retry: ${String(err)}`);
|
|
13504
|
+
});
|
|
13529
13505
|
}
|
|
13530
13506
|
function registerHooks(api, cfg) {
|
|
13531
13507
|
STATE_FILE_PATH = path3.join(cfg.stateDir, "session-state.json");
|
|
@@ -13535,6 +13511,12 @@ function registerHooks(api, cfg) {
|
|
|
13535
13511
|
const convexUrl = cfg.convexUrl ?? deriveConvexUrl(cfg.apiUrl);
|
|
13536
13512
|
createClient(convexUrl);
|
|
13537
13513
|
setLogger(logger);
|
|
13514
|
+
gatewayPort = api.config?.gateway?.port ?? null;
|
|
13515
|
+
gatewayToken = resolveGatewayToken(api);
|
|
13516
|
+
if (gatewayPort && gatewayToken) {
|
|
13517
|
+
initGatewayClient(gatewayPort, gatewayToken, cfg, resolveAgentName, logger);
|
|
13518
|
+
}
|
|
13519
|
+
const cronStorePath = api.config?.cron?.store ?? path3.join(os3.homedir(), ".openclaw", "cron", "jobs.json");
|
|
13538
13520
|
logger.info(`cohort-sync: registerHooks v${PLUGIN_VERSION}`);
|
|
13539
13521
|
diag("REGISTER_HOOKS", {
|
|
13540
13522
|
PLUGIN_VERSION,
|
|
@@ -13873,6 +13855,19 @@ Do not attempt to make more comments until ${resetAt}.`
|
|
|
13873
13855
|
tracker2.markTelemetryPushed(agentName);
|
|
13874
13856
|
}
|
|
13875
13857
|
}
|
|
13858
|
+
const sessionKey = ctx.sessionKey;
|
|
13859
|
+
if (sessionKey && sessionKey.includes(":cron:")) {
|
|
13860
|
+
try {
|
|
13861
|
+
const raw = fs3.readFileSync(cronStorePath, "utf8");
|
|
13862
|
+
const store = JSON.parse(raw);
|
|
13863
|
+
const jobs = store.jobs ?? [];
|
|
13864
|
+
const mapped = jobs.map((j) => mapCronJob(j, resolveAgentName));
|
|
13865
|
+
await pushCronSnapshot(cfg.apiKey, mapped);
|
|
13866
|
+
diag("CRON_AGENT_END_PUSH", { count: mapped.length, sessionKey });
|
|
13867
|
+
} catch (err) {
|
|
13868
|
+
diag("CRON_AGENT_END_PUSH_FAILED", { error: String(err) });
|
|
13869
|
+
}
|
|
13870
|
+
}
|
|
13876
13871
|
if (event.success === false) {
|
|
13877
13872
|
const entry = buildActivityEntry(agentName, "agent_end", {
|
|
13878
13873
|
success: false,
|
|
@@ -14352,14 +14347,19 @@ function registerCohortCli(ctx, cfg) {
|
|
|
14352
14347
|
|
|
14353
14348
|
// index.ts
|
|
14354
14349
|
init_keychain();
|
|
14355
|
-
var DEFAULT_API_URL = "https://fortunate-chipmunk-286.convex.site";
|
|
14356
14350
|
var plugin = {
|
|
14357
14351
|
id: "cohort-sync",
|
|
14358
14352
|
name: "Cohort Sync",
|
|
14359
14353
|
description: "Syncs agent status and skills to Cohort dashboard",
|
|
14360
14354
|
register(api) {
|
|
14361
14355
|
const cfg = api.pluginConfig;
|
|
14362
|
-
const apiUrl = cfg?.apiUrl
|
|
14356
|
+
const apiUrl = cfg?.apiUrl;
|
|
14357
|
+
if (!apiUrl) {
|
|
14358
|
+
api.logger.error(
|
|
14359
|
+
"cohort-sync: apiUrl is required in plugin config \u2014 set it in your OpenClaw configuration"
|
|
14360
|
+
);
|
|
14361
|
+
return;
|
|
14362
|
+
}
|
|
14363
14363
|
api.registerCli(
|
|
14364
14364
|
(ctx) => registerCohortCli(ctx, {
|
|
14365
14365
|
apiUrl,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"uiHints": {
|
|
4
4
|
"apiUrl": {
|
|
5
5
|
"label": "Cohort API URL",
|
|
6
|
-
"placeholder": "https://
|
|
6
|
+
"placeholder": "https://api.cohort.bot",
|
|
7
7
|
"help": "Base URL for the Cohort telemetry API"
|
|
8
8
|
},
|
|
9
9
|
"apiKey": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"convexUrl": {
|
|
27
27
|
"label": "Convex WebSocket URL",
|
|
28
|
-
"placeholder": "https://
|
|
28
|
+
"placeholder": "https://ws.cohort.bot",
|
|
29
29
|
"advanced": true,
|
|
30
30
|
"help": "Override the auto-derived Convex WebSocket URL (rarely needed)"
|
|
31
31
|
}
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
|
-
"version": "0.8.
|
|
57
|
+
"version": "0.8.1"
|
|
58
58
|
}
|
package/dist/package.json
CHANGED