@gendigital/sage-openclaw 0.13.0 → 0.14.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/dist/index.cjs +183 -74
- package/dist/index.cjs.map +4 -4
- package/dist/mcp-server.cjs +385 -90
- package/dist/mcp-server.cjs.map +4 -4
- package/dist/model-download-worker.cjs +1 -1
- package/dist/model-download-worker.cjs.map +2 -2
- package/dist/skill-upload-worker.cjs +129 -42
- package/dist/skill-upload-worker.cjs.map +4 -4
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -3
- package/resources/skills/security-awareness/SKILL.md +2 -2
package/dist/index.cjs
CHANGED
|
@@ -14500,6 +14500,84 @@ function buildContentSnapshot(toolType, toolInput, artifacts = [], signals = {})
|
|
|
14500
14500
|
return content;
|
|
14501
14501
|
}
|
|
14502
14502
|
|
|
14503
|
+
// ../core/dist/detection-names.js
|
|
14504
|
+
var PI_DETECTION_NAME = "Other:SagePromptInjectionML-A [Susp]";
|
|
14505
|
+
var REPORTING_ENGINE_SHORTHANDS = {
|
|
14506
|
+
package: "sgpk",
|
|
14507
|
+
amsi: "sgam",
|
|
14508
|
+
heuristics: "sghe",
|
|
14509
|
+
ml: "sgml",
|
|
14510
|
+
skill: "skan"
|
|
14511
|
+
};
|
|
14512
|
+
var REPORTING_DETECTION_SUFFIX = "sage";
|
|
14513
|
+
function formatReportingDetectionName(canonicalName, engine, optionalData = "") {
|
|
14514
|
+
const engineMetadata = optionalData ? `${REPORTING_ENGINE_SHORTHANDS[engine]}:${optionalData}` : REPORTING_ENGINE_SHORTHANDS[engine];
|
|
14515
|
+
return `${canonicalName}|${engineMetadata}|${REPORTING_DETECTION_SUFFIX}`;
|
|
14516
|
+
}
|
|
14517
|
+
var PACKAGE_DETECTION_NAMES = {
|
|
14518
|
+
not_found: "Other:SagePackageNotFound-A [Susp]",
|
|
14519
|
+
suspicious_age: "Other:SagePackageNew-A [Susp]",
|
|
14520
|
+
malicious: "Other:SagePackageMalicious-A [Trj]",
|
|
14521
|
+
unknown: "Other:SagePackageUnknown-A [Susp]"
|
|
14522
|
+
};
|
|
14523
|
+
var AMSI_DETECTION_NAMES = {
|
|
14524
|
+
detected: "Other:SageAmsiDetected-A [Heur]",
|
|
14525
|
+
blocked_by_admin: "Other:SageAmsiBlockedByAdmin-A [Heur]",
|
|
14526
|
+
unknown: "Other:SageAmsiUnknown-A [Susp]"
|
|
14527
|
+
};
|
|
14528
|
+
var AMSI_REPORTING_RULE_NAMES = {
|
|
14529
|
+
detected: "AMSI_DETECTED",
|
|
14530
|
+
blocked_by_admin: "AMSI_BLOCKED_BY_ADMIN",
|
|
14531
|
+
unknown: "AMSI_UNKNOWN"
|
|
14532
|
+
};
|
|
14533
|
+
var SKILL_DETECTION_NAMES = {
|
|
14534
|
+
HIGH: "Other:SageSuspiciousSkill-A [Susp]",
|
|
14535
|
+
CRITICAL: "Other:SageMaliciousSkill-A [Trj]"
|
|
14536
|
+
};
|
|
14537
|
+
function isCanonicalDetectionName(name) {
|
|
14538
|
+
return /^\w+:\w+-[A-Z]+ \[[^\]\r\n]+\]$/.test(name);
|
|
14539
|
+
}
|
|
14540
|
+
function packageDetectionName(verdict) {
|
|
14541
|
+
return PACKAGE_DETECTION_NAMES[verdict];
|
|
14542
|
+
}
|
|
14543
|
+
function amsiDetectionClass(amsiResult) {
|
|
14544
|
+
if (amsiResult >= 32768)
|
|
14545
|
+
return "detected";
|
|
14546
|
+
if (amsiResult >= 16384)
|
|
14547
|
+
return "blocked_by_admin";
|
|
14548
|
+
return "unknown";
|
|
14549
|
+
}
|
|
14550
|
+
function amsiDetectionName(amsiResult) {
|
|
14551
|
+
return AMSI_DETECTION_NAMES[amsiDetectionClass(amsiResult)];
|
|
14552
|
+
}
|
|
14553
|
+
function amsiReportingData(amsiResult) {
|
|
14554
|
+
const ruleName = AMSI_REPORTING_RULE_NAMES[amsiDetectionClass(amsiResult)];
|
|
14555
|
+
return `${ruleName}:${Math.trunc(amsiResult).toString(16)}`;
|
|
14556
|
+
}
|
|
14557
|
+
function skillDetectionName(verdict) {
|
|
14558
|
+
return SKILL_DETECTION_NAMES[verdict.toUpperCase()];
|
|
14559
|
+
}
|
|
14560
|
+
function isSkillId(value) {
|
|
14561
|
+
return /^[0-9a-f]{64}$/i.test(value);
|
|
14562
|
+
}
|
|
14563
|
+
function skillReportingDetectionName(verdict, skillId) {
|
|
14564
|
+
const canonicalName = skillDetectionName(verdict);
|
|
14565
|
+
return canonicalName && isSkillId(skillId) ? formatReportingDetectionName(canonicalName, "skill", skillId.toLowerCase()) : void 0;
|
|
14566
|
+
}
|
|
14567
|
+
function buildSkillCheckSignal(skillId, analyzerVerdict, jobId) {
|
|
14568
|
+
const normalizedSkillId = skillId.toLowerCase();
|
|
14569
|
+
const normalizedVerdict = analyzerVerdict.toUpperCase();
|
|
14570
|
+
const detectionName = skillReportingDetectionName(normalizedVerdict, normalizedSkillId);
|
|
14571
|
+
if (!detectionName)
|
|
14572
|
+
return void 0;
|
|
14573
|
+
return {
|
|
14574
|
+
detection_name: detectionName,
|
|
14575
|
+
skill_id: normalizedSkillId,
|
|
14576
|
+
...jobId ? { job_id: jobId } : {},
|
|
14577
|
+
analyzer_verdict: normalizedVerdict
|
|
14578
|
+
};
|
|
14579
|
+
}
|
|
14580
|
+
|
|
14503
14581
|
// ../core/dist/audit-log.js
|
|
14504
14582
|
init_file_utils();
|
|
14505
14583
|
|
|
@@ -14651,6 +14729,37 @@ async function logSkillQueued(config2, skillId, pluginKey, skillFolder) {
|
|
|
14651
14729
|
} catch {
|
|
14652
14730
|
}
|
|
14653
14731
|
}
|
|
14732
|
+
async function logSkillVerdict(config2, skillId, status, verdict, summary, context = {}) {
|
|
14733
|
+
if (!config2.enabled)
|
|
14734
|
+
return false;
|
|
14735
|
+
const entry = {
|
|
14736
|
+
type: "skill_verdict",
|
|
14737
|
+
entry_id: context.entryId ?? (0, import_node_crypto3.randomUUID)(),
|
|
14738
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14739
|
+
skill_id: skillId,
|
|
14740
|
+
status
|
|
14741
|
+
};
|
|
14742
|
+
if (context.jobId !== void 0)
|
|
14743
|
+
entry.job_id = context.jobId;
|
|
14744
|
+
if (context.agentRuntime !== void 0)
|
|
14745
|
+
entry.agent_runtime = context.agentRuntime;
|
|
14746
|
+
if (verdict !== void 0)
|
|
14747
|
+
entry.verdict = verdict;
|
|
14748
|
+
if (summary !== void 0)
|
|
14749
|
+
entry.summary = summary.slice(0, MAX_SUMMARY_LEN);
|
|
14750
|
+
const skillSignal = status === "analyzed" && verdict !== void 0 ? buildSkillCheckSignal(skillId, verdict, context.jobId) : void 0;
|
|
14751
|
+
if (skillSignal) {
|
|
14752
|
+
entry.signals = {
|
|
14753
|
+
skill_checks: [skillSignal]
|
|
14754
|
+
};
|
|
14755
|
+
}
|
|
14756
|
+
try {
|
|
14757
|
+
await appendEntry(config2, entry);
|
|
14758
|
+
return true;
|
|
14759
|
+
} catch {
|
|
14760
|
+
return false;
|
|
14761
|
+
}
|
|
14762
|
+
}
|
|
14654
14763
|
|
|
14655
14764
|
// ../core/dist/cache.js
|
|
14656
14765
|
init_config();
|
|
@@ -15445,7 +15554,7 @@ init_file_utils();
|
|
|
15445
15554
|
var import_meta = {};
|
|
15446
15555
|
function resolveVersion() {
|
|
15447
15556
|
if (true)
|
|
15448
|
-
return "0.
|
|
15557
|
+
return "0.14.0";
|
|
15449
15558
|
try {
|
|
15450
15559
|
const pkgPath = (0, import_node_path5.join)((0, import_node_path5.dirname)((0, import_node_url.fileURLToPath)(import_meta.url)), "..", "package.json");
|
|
15451
15560
|
const pkg = JSON.parse(getFileContentSync(pkgPath));
|
|
@@ -16303,6 +16412,7 @@ var SkillCheckClient = class {
|
|
|
16303
16412
|
parseResult(skillId, raw) {
|
|
16304
16413
|
return {
|
|
16305
16414
|
skillId,
|
|
16415
|
+
jobId: typeof raw.job_id === "string" ? raw.job_id : void 0,
|
|
16306
16416
|
verdict: typeof raw.verdict === "string" ? raw.verdict : void 0,
|
|
16307
16417
|
summary: typeof raw.summary === "string" ? raw.summary : void 0
|
|
16308
16418
|
};
|
|
@@ -16512,56 +16622,6 @@ function isScannableContent(content) {
|
|
|
16512
16622
|
return SNIFF_HTML.test(head) || SNIFF_HTML_TAGS.test(head) || SNIFF_JSON.test(head) || SNIFF_XML.test(head) || SNIFF_YAML.test(head) || SNIFF_SHEBANG_SHELL.test(head) || SNIFF_SHEBANG_PYTHON.test(head) || SNIFF_PYTHON.test(head) || SNIFF_JS_TS.test(head) || SNIFF_C_CPP.test(head) || SNIFF_KOTLIN.test(head) || SNIFF_CSV.test(head);
|
|
16513
16623
|
}
|
|
16514
16624
|
|
|
16515
|
-
// ../core/dist/detection-names.js
|
|
16516
|
-
var PI_DETECTION_NAME = "Other:SagePromptInjectionML-A [Susp]";
|
|
16517
|
-
var REPORTING_ENGINE_SHORTHANDS = {
|
|
16518
|
-
package: "sgpk",
|
|
16519
|
-
amsi: "sgam",
|
|
16520
|
-
heuristics: "sghe",
|
|
16521
|
-
ml: "sgml"
|
|
16522
|
-
};
|
|
16523
|
-
var REPORTING_DETECTION_SUFFIX = "sage";
|
|
16524
|
-
function formatReportingDetectionName(canonicalName, engine, optionalData = "") {
|
|
16525
|
-
const engineMetadata = optionalData ? `${REPORTING_ENGINE_SHORTHANDS[engine]}:${optionalData}` : REPORTING_ENGINE_SHORTHANDS[engine];
|
|
16526
|
-
return `${canonicalName}|${engineMetadata}|${REPORTING_DETECTION_SUFFIX}`;
|
|
16527
|
-
}
|
|
16528
|
-
var PACKAGE_DETECTION_NAMES = {
|
|
16529
|
-
not_found: "Other:SagePackageNotFound-A [Susp]",
|
|
16530
|
-
suspicious_age: "Other:SagePackageNew-A [Susp]",
|
|
16531
|
-
malicious: "Other:SagePackageMalicious-A [Trj]",
|
|
16532
|
-
unknown: "Other:SagePackageUnknown-A [Susp]"
|
|
16533
|
-
};
|
|
16534
|
-
var AMSI_DETECTION_NAMES = {
|
|
16535
|
-
detected: "Other:SageAmsiDetected-A [Heur]",
|
|
16536
|
-
blocked_by_admin: "Other:SageAmsiBlockedByAdmin-A [Heur]",
|
|
16537
|
-
unknown: "Other:SageAmsiUnknown-A [Susp]"
|
|
16538
|
-
};
|
|
16539
|
-
var AMSI_REPORTING_RULE_NAMES = {
|
|
16540
|
-
detected: "AMSI_DETECTED",
|
|
16541
|
-
blocked_by_admin: "AMSI_BLOCKED_BY_ADMIN",
|
|
16542
|
-
unknown: "AMSI_UNKNOWN"
|
|
16543
|
-
};
|
|
16544
|
-
function isCanonicalDetectionName(name) {
|
|
16545
|
-
return /^\w+:\w+-[A-Z]+ \[[^\]\r\n]+\]$/.test(name);
|
|
16546
|
-
}
|
|
16547
|
-
function packageDetectionName(verdict) {
|
|
16548
|
-
return PACKAGE_DETECTION_NAMES[verdict];
|
|
16549
|
-
}
|
|
16550
|
-
function amsiDetectionClass(amsiResult) {
|
|
16551
|
-
if (amsiResult >= 32768)
|
|
16552
|
-
return "detected";
|
|
16553
|
-
if (amsiResult >= 16384)
|
|
16554
|
-
return "blocked_by_admin";
|
|
16555
|
-
return "unknown";
|
|
16556
|
-
}
|
|
16557
|
-
function amsiDetectionName(amsiResult) {
|
|
16558
|
-
return AMSI_DETECTION_NAMES[amsiDetectionClass(amsiResult)];
|
|
16559
|
-
}
|
|
16560
|
-
function amsiReportingData(amsiResult) {
|
|
16561
|
-
const ruleName = AMSI_REPORTING_RULE_NAMES[amsiDetectionClass(amsiResult)];
|
|
16562
|
-
return `${ruleName}:${Math.trunc(amsiResult).toString(16)}`;
|
|
16563
|
-
}
|
|
16564
|
-
|
|
16565
16625
|
// ../core/dist/extended-info.js
|
|
16566
16626
|
var import_promises4 = require("node:fs/promises");
|
|
16567
16627
|
var import_node_os3 = require("node:os");
|
|
@@ -18137,7 +18197,7 @@ function extractFromPackageJson(content) {
|
|
|
18137
18197
|
continue;
|
|
18138
18198
|
if (version === "" || version === "*")
|
|
18139
18199
|
continue;
|
|
18140
|
-
if (version.startsWith("file:") || version.startsWith("link:") || version.startsWith("git+") || version.startsWith("git:") || version.startsWith("http:") || version.startsWith("https:") || version.startsWith("workspace:") || version.startsWith("github:") || version.startsWith("bitbucket:") || version.startsWith("gitlab:") || version.startsWith("portal:") || version.startsWith("patch:"))
|
|
18200
|
+
if (version.startsWith("catalog:") || version.startsWith("file:") || version.startsWith("link:") || version.startsWith("git+") || version.startsWith("git:") || version.startsWith("http:") || version.startsWith("https:") || version.startsWith("workspace:") || version.startsWith("github:") || version.startsWith("bitbucket:") || version.startsWith("gitlab:") || version.startsWith("portal:") || version.startsWith("patch:"))
|
|
18141
18201
|
continue;
|
|
18142
18202
|
if (version.startsWith("npm:")) {
|
|
18143
18203
|
const aliasTarget = version.slice(4);
|
|
@@ -19652,7 +19712,7 @@ function storeResult(cache2, pluginKey, version, lastUpdated, findings) {
|
|
|
19652
19712
|
}
|
|
19653
19713
|
|
|
19654
19714
|
// ../core/dist/plugin-scanner.js
|
|
19655
|
-
var
|
|
19715
|
+
var import_node_crypto10 = require("node:crypto");
|
|
19656
19716
|
var import_promises11 = require("node:fs/promises");
|
|
19657
19717
|
var import_node_path23 = require("node:path");
|
|
19658
19718
|
init_config();
|
|
@@ -20017,7 +20077,7 @@ function mergeSources(existing, incoming) {
|
|
|
20017
20077
|
function defaultCachePath2() {
|
|
20018
20078
|
return (0, import_node_path22.join)(resolvePath(SAGE_DIR), "skill_verdict_cache.json");
|
|
20019
20079
|
}
|
|
20020
|
-
async function
|
|
20080
|
+
async function loadSkillVerdictCacheInternal(cachePath, ttlMs, logger, pruneOnLoad) {
|
|
20021
20081
|
let raw;
|
|
20022
20082
|
try {
|
|
20023
20083
|
raw = await getFileContent(cachePath);
|
|
@@ -20040,6 +20100,8 @@ async function loadSkillVerdictCache(cachePath = defaultCachePath2(), ttlMs = DE
|
|
|
20040
20100
|
continue;
|
|
20041
20101
|
}
|
|
20042
20102
|
entries[skillId] = {
|
|
20103
|
+
entryId: typeof entry.entry_id === "string" ? entry.entry_id : void 0,
|
|
20104
|
+
jobId: typeof entry.job_id === "string" ? entry.job_id : void 0,
|
|
20043
20105
|
verdict: typeof entry.verdict === "string" ? entry.verdict : void 0,
|
|
20044
20106
|
summary: typeof entry.summary === "string" ? entry.summary : void 0,
|
|
20045
20107
|
skillName: typeof entry.skill_name === "string" ? entry.skill_name : void 0,
|
|
@@ -20048,7 +20110,7 @@ async function loadSkillVerdictCache(cachePath = defaultCachePath2(), ttlMs = DE
|
|
|
20048
20110
|
};
|
|
20049
20111
|
}
|
|
20050
20112
|
const cache2 = { entries };
|
|
20051
|
-
if (pruned > 0) {
|
|
20113
|
+
if (pruneOnLoad && pruned > 0) {
|
|
20052
20114
|
logger.debug(`Pruned ${pruned} stale verdict(s) from cache`, { cachePath });
|
|
20053
20115
|
await saveSkillVerdictCache(cache2, cachePath, logger);
|
|
20054
20116
|
}
|
|
@@ -20058,6 +20120,9 @@ async function loadSkillVerdictCache(cachePath = defaultCachePath2(), ttlMs = DE
|
|
|
20058
20120
|
return { entries: {} };
|
|
20059
20121
|
}
|
|
20060
20122
|
}
|
|
20123
|
+
async function loadSkillVerdictCache(cachePath = defaultCachePath2(), ttlMs = DEFAULT_VERDICT_TTL_MS, logger = nullLogger) {
|
|
20124
|
+
return loadSkillVerdictCacheInternal(cachePath, ttlMs, logger, true);
|
|
20125
|
+
}
|
|
20061
20126
|
async function saveSkillVerdictCache(cache2, cachePath = defaultCachePath2(), logger = nullLogger) {
|
|
20062
20127
|
try {
|
|
20063
20128
|
const data = {
|
|
@@ -20065,6 +20130,8 @@ async function saveSkillVerdictCache(cache2, cachePath = defaultCachePath2(), lo
|
|
|
20065
20130
|
entries: Object.fromEntries(Object.entries(cache2.entries).map(([skillId, v]) => [
|
|
20066
20131
|
skillId,
|
|
20067
20132
|
{
|
|
20133
|
+
entry_id: v.entryId,
|
|
20134
|
+
job_id: v.jobId,
|
|
20068
20135
|
verdict: v.verdict,
|
|
20069
20136
|
summary: v.summary,
|
|
20070
20137
|
skill_name: v.skillName,
|
|
@@ -20077,8 +20144,10 @@ async function saveSkillVerdictCache(cache2, cachePath = defaultCachePath2(), lo
|
|
|
20077
20144
|
]))
|
|
20078
20145
|
};
|
|
20079
20146
|
await atomicWriteJson(cachePath, data);
|
|
20147
|
+
return true;
|
|
20080
20148
|
} catch (e) {
|
|
20081
20149
|
logger.warn(`Failed to save verdict cache to ${cachePath}`, { error: String(e) });
|
|
20150
|
+
return false;
|
|
20082
20151
|
}
|
|
20083
20152
|
}
|
|
20084
20153
|
function getVerdict(cache2, skillId, ttlMs = DEFAULT_VERDICT_TTL_MS) {
|
|
@@ -20099,6 +20168,34 @@ function putVerdict(cache2, skillId, verdict) {
|
|
|
20099
20168
|
};
|
|
20100
20169
|
}
|
|
20101
20170
|
|
|
20171
|
+
// ../core/dist/skill-verdict-record.js
|
|
20172
|
+
var import_node_crypto9 = require("node:crypto");
|
|
20173
|
+
function recordAnalyzedSkillVerdict(cache2, skillId, result, origin) {
|
|
20174
|
+
const entryId = (0, import_node_crypto9.randomUUID)();
|
|
20175
|
+
putVerdict(cache2, skillId, {
|
|
20176
|
+
entryId,
|
|
20177
|
+
jobId: result.jobId,
|
|
20178
|
+
verdict: result.verdict,
|
|
20179
|
+
summary: result.summary,
|
|
20180
|
+
skillName: origin.skillName,
|
|
20181
|
+
sources: [{ agentRuntime: origin.agentRuntime, containerKey: origin.containerKey }]
|
|
20182
|
+
});
|
|
20183
|
+
const { loggingConfig } = origin;
|
|
20184
|
+
return {
|
|
20185
|
+
entryId,
|
|
20186
|
+
writeAuditEntry: async () => {
|
|
20187
|
+
if (!loggingConfig)
|
|
20188
|
+
return;
|
|
20189
|
+
await logSkillVerdict(loggingConfig, skillId, "analyzed", result.verdict, result.summary, {
|
|
20190
|
+
entryId,
|
|
20191
|
+
jobId: result.jobId,
|
|
20192
|
+
agentRuntime: origin.agentRuntime
|
|
20193
|
+
});
|
|
20194
|
+
}
|
|
20195
|
+
};
|
|
20196
|
+
}
|
|
20197
|
+
var SKILL_ENTRY_ID_NAMESPACE = Buffer.from("75bba79a376142a7bacbf95d791126d3", "hex");
|
|
20198
|
+
|
|
20102
20199
|
// ../core/dist/plugin-scanner.js
|
|
20103
20200
|
init_types2();
|
|
20104
20201
|
var SCANNABLE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
@@ -20226,7 +20323,7 @@ async function scanPlugin(plugin, options = {}) {
|
|
|
20226
20323
|
allUrls.push(...extractUrls(content));
|
|
20227
20324
|
}
|
|
20228
20325
|
if (checkFileHashes) {
|
|
20229
|
-
const sha256 = (0,
|
|
20326
|
+
const sha256 = (0, import_node_crypto10.createHash)("sha256").update(rawBytes).digest("hex");
|
|
20230
20327
|
const existing = hashToFiles.get(sha256);
|
|
20231
20328
|
if (existing) {
|
|
20232
20329
|
existing.push(filePath);
|
|
@@ -20323,6 +20420,8 @@ async function runSkillCheck(plugin, findings, logger, paths = {}) {
|
|
|
20323
20420
|
let markerModified = false;
|
|
20324
20421
|
let lookupFailed = false;
|
|
20325
20422
|
let graceDeferred = false;
|
|
20423
|
+
const resolvedPendingSkillIds = /* @__PURE__ */ new Set();
|
|
20424
|
+
const recordedVerdicts = /* @__PURE__ */ new Map();
|
|
20326
20425
|
for (const { folder, skillId } of uncached) {
|
|
20327
20426
|
if (!verdicts.has(skillId)) {
|
|
20328
20427
|
lookupFailed = true;
|
|
@@ -20330,17 +20429,18 @@ async function runSkillCheck(plugin, findings, logger, paths = {}) {
|
|
|
20330
20429
|
}
|
|
20331
20430
|
const verdict = verdicts.get(skillId) ?? null;
|
|
20332
20431
|
if (verdict) {
|
|
20333
|
-
|
|
20334
|
-
|
|
20335
|
-
|
|
20336
|
-
|
|
20337
|
-
|
|
20338
|
-
|
|
20339
|
-
|
|
20432
|
+
if (!recordedVerdicts.has(skillId)) {
|
|
20433
|
+
recordedVerdicts.set(skillId, recordAnalyzedSkillVerdict(verdictCache, skillId, verdict, {
|
|
20434
|
+
skillName: (0, import_node_path23.basename)(folder),
|
|
20435
|
+
agentRuntime: paths.agentRuntime,
|
|
20436
|
+
containerKey: plugin.key,
|
|
20437
|
+
loggingConfig: paths.loggingConfig
|
|
20438
|
+
}));
|
|
20439
|
+
cacheModified = true;
|
|
20440
|
+
}
|
|
20340
20441
|
pushSkillFindingIfRisky(findings, plugin, skillId, folder, verdict);
|
|
20341
20442
|
if (isPending(marker, skillId)) {
|
|
20342
|
-
|
|
20343
|
-
markerModified = true;
|
|
20443
|
+
resolvedPendingSkillIds.add(skillId);
|
|
20344
20444
|
}
|
|
20345
20445
|
} else if (!isPending(marker, skillId)) {
|
|
20346
20446
|
if (paths.uploadEnabled === false) {
|
|
@@ -20359,8 +20459,17 @@ async function runSkillCheck(plugin, findings, logger, paths = {}) {
|
|
|
20359
20459
|
}
|
|
20360
20460
|
}
|
|
20361
20461
|
}
|
|
20362
|
-
|
|
20363
|
-
|
|
20462
|
+
const cacheSaved = cacheModified ? await saveSkillVerdictCache(verdictCache, paths.verdictCachePath, logger) : true;
|
|
20463
|
+
if (cacheSaved) {
|
|
20464
|
+
await Promise.all([...recordedVerdicts.values()].map((entry) => entry.writeAuditEntry().catch(() => {
|
|
20465
|
+
})));
|
|
20466
|
+
for (const skillId of resolvedPendingSkillIds) {
|
|
20467
|
+
removePending(marker, skillId);
|
|
20468
|
+
markerModified = true;
|
|
20469
|
+
}
|
|
20470
|
+
} else {
|
|
20471
|
+
lookupFailed = true;
|
|
20472
|
+
}
|
|
20364
20473
|
if (markerModified)
|
|
20365
20474
|
await savePendingMarker(marker, paths.pendingPath, logger);
|
|
20366
20475
|
const anyStillPending = uncached.some(({ skillId }) => isPending(marker, skillId));
|
|
@@ -21050,7 +21159,7 @@ function createOpenClawScanHandler(logger, context, branding2 = defaultBranding,
|
|
|
21050
21159
|
branding: branding2,
|
|
21051
21160
|
onResult,
|
|
21052
21161
|
// No onNotices: OpenClaw delivers the one-time notice from
|
|
21053
|
-
// `
|
|
21162
|
+
// `before_prompt_build` (a different process/turn than this scan) via
|
|
21054
21163
|
// takePendingNotices, so the scan-time callback would never fire.
|
|
21055
21164
|
modelDownloadWorkerPath: (0, import_node_path28.resolve)(__dirname, "model-download-worker.cjs"),
|
|
21056
21165
|
skillUploadWorkerPath: (0, import_node_path28.resolve)(__dirname, "skill-upload-worker.cjs"),
|
|
@@ -21065,15 +21174,15 @@ function createStartupScanHandler(logger, branding2 = defaultBranding, onResult,
|
|
|
21065
21174
|
function createSessionScanHandler(logger, branding2 = defaultBranding, onResult, announceCleanScans = true) {
|
|
21066
21175
|
return createOpenClawScanHandler(logger, "session", branding2, onResult, announceCleanScans);
|
|
21067
21176
|
}
|
|
21068
|
-
function
|
|
21177
|
+
function createPromptContextHandler(getSecurityFindings, clearFindings, logger, branding2 = defaultBranding) {
|
|
21069
21178
|
return (notices) => {
|
|
21070
21179
|
const findings = getSecurityFindings();
|
|
21071
21180
|
if (!notices && !findings) {
|
|
21072
|
-
logger.debug(`${branding2.name}:
|
|
21181
|
+
logger.debug(`${branding2.name}: before_prompt_build - nothing pending to surface`);
|
|
21073
21182
|
return void 0;
|
|
21074
21183
|
}
|
|
21075
21184
|
if (findings) clearFindings();
|
|
21076
|
-
logger.debug(`${branding2.name}: surfacing context via
|
|
21185
|
+
logger.debug(`${branding2.name}: surfacing context via before_prompt_build`, {
|
|
21077
21186
|
hasNotices: Boolean(notices),
|
|
21078
21187
|
hasFindings: Boolean(findings)
|
|
21079
21188
|
});
|
|
@@ -21326,7 +21435,7 @@ ${notice}` : notice;
|
|
|
21326
21435
|
pendingScanFindings = msg;
|
|
21327
21436
|
};
|
|
21328
21437
|
const getPendingSecurityFindings = () => [pendingConfigurationWarnings, pendingScanFindings].filter(Boolean).join("\n\n") || null;
|
|
21329
|
-
const
|
|
21438
|
+
const promptContextHandler = createPromptContextHandler(
|
|
21330
21439
|
getPendingSecurityFindings,
|
|
21331
21440
|
() => {
|
|
21332
21441
|
pendingConfigurationWarnings = null;
|
|
@@ -21362,10 +21471,10 @@ ${notice}` : notice;
|
|
|
21362
21471
|
"session_start",
|
|
21363
21472
|
createSessionScanHandler(scanLogger, branding, onFindings, config.announce_clean_scans)
|
|
21364
21473
|
);
|
|
21365
|
-
api.on("
|
|
21474
|
+
api.on("before_prompt_build", async () => {
|
|
21366
21475
|
await migrationCheckPromise;
|
|
21367
21476
|
const notices = await resolveNoticeText();
|
|
21368
|
-
return
|
|
21477
|
+
return promptContextHandler(notices);
|
|
21369
21478
|
});
|
|
21370
21479
|
}
|
|
21371
21480
|
};
|