@cfio/cohort-sync 0.34.4 → 0.34.5
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 +70 -19
- package/dist/openclaw.plugin.json +1 -1
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2826,7 +2826,7 @@ async function markAllUnreachable(cfg, logger) {
|
|
|
2826
2826
|
}
|
|
2827
2827
|
logger.info("cohort-sync: all agents marked unreachable");
|
|
2828
2828
|
}
|
|
2829
|
-
var MAX_SKILL_BYTES =
|
|
2829
|
+
var MAX_SKILL_BYTES = 256 * 1024;
|
|
2830
2830
|
var MAX_SYNC_SKILLS = 500;
|
|
2831
2831
|
function parseSkillFrontmatter(text) {
|
|
2832
2832
|
if (!text) return null;
|
|
@@ -2862,7 +2862,7 @@ function stripScalar(value) {
|
|
|
2862
2862
|
}
|
|
2863
2863
|
return v2;
|
|
2864
2864
|
}
|
|
2865
|
-
function enumerateSkills(
|
|
2865
|
+
function enumerateSkills(skillsDir2, source = "hermes") {
|
|
2866
2866
|
const byName = /* @__PURE__ */ new Map();
|
|
2867
2867
|
const visit = (dir) => {
|
|
2868
2868
|
let entries;
|
|
@@ -2893,15 +2893,44 @@ function enumerateSkills(skillsDir, source = "hermes") {
|
|
|
2893
2893
|
const parsed = parseSkillFrontmatter(text);
|
|
2894
2894
|
if (!parsed) continue;
|
|
2895
2895
|
if (byName.has(parsed.name)) continue;
|
|
2896
|
-
byName.set(parsed.name, {
|
|
2896
|
+
byName.set(parsed.name, {
|
|
2897
|
+
name: parsed.name,
|
|
2898
|
+
description: parsed.description,
|
|
2899
|
+
source,
|
|
2900
|
+
body: text,
|
|
2901
|
+
location: path.relative(skillsDir2, full)
|
|
2902
|
+
});
|
|
2897
2903
|
}
|
|
2898
2904
|
};
|
|
2899
|
-
visit(
|
|
2905
|
+
visit(skillsDir2);
|
|
2900
2906
|
return [...byName.values()];
|
|
2901
2907
|
}
|
|
2902
|
-
function
|
|
2908
|
+
function writeSkillBody(skillsDir2, location, body) {
|
|
2909
|
+
if (!skillsDir2) {
|
|
2910
|
+
throw new Error("skillsDir is required for skill writeback");
|
|
2911
|
+
}
|
|
2912
|
+
if (!location || path.isAbsolute(location) || location.split(/[\\/]+/).includes("..")) {
|
|
2913
|
+
throw new Error("Invalid skill location");
|
|
2914
|
+
}
|
|
2915
|
+
if (path.basename(location) !== "SKILL.md") {
|
|
2916
|
+
throw new Error("Skill location must end with SKILL.md");
|
|
2917
|
+
}
|
|
2918
|
+
if (body.length > MAX_SKILL_BYTES) {
|
|
2919
|
+
throw new Error(`Skill body exceeds maximum length of ${MAX_SKILL_BYTES} characters`);
|
|
2920
|
+
}
|
|
2921
|
+
const root = path.resolve(skillsDir2);
|
|
2922
|
+
const target = path.resolve(root, location);
|
|
2923
|
+
const relative = path.relative(root, target);
|
|
2924
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
2925
|
+
throw new Error("Skill location escapes skills directory");
|
|
2926
|
+
}
|
|
2927
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
2928
|
+
fs.writeFileSync(target, body, "utf8");
|
|
2929
|
+
return target;
|
|
2930
|
+
}
|
|
2931
|
+
function skillsDirExists(skillsDir2) {
|
|
2903
2932
|
try {
|
|
2904
|
-
return fs.statSync(
|
|
2933
|
+
return fs.statSync(skillsDir2).isDirectory();
|
|
2905
2934
|
} catch {
|
|
2906
2935
|
return false;
|
|
2907
2936
|
}
|
|
@@ -2913,7 +2942,7 @@ async function syncSkills(agentName, skills, cfg, logger) {
|
|
|
2913
2942
|
}
|
|
2914
2943
|
await v1Post(cfg.apiUrl, cfg.apiKey, "/api/v1/skills/sync", { agentName, skills: capped });
|
|
2915
2944
|
}
|
|
2916
|
-
async function fullSync(agentName, model, cfg, logger, openClawAgents,
|
|
2945
|
+
async function fullSync(agentName, model, cfg, logger, openClawAgents, skillsDir2) {
|
|
2917
2946
|
logger.info("cohort-sync: full sync starting");
|
|
2918
2947
|
if (openClawAgents && openClawAgents.length > 0) {
|
|
2919
2948
|
try {
|
|
@@ -2924,14 +2953,14 @@ async function fullSync(agentName, model, cfg, logger, openClawAgents, skillsDir
|
|
|
2924
2953
|
} else {
|
|
2925
2954
|
await syncAgentStatus(agentName, "working", model, cfg, logger);
|
|
2926
2955
|
}
|
|
2927
|
-
if (
|
|
2956
|
+
if (skillsDir2) {
|
|
2928
2957
|
try {
|
|
2929
|
-
if (!skillsDirExists(
|
|
2930
|
-
logger.info(`cohort-sync: skill sync skipped (skills dir missing or unreadable: ${
|
|
2958
|
+
if (!skillsDirExists(skillsDir2)) {
|
|
2959
|
+
logger.info(`cohort-sync: skill sync skipped (skills dir missing or unreadable: ${skillsDir2})`);
|
|
2931
2960
|
} else {
|
|
2932
|
-
const skills = enumerateSkills(
|
|
2961
|
+
const skills = enumerateSkills(skillsDir2, "openclaw");
|
|
2933
2962
|
await syncSkills(agentName, skills, cfg, logger);
|
|
2934
|
-
logger.info(`cohort-sync: synced ${skills.length} skill(s) from ${
|
|
2963
|
+
logger.info(`cohort-sync: synced ${skills.length} skill(s) from ${skillsDir2}`);
|
|
2935
2964
|
}
|
|
2936
2965
|
} catch (err) {
|
|
2937
2966
|
logger.warn(`cohort-sync: skill sync failed (non-fatal): ${String(err)}`);
|
|
@@ -11892,6 +11921,27 @@ async function executeCommand(cmd, gwClient, cfg, resolveAgentName, logger, cron
|
|
|
11892
11921
|
});
|
|
11893
11922
|
return;
|
|
11894
11923
|
}
|
|
11924
|
+
if (cmd.type === "skillWrite") {
|
|
11925
|
+
const skillsDir2 = injection?.skillsDir;
|
|
11926
|
+
const agentName = cmd.payload?.agentId;
|
|
11927
|
+
const location = cmd.payload?.location;
|
|
11928
|
+
const body = cmd.payload?.skillBody;
|
|
11929
|
+
if (!skillsDir2) {
|
|
11930
|
+
throw new Error("skillsDir is required for skillWrite");
|
|
11931
|
+
}
|
|
11932
|
+
if (!agentName) {
|
|
11933
|
+
throw new Error("agentId is required for skillWrite");
|
|
11934
|
+
}
|
|
11935
|
+
if (!location) {
|
|
11936
|
+
throw new Error("location is required for skillWrite");
|
|
11937
|
+
}
|
|
11938
|
+
if (typeof body !== "string") {
|
|
11939
|
+
throw new Error("skillBody is required for skillWrite");
|
|
11940
|
+
}
|
|
11941
|
+
writeSkillBody(skillsDir2, location, body);
|
|
11942
|
+
await syncSkills(agentName, enumerateSkills(skillsDir2, "openclaw"), cfg, logger);
|
|
11943
|
+
return;
|
|
11944
|
+
}
|
|
11895
11945
|
if (cmd.type.startsWith("cron")) {
|
|
11896
11946
|
if (!gwClient || !gwClient.isAlive()) {
|
|
11897
11947
|
logger.warn(`cohort-sync: no gateway client, cannot execute ${cmd.type}`);
|
|
@@ -14266,7 +14316,7 @@ function dumpEvent(event) {
|
|
|
14266
14316
|
function positiveNumber(value) {
|
|
14267
14317
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
14268
14318
|
}
|
|
14269
|
-
var PLUGIN_VERSION = true ? "0.34.
|
|
14319
|
+
var PLUGIN_VERSION = true ? "0.34.5" : "unknown";
|
|
14270
14320
|
var PRESENCE_PING_INTERVAL_MS = 12e4;
|
|
14271
14321
|
function resolveGatewayToken(api) {
|
|
14272
14322
|
const token2 = api.config?.gateway?.auth?.token;
|
|
@@ -14444,7 +14494,7 @@ async function handleGatewayStart(event, state) {
|
|
|
14444
14494
|
if (!state) {
|
|
14445
14495
|
return;
|
|
14446
14496
|
}
|
|
14447
|
-
const { cfg, tracker, logger, config, api } = state;
|
|
14497
|
+
const { cfg, tracker, logger, config, api, skillsDir: skillsDir2 } = state;
|
|
14448
14498
|
try {
|
|
14449
14499
|
const latestVersion = await checkForUpdate(PLUGIN_VERSION, logger);
|
|
14450
14500
|
if (latestVersion) {
|
|
@@ -14471,14 +14521,13 @@ async function handleGatewayStart(event, state) {
|
|
|
14471
14521
|
model: state.resolveModel(a.id),
|
|
14472
14522
|
identity: resolveIdentity(a.identity, a.workspace)
|
|
14473
14523
|
}));
|
|
14474
|
-
const skillsDir = api.config?.skills?.dir ?? path3.join(os2.homedir(), ".openclaw", "skills");
|
|
14475
14524
|
await fullSync(
|
|
14476
14525
|
state.resolveAgentName("main"),
|
|
14477
14526
|
state.resolveModel("main"),
|
|
14478
14527
|
cfg,
|
|
14479
14528
|
logger,
|
|
14480
14529
|
agentList,
|
|
14481
|
-
|
|
14530
|
+
skillsDir2
|
|
14482
14531
|
);
|
|
14483
14532
|
} catch (err) {
|
|
14484
14533
|
logger.error(`cohort-sync: gateway_start sync failed: ${String(err)}`);
|
|
@@ -14512,7 +14561,7 @@ async function handleGatewayStart(event, state) {
|
|
|
14512
14561
|
state.resolveAgentName,
|
|
14513
14562
|
state.persistentGwClient,
|
|
14514
14563
|
state.cronTimestampTracker,
|
|
14515
|
-
{ port: state.gatewayPort, hooksToken }
|
|
14564
|
+
{ port: state.gatewayPort, hooksToken, skillsDir: skillsDir2 }
|
|
14516
14565
|
);
|
|
14517
14566
|
state.commandUnsubscriber = unsub;
|
|
14518
14567
|
} catch (err) {
|
|
@@ -14860,7 +14909,7 @@ function registerHookHandlers(api, logger, getState) {
|
|
|
14860
14909
|
state.resolveAgentName,
|
|
14861
14910
|
state.persistentGwClient,
|
|
14862
14911
|
state.cronTimestampTracker,
|
|
14863
|
-
{ port: state.gatewayPort, hooksToken: state.gatewayToken }
|
|
14912
|
+
{ port: state.gatewayPort, hooksToken: state.gatewayToken, skillsDir }
|
|
14864
14913
|
);
|
|
14865
14914
|
state.commandUnsubscriber = unsub;
|
|
14866
14915
|
} catch (err) {
|
|
@@ -15173,6 +15222,7 @@ function initializeHookState(api, cfg) {
|
|
|
15173
15222
|
const gatewayPort = api.config?.gateway?.port ?? null;
|
|
15174
15223
|
const gatewayToken = resolveGatewayToken(api);
|
|
15175
15224
|
const hooksToken = resolveHooksToken(api);
|
|
15225
|
+
const skillsDir2 = api.config?.skills?.dir ?? path3.join(os2.homedir(), ".openclaw", "skills");
|
|
15176
15226
|
const cronTimestampTracker = new CronTimestampTracker();
|
|
15177
15227
|
const cronRunStarts = /* @__PURE__ */ new Map();
|
|
15178
15228
|
let persistentGwClient = null;
|
|
@@ -15188,7 +15238,7 @@ function initializeHookState(api, cfg) {
|
|
|
15188
15238
|
resolveAgentName,
|
|
15189
15239
|
persistentGwClient,
|
|
15190
15240
|
cronTimestampTracker,
|
|
15191
|
-
{ port: gatewayPort, hooksToken }
|
|
15241
|
+
{ port: gatewayPort, hooksToken, skillsDir: skillsDir2 }
|
|
15192
15242
|
);
|
|
15193
15243
|
setToolRuntime({
|
|
15194
15244
|
apiKey: cfg.apiKey,
|
|
@@ -15233,6 +15283,7 @@ function initializeHookState(api, cfg) {
|
|
|
15233
15283
|
getModelContextLimit: getModelContextLimit2,
|
|
15234
15284
|
activityBatch,
|
|
15235
15285
|
cronStorePath,
|
|
15286
|
+
skillsDir: skillsDir2,
|
|
15236
15287
|
stateFilePath,
|
|
15237
15288
|
gatewayPort,
|
|
15238
15289
|
gatewayToken,
|
package/dist/package.json
CHANGED
package/package.json
CHANGED