@useorgx/openclaw-plugin 0.4.8 → 0.7.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 +35 -0
- package/dashboard/dist/assets/BJgZIVUQ.js +53 -0
- package/dashboard/dist/assets/BJgZIVUQ.js.br +0 -0
- package/dashboard/dist/assets/BJgZIVUQ.js.gz +0 -0
- package/dashboard/dist/assets/BXWDRGm-.js +1 -0
- package/dashboard/dist/assets/BXWDRGm-.js.br +0 -0
- package/dashboard/dist/assets/BXWDRGm-.js.gz +0 -0
- package/dashboard/dist/assets/BgOYB78t.js +4 -0
- package/dashboard/dist/assets/BgOYB78t.js.br +0 -0
- package/dashboard/dist/assets/BgOYB78t.js.gz +0 -0
- package/dashboard/dist/assets/C-KIc3Wc.js.br +0 -0
- package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
- package/dashboard/dist/assets/CE38zU4U.js +1 -0
- package/dashboard/dist/assets/CE38zU4U.js.br +0 -0
- package/dashboard/dist/assets/CE38zU4U.js.gz +0 -0
- package/dashboard/dist/assets/CFGKRAzG.js +1 -0
- package/dashboard/dist/assets/CFGKRAzG.js.br +0 -0
- package/dashboard/dist/assets/CFGKRAzG.js.gz +0 -0
- package/dashboard/dist/assets/CGGR2GZh.js +1 -0
- package/dashboard/dist/assets/CGGR2GZh.js.br +0 -0
- package/dashboard/dist/assets/CGGR2GZh.js.gz +0 -0
- package/dashboard/dist/assets/CL_wXqR7.js +1 -0
- package/dashboard/dist/assets/CL_wXqR7.js.br +0 -0
- package/dashboard/dist/assets/CL_wXqR7.js.gz +0 -0
- package/dashboard/dist/assets/CPFiTmlw.js +8 -0
- package/dashboard/dist/assets/CPFiTmlw.js.br +0 -0
- package/dashboard/dist/assets/CPFiTmlw.js.gz +0 -0
- package/dashboard/dist/assets/CZZTvkQZ.js +1 -0
- package/dashboard/dist/assets/CZZTvkQZ.js.br +0 -0
- package/dashboard/dist/assets/CZZTvkQZ.js.gz +0 -0
- package/dashboard/dist/assets/{CpJsfbXo.js → CxQ08qFN.js} +2 -2
- package/dashboard/dist/assets/CxQ08qFN.js.br +0 -0
- package/dashboard/dist/assets/CxQ08qFN.js.gz +0 -0
- package/dashboard/dist/assets/D-bf6hEI.js +213 -0
- package/dashboard/dist/assets/D-bf6hEI.js.br +0 -0
- package/dashboard/dist/assets/D-bf6hEI.js.gz +0 -0
- package/dashboard/dist/assets/DG6y9wJI.js +2 -0
- package/dashboard/dist/assets/DG6y9wJI.js.br +0 -0
- package/dashboard/dist/assets/DG6y9wJI.js.gz +0 -0
- package/dashboard/dist/assets/DNxKz-GV.js +1 -0
- package/dashboard/dist/assets/DNxKz-GV.js.br +0 -0
- package/dashboard/dist/assets/DNxKz-GV.js.gz +0 -0
- package/dashboard/dist/assets/DW_rKUic.js +11 -0
- package/dashboard/dist/assets/DW_rKUic.js.br +0 -0
- package/dashboard/dist/assets/DW_rKUic.js.gz +0 -0
- package/dashboard/dist/assets/DbNoijHm.js +1 -0
- package/dashboard/dist/assets/DbNoijHm.js.br +0 -0
- package/dashboard/dist/assets/DbNoijHm.js.gz +0 -0
- package/dashboard/dist/assets/DjcdE6jC.js +2 -0
- package/dashboard/dist/assets/DjcdE6jC.js.br +0 -0
- package/dashboard/dist/assets/DjcdE6jC.js.gz +0 -0
- package/dashboard/dist/assets/FZYuCDnt.js +1 -0
- package/dashboard/dist/assets/FZYuCDnt.js.br +0 -0
- package/dashboard/dist/assets/FZYuCDnt.js.gz +0 -0
- package/dashboard/dist/assets/PAUiij_z.js +1 -0
- package/dashboard/dist/assets/PAUiij_z.js.br +0 -0
- package/dashboard/dist/assets/PAUiij_z.js.gz +0 -0
- package/dashboard/dist/assets/cNrhgGc1.js +8 -0
- package/dashboard/dist/assets/cNrhgGc1.js.br +0 -0
- package/dashboard/dist/assets/cNrhgGc1.js.gz +0 -0
- package/dashboard/dist/assets/h5biQs2I.css +1 -0
- package/dashboard/dist/assets/h5biQs2I.css.br +0 -0
- package/dashboard/dist/assets/h5biQs2I.css.gz +0 -0
- package/dashboard/dist/assets/ic2FaMnh.js +1 -0
- package/dashboard/dist/assets/ic2FaMnh.js.br +0 -0
- package/dashboard/dist/assets/ic2FaMnh.js.gz +0 -0
- package/dashboard/dist/assets/nByHNHoW.js +1 -0
- package/dashboard/dist/assets/nByHNHoW.js.br +0 -0
- package/dashboard/dist/assets/nByHNHoW.js.gz +0 -0
- package/dashboard/dist/assets/qm8xLgv-.css +1 -0
- package/dashboard/dist/assets/qm8xLgv-.css.br +0 -0
- package/dashboard/dist/assets/qm8xLgv-.css.gz +0 -0
- package/dashboard/dist/assets/tS9mbYZi.js +1 -0
- package/dashboard/dist/assets/tS9mbYZi.js.br +0 -0
- package/dashboard/dist/assets/tS9mbYZi.js.gz +0 -0
- package/dashboard/dist/brand/anthropic-mark.svg.br +0 -0
- package/dashboard/dist/brand/anthropic-mark.svg.gz +0 -0
- package/dashboard/dist/brand/openai-mark.svg.br +0 -0
- package/dashboard/dist/brand/openai-mark.svg.gz +0 -0
- package/dashboard/dist/brand/openclaw-mark.svg.br +0 -0
- package/dashboard/dist/brand/openclaw-mark.svg.gz +0 -0
- package/dashboard/dist/brand/xandy-orchestrator.png +0 -0
- package/dashboard/dist/index.html +7 -5
- package/dashboard/dist/index.html.br +0 -0
- package/dashboard/dist/index.html.gz +0 -0
- package/dist/activity-actor-fields.js +26 -4
- package/dist/activity-store.js +38 -26
- package/dist/agent-context-store.js +84 -42
- package/dist/agent-run-store.js +49 -28
- package/dist/agent-suite.d.ts +9 -0
- package/dist/agent-suite.js +150 -17
- package/dist/artifacts/artifact-domain-schemas.d.ts +66 -0
- package/dist/artifacts/artifact-domain-schemas.js +357 -0
- package/dist/artifacts/register-artifact.d.ts +4 -3
- package/dist/artifacts/register-artifact.js +170 -57
- package/dist/auth/flows.d.ts +47 -0
- package/dist/auth/flows.js +169 -0
- package/dist/auth-store.js +6 -26
- package/dist/byok-store.js +5 -19
- package/dist/chat-store.d.ts +157 -0
- package/dist/chat-store.js +586 -0
- package/dist/cli/orgx.d.ts +66 -0
- package/dist/cli/orgx.js +102 -0
- package/dist/config/refresh.d.ts +32 -0
- package/dist/config/refresh.js +55 -0
- package/dist/config/resolution.d.ts +37 -0
- package/dist/config/resolution.js +178 -0
- package/dist/contracts/client.d.ts +43 -3
- package/dist/contracts/client.js +159 -30
- package/dist/contracts/retro-schema.d.ts +81 -0
- package/dist/contracts/retro-schema.js +80 -0
- package/dist/contracts/shared-types.d.ts +306 -0
- package/dist/contracts/shared-types.js +179 -0
- package/dist/contracts/skill-pack-schema.d.ts +192 -0
- package/dist/contracts/skill-pack-schema.js +180 -0
- package/dist/contracts/types.d.ts +224 -132
- package/dist/contracts/types.js +5 -0
- package/dist/entities/auto-assignment.d.ts +36 -0
- package/dist/entities/auto-assignment.js +141 -0
- package/dist/entity-comment-store.js +5 -25
- package/dist/event-sanitization.d.ts +11 -0
- package/dist/event-sanitization.js +113 -0
- package/dist/fs-utils.js +13 -1
- package/dist/gateway-watchdog.d.ts +5 -0
- package/dist/gateway-watchdog.js +50 -0
- package/dist/hash-utils.d.ts +2 -0
- package/dist/hash-utils.js +12 -0
- package/dist/hooks/post-reporting-event.mjs +1 -5
- package/dist/http/helpers/activity-headline.d.ts +10 -0
- package/dist/http/helpers/activity-headline.js +73 -0
- package/dist/http/helpers/artifact-fallback.d.ts +13 -0
- package/dist/http/helpers/artifact-fallback.js +148 -0
- package/dist/http/helpers/auto-continue-engine.d.ts +486 -0
- package/dist/http/helpers/auto-continue-engine.js +3563 -0
- package/dist/http/helpers/autopilot-operations.d.ts +176 -0
- package/dist/http/helpers/autopilot-operations.js +554 -0
- package/dist/http/helpers/autopilot-runtime.d.ts +43 -0
- package/dist/http/helpers/autopilot-runtime.js +607 -0
- package/dist/http/helpers/autopilot-slice-utils.d.ts +56 -0
- package/dist/http/helpers/autopilot-slice-utils.js +899 -0
- package/dist/http/helpers/decision-mapper.d.ts +52 -0
- package/dist/http/helpers/decision-mapper.js +260 -0
- package/dist/http/helpers/dispatch-lifecycle.d.ts +119 -0
- package/dist/http/helpers/dispatch-lifecycle.js +809 -0
- package/dist/http/helpers/hash-utils.d.ts +1 -0
- package/dist/http/helpers/hash-utils.js +1 -0
- package/dist/http/helpers/kickoff-context.d.ts +12 -0
- package/dist/http/helpers/kickoff-context.js +228 -0
- package/dist/http/helpers/llm-client.d.ts +47 -0
- package/dist/http/helpers/llm-client.js +256 -0
- package/dist/http/helpers/mission-control.d.ts +193 -0
- package/dist/http/helpers/mission-control.js +1383 -0
- package/dist/http/helpers/openclaw-cli.d.ts +37 -0
- package/dist/http/helpers/openclaw-cli.js +283 -0
- package/dist/http/helpers/runtime-sse.d.ts +20 -0
- package/dist/http/helpers/runtime-sse.js +110 -0
- package/dist/http/helpers/sentinel-catalog.d.ts +23 -0
- package/dist/http/helpers/sentinel-catalog.js +193 -0
- package/dist/http/helpers/session-classification.d.ts +9 -0
- package/dist/http/helpers/session-classification.js +564 -0
- package/dist/http/helpers/slice-experience-v2.d.ts +137 -0
- package/dist/http/helpers/slice-experience-v2.js +677 -0
- package/dist/http/helpers/slice-run-projections.d.ts +72 -0
- package/dist/http/helpers/slice-run-projections.js +860 -0
- package/dist/http/helpers/triage-mapper.d.ts +43 -0
- package/dist/http/helpers/triage-mapper.js +549 -0
- package/dist/http/helpers/value-utils.d.ts +6 -0
- package/dist/http/helpers/value-utils.js +72 -0
- package/dist/http/helpers/workspace-scope.d.ts +15 -0
- package/dist/http/helpers/workspace-scope.js +170 -0
- package/dist/http/index.d.ts +88 -0
- package/dist/http/index.js +3610 -0
- package/dist/http/router.d.ts +23 -0
- package/dist/http/router.js +23 -0
- package/dist/http/routes/agent-control.d.ts +79 -0
- package/dist/http/routes/agent-control.js +684 -0
- package/dist/http/routes/agent-suite.d.ts +38 -0
- package/dist/http/routes/agent-suite.js +397 -0
- package/dist/http/routes/agents-catalog.d.ts +40 -0
- package/dist/http/routes/agents-catalog.js +128 -0
- package/dist/http/routes/billing.d.ts +23 -0
- package/dist/http/routes/billing.js +55 -0
- package/dist/http/routes/chat.d.ts +19 -0
- package/dist/http/routes/chat.js +522 -0
- package/dist/http/routes/debug.d.ts +14 -0
- package/dist/http/routes/debug.js +21 -0
- package/dist/http/routes/decision-actions.d.ts +20 -0
- package/dist/http/routes/decision-actions.js +103 -0
- package/dist/http/routes/delegation.d.ts +19 -0
- package/dist/http/routes/delegation.js +32 -0
- package/dist/http/routes/dispatch-gateway-envelope.d.ts +25 -0
- package/dist/http/routes/dispatch-gateway-envelope.js +26 -0
- package/dist/http/routes/entities.d.ts +63 -0
- package/dist/http/routes/entities.js +440 -0
- package/dist/http/routes/entity-dynamic.d.ts +25 -0
- package/dist/http/routes/entity-dynamic.js +191 -0
- package/dist/http/routes/health.d.ts +22 -0
- package/dist/http/routes/health.js +49 -0
- package/dist/http/routes/live-legacy.d.ts +115 -0
- package/dist/http/routes/live-legacy.js +112 -0
- package/dist/http/routes/live-misc.d.ts +81 -0
- package/dist/http/routes/live-misc.js +426 -0
- package/dist/http/routes/live-snapshot.d.ts +136 -0
- package/dist/http/routes/live-snapshot.js +916 -0
- package/dist/http/routes/live-terminal.d.ts +11 -0
- package/dist/http/routes/live-terminal.js +261 -0
- package/dist/http/routes/live-triage.d.ts +61 -0
- package/dist/http/routes/live-triage.js +248 -0
- package/dist/http/routes/mission-control-actions.d.ts +131 -0
- package/dist/http/routes/mission-control-actions.js +1791 -0
- package/dist/http/routes/mission-control-read.d.ts +73 -0
- package/dist/http/routes/mission-control-read.js +1640 -0
- package/dist/http/routes/onboarding.d.ts +34 -0
- package/dist/http/routes/onboarding.js +101 -0
- package/dist/http/routes/realtime-orchestrator.d.ts +10 -0
- package/dist/http/routes/realtime-orchestrator.js +74 -0
- package/dist/http/routes/run-control.d.ts +27 -0
- package/dist/http/routes/run-control.js +96 -0
- package/dist/http/routes/runtime-hooks.d.ts +69 -0
- package/dist/http/routes/runtime-hooks.js +437 -0
- package/dist/http/routes/sentinels-catalog.d.ts +7 -0
- package/dist/http/routes/sentinels-catalog.js +24 -0
- package/dist/http/routes/settings-byok.d.ts +23 -0
- package/dist/http/routes/settings-byok.js +163 -0
- package/dist/http/routes/summary.d.ts +18 -0
- package/dist/http/routes/summary.js +49 -0
- package/dist/http/routes/usage.d.ts +24 -0
- package/dist/http/routes/usage.js +362 -0
- package/dist/http/routes/work-artifacts.d.ts +9 -0
- package/dist/http/routes/work-artifacts.js +55 -0
- package/dist/http/shared-state.d.ts +16 -0
- package/dist/http/shared-state.js +1 -0
- package/dist/http-handler.d.ts +1 -88
- package/dist/http-handler.js +1 -10605
- package/dist/index.js +287 -2284
- package/dist/json-utils.d.ts +1 -0
- package/dist/json-utils.js +8 -0
- package/dist/local-openclaw.js +29 -6
- package/dist/mcp-client-setup.js +3 -3
- package/dist/mcp-http-handler.js +33 -59
- package/dist/next-up-queue-store.d.ts +16 -1
- package/dist/next-up-queue-store.js +93 -25
- package/dist/outbox.d.ts +5 -0
- package/dist/outbox.js +113 -9
- package/dist/paths.js +24 -5
- package/dist/reporting/rollups.d.ts +53 -0
- package/dist/reporting/rollups.js +148 -0
- package/dist/retro/domain-templates.d.ts +45 -0
- package/dist/retro/domain-templates.js +297 -0
- package/dist/retro/quality-rubric.d.ts +33 -0
- package/dist/retro/quality-rubric.js +213 -0
- package/dist/runtime-cleanup.d.ts +18 -0
- package/dist/runtime-cleanup.js +87 -0
- package/dist/runtime-instance-store.js +5 -31
- package/dist/services/background.d.ts +34 -0
- package/dist/services/background.js +45 -0
- package/dist/services/experiment-randomization.d.ts +21 -0
- package/dist/services/experiment-randomization.js +63 -0
- package/dist/services/instrumentation.d.ts +29 -0
- package/dist/services/instrumentation.js +136 -0
- package/dist/skill-pack-state.d.ts +36 -5
- package/dist/skill-pack-state.js +273 -29
- package/dist/snapshot-store.js +5 -25
- package/dist/stores/json-store.d.ts +11 -0
- package/dist/stores/json-store.js +42 -0
- package/dist/sync/local-agent-telemetry.d.ts +13 -0
- package/dist/sync/local-agent-telemetry.js +128 -0
- package/dist/sync/outbox-replay.d.ts +55 -0
- package/dist/sync/outbox-replay.js +621 -0
- package/dist/team-context-store.d.ts +23 -0
- package/dist/team-context-store.js +116 -0
- package/dist/telemetry/posthog.js +4 -2
- package/dist/tools/core-tools.d.ts +72 -0
- package/dist/tools/core-tools.js +2270 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +2 -0
- package/dist/worker-supervisor.js +23 -0
- package/package.json +14 -4
- package/dashboard/dist/assets/B3ziCA02.js +0 -8
- package/dashboard/dist/assets/BNeJ0kpF.js +0 -1
- package/dashboard/dist/assets/BzkiMPmM.js +0 -215
- package/dashboard/dist/assets/CUV9IHHi.js +0 -1
- package/dashboard/dist/assets/Ie7d9Iq2.css +0 -1
- package/dashboard/dist/assets/sAhvFnpk.js +0 -4
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { posthogCapture } from "../telemetry/posthog.js";
|
|
2
|
+
export function instrumentPluginApi(input) {
|
|
3
|
+
const registerTool = input.api.registerTool.bind(input.api);
|
|
4
|
+
input.api.registerTool = (tool, options) => {
|
|
5
|
+
const toolName = tool.name;
|
|
6
|
+
const optional = Boolean(options?.optional);
|
|
7
|
+
registerTool({
|
|
8
|
+
...tool,
|
|
9
|
+
execute: async (callId, params) => {
|
|
10
|
+
const startedAt = Date.now();
|
|
11
|
+
void posthogCapture({
|
|
12
|
+
event: "openclaw_tool_called",
|
|
13
|
+
distinctId: input.installationId,
|
|
14
|
+
properties: {
|
|
15
|
+
tool_name: toolName,
|
|
16
|
+
tool_optional: optional,
|
|
17
|
+
call_id: callId,
|
|
18
|
+
plugin_version: input.pluginVersion,
|
|
19
|
+
},
|
|
20
|
+
}).catch(() => {
|
|
21
|
+
// best effort
|
|
22
|
+
});
|
|
23
|
+
try {
|
|
24
|
+
const result = await tool.execute(callId, params);
|
|
25
|
+
const durationMs = Date.now() - startedAt;
|
|
26
|
+
void posthogCapture({
|
|
27
|
+
event: "openclaw_tool_succeeded",
|
|
28
|
+
distinctId: input.installationId,
|
|
29
|
+
properties: {
|
|
30
|
+
tool_name: toolName,
|
|
31
|
+
tool_optional: optional,
|
|
32
|
+
call_id: callId,
|
|
33
|
+
duration_ms: durationMs,
|
|
34
|
+
plugin_version: input.pluginVersion,
|
|
35
|
+
},
|
|
36
|
+
}).catch(() => {
|
|
37
|
+
// best effort
|
|
38
|
+
});
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const durationMs = Date.now() - startedAt;
|
|
43
|
+
void posthogCapture({
|
|
44
|
+
event: "openclaw_tool_failed",
|
|
45
|
+
distinctId: input.installationId,
|
|
46
|
+
properties: {
|
|
47
|
+
tool_name: toolName,
|
|
48
|
+
tool_optional: optional,
|
|
49
|
+
call_id: callId,
|
|
50
|
+
duration_ms: durationMs,
|
|
51
|
+
plugin_version: input.pluginVersion,
|
|
52
|
+
error: input.toErrorMessage(err),
|
|
53
|
+
},
|
|
54
|
+
}).catch(() => {
|
|
55
|
+
// best effort
|
|
56
|
+
});
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
}, options);
|
|
61
|
+
};
|
|
62
|
+
const registerService = input.api.registerService.bind(input.api);
|
|
63
|
+
input.api.registerService = (service) => {
|
|
64
|
+
registerService({
|
|
65
|
+
...service,
|
|
66
|
+
start: async () => {
|
|
67
|
+
const startedAt = Date.now();
|
|
68
|
+
try {
|
|
69
|
+
await service.start();
|
|
70
|
+
const durationMs = Date.now() - startedAt;
|
|
71
|
+
void posthogCapture({
|
|
72
|
+
event: "openclaw_service_started",
|
|
73
|
+
distinctId: input.installationId,
|
|
74
|
+
properties: {
|
|
75
|
+
service_id: service.id,
|
|
76
|
+
duration_ms: durationMs,
|
|
77
|
+
plugin_version: input.pluginVersion,
|
|
78
|
+
},
|
|
79
|
+
}).catch(() => {
|
|
80
|
+
// best effort
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
const durationMs = Date.now() - startedAt;
|
|
85
|
+
void posthogCapture({
|
|
86
|
+
event: "openclaw_service_start_failed",
|
|
87
|
+
distinctId: input.installationId,
|
|
88
|
+
properties: {
|
|
89
|
+
service_id: service.id,
|
|
90
|
+
duration_ms: durationMs,
|
|
91
|
+
plugin_version: input.pluginVersion,
|
|
92
|
+
error: input.toErrorMessage(err),
|
|
93
|
+
},
|
|
94
|
+
}).catch(() => {
|
|
95
|
+
// best effort
|
|
96
|
+
});
|
|
97
|
+
throw err;
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
stop: async () => {
|
|
101
|
+
const startedAt = Date.now();
|
|
102
|
+
try {
|
|
103
|
+
await service.stop();
|
|
104
|
+
const durationMs = Date.now() - startedAt;
|
|
105
|
+
void posthogCapture({
|
|
106
|
+
event: "openclaw_service_stopped",
|
|
107
|
+
distinctId: input.installationId,
|
|
108
|
+
properties: {
|
|
109
|
+
service_id: service.id,
|
|
110
|
+
duration_ms: durationMs,
|
|
111
|
+
plugin_version: input.pluginVersion,
|
|
112
|
+
},
|
|
113
|
+
}).catch(() => {
|
|
114
|
+
// best effort
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
const durationMs = Date.now() - startedAt;
|
|
119
|
+
void posthogCapture({
|
|
120
|
+
event: "openclaw_service_stop_failed",
|
|
121
|
+
distinctId: input.installationId,
|
|
122
|
+
properties: {
|
|
123
|
+
service_id: service.id,
|
|
124
|
+
duration_ms: durationMs,
|
|
125
|
+
plugin_version: input.pluginVersion,
|
|
126
|
+
error: input.toErrorMessage(err),
|
|
127
|
+
},
|
|
128
|
+
}).catch(() => {
|
|
129
|
+
// best effort
|
|
130
|
+
});
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
}
|
|
@@ -1,15 +1,32 @@
|
|
|
1
1
|
import type { SkillPack } from "./contracts/types.js";
|
|
2
2
|
import type { OrgxSkillPackOverrides } from "./agent-suite.js";
|
|
3
|
+
export type SkillPackPolicy = {
|
|
4
|
+
frozen: boolean;
|
|
5
|
+
pinnedChecksum: string | null;
|
|
6
|
+
};
|
|
7
|
+
export type SkillPackPolicyDiff = {
|
|
8
|
+
field: "policy.frozen" | "policy.pinnedChecksum";
|
|
9
|
+
before: boolean | string | null;
|
|
10
|
+
after: boolean | string | null;
|
|
11
|
+
};
|
|
12
|
+
export type SkillPackPolicyAuditEntry = {
|
|
13
|
+
id: string;
|
|
14
|
+
changedAt: string;
|
|
15
|
+
changedBy: string;
|
|
16
|
+
action: "policy.update" | "policy.rollback";
|
|
17
|
+
reason: string | null;
|
|
18
|
+
rollbackOfAuditId: string | null;
|
|
19
|
+
diff: SkillPackPolicyDiff[];
|
|
20
|
+
beforePolicy: SkillPackPolicy;
|
|
21
|
+
afterPolicy: SkillPackPolicy;
|
|
22
|
+
};
|
|
3
23
|
export type SkillPackState = {
|
|
4
24
|
version: 1;
|
|
5
25
|
updatedAt: string;
|
|
6
26
|
lastCheckedAt: string | null;
|
|
7
27
|
lastError: string | null;
|
|
8
28
|
etag: string | null;
|
|
9
|
-
policy:
|
|
10
|
-
frozen: boolean;
|
|
11
|
-
pinnedChecksum: string | null;
|
|
12
|
-
};
|
|
29
|
+
policy: SkillPackPolicy;
|
|
13
30
|
pack: {
|
|
14
31
|
name: string;
|
|
15
32
|
version: string;
|
|
@@ -23,6 +40,9 @@ export type SkillPackState = {
|
|
|
23
40
|
updated_at: string | null;
|
|
24
41
|
} | null;
|
|
25
42
|
overrides: OrgxSkillPackOverrides | null;
|
|
43
|
+
audit: {
|
|
44
|
+
entries: SkillPackPolicyAuditEntry[];
|
|
45
|
+
};
|
|
26
46
|
};
|
|
27
47
|
export declare function readSkillPackState(input?: {
|
|
28
48
|
openclawDir?: string;
|
|
@@ -36,11 +56,22 @@ export declare function updateSkillPackPolicy(input: {
|
|
|
36
56
|
pinnedChecksum?: string | null;
|
|
37
57
|
pinToCurrent?: boolean;
|
|
38
58
|
clearPin?: boolean;
|
|
59
|
+
changedBy?: string;
|
|
60
|
+
reason?: string;
|
|
61
|
+
}): SkillPackState;
|
|
62
|
+
export declare function rollbackSkillPackPolicy(input?: {
|
|
63
|
+
openclawDir?: string;
|
|
64
|
+
auditId?: string;
|
|
65
|
+
changedBy?: string;
|
|
66
|
+
reason?: string;
|
|
39
67
|
}): SkillPackState;
|
|
40
68
|
export declare function toOrgxSkillPackOverrides(input: {
|
|
41
69
|
pack: SkillPack;
|
|
42
70
|
etag: string | null;
|
|
43
|
-
}):
|
|
71
|
+
}): {
|
|
72
|
+
overrides: OrgxSkillPackOverrides;
|
|
73
|
+
validationErrors: string[];
|
|
74
|
+
};
|
|
44
75
|
export declare function refreshSkillPackState(input: {
|
|
45
76
|
getSkillPack: (args: {
|
|
46
77
|
name?: string;
|
package/dist/skill-pack-state.js
CHANGED
|
@@ -2,8 +2,10 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { writeFileAtomicSync } from "./fs-utils.js";
|
|
4
4
|
import { getOpenClawDir } from "./paths.js";
|
|
5
|
+
import { validateOpenClawSkillPackManifest } from "./contracts/skill-pack-schema.js";
|
|
5
6
|
const STORE_VERSION = 1;
|
|
6
7
|
const STATE_FILENAME = "orgx-skill-pack-state.json";
|
|
8
|
+
const AUDIT_HISTORY_LIMIT = 50;
|
|
7
9
|
function nowIso() {
|
|
8
10
|
return new Date().toISOString();
|
|
9
11
|
}
|
|
@@ -16,6 +18,94 @@ function coerceString(value) {
|
|
|
16
18
|
function statePath(openclawDir) {
|
|
17
19
|
return join(openclawDir, STATE_FILENAME);
|
|
18
20
|
}
|
|
21
|
+
function clonePolicy(input) {
|
|
22
|
+
return {
|
|
23
|
+
frozen: Boolean(input.frozen),
|
|
24
|
+
pinnedChecksum: coerceString(input.pinnedChecksum),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function normalizeChangedBy(input) {
|
|
28
|
+
if (typeof input !== "string")
|
|
29
|
+
return "unknown";
|
|
30
|
+
const value = input.trim();
|
|
31
|
+
return value.length > 0 ? value : "unknown";
|
|
32
|
+
}
|
|
33
|
+
function normalizeReason(input) {
|
|
34
|
+
return typeof input === "string" && input.trim().length > 0 ? input.trim() : null;
|
|
35
|
+
}
|
|
36
|
+
function nextAuditId() {
|
|
37
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
38
|
+
}
|
|
39
|
+
function computePolicyDiff(before, after) {
|
|
40
|
+
const diff = [];
|
|
41
|
+
if (before.frozen !== after.frozen) {
|
|
42
|
+
diff.push({
|
|
43
|
+
field: "policy.frozen",
|
|
44
|
+
before: before.frozen,
|
|
45
|
+
after: after.frozen,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (before.pinnedChecksum !== after.pinnedChecksum) {
|
|
49
|
+
diff.push({
|
|
50
|
+
field: "policy.pinnedChecksum",
|
|
51
|
+
before: before.pinnedChecksum,
|
|
52
|
+
after: after.pinnedChecksum,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return diff;
|
|
56
|
+
}
|
|
57
|
+
function appendPolicyAuditEntry(entries, entry) {
|
|
58
|
+
return [entry, ...entries].slice(0, AUDIT_HISTORY_LIMIT);
|
|
59
|
+
}
|
|
60
|
+
function parseAuditEntries(raw) {
|
|
61
|
+
if (!Array.isArray(raw))
|
|
62
|
+
return [];
|
|
63
|
+
const entries = [];
|
|
64
|
+
for (const candidate of raw) {
|
|
65
|
+
if (!isRecord(candidate))
|
|
66
|
+
continue;
|
|
67
|
+
const beforePolicyRaw = isRecord(candidate.beforePolicy) ? candidate.beforePolicy : null;
|
|
68
|
+
const afterPolicyRaw = isRecord(candidate.afterPolicy) ? candidate.afterPolicy : null;
|
|
69
|
+
if (!beforePolicyRaw || !afterPolicyRaw)
|
|
70
|
+
continue;
|
|
71
|
+
const diffRaw = Array.isArray(candidate.diff) ? candidate.diff : [];
|
|
72
|
+
const diff = [];
|
|
73
|
+
for (const diffEntry of diffRaw) {
|
|
74
|
+
if (!isRecord(diffEntry))
|
|
75
|
+
continue;
|
|
76
|
+
const field = diffEntry.field;
|
|
77
|
+
if (field !== "policy.frozen" && field !== "policy.pinnedChecksum")
|
|
78
|
+
continue;
|
|
79
|
+
diff.push({
|
|
80
|
+
field,
|
|
81
|
+
before: typeof diffEntry.before === "boolean" || diffEntry.before === null
|
|
82
|
+
? diffEntry.before
|
|
83
|
+
: coerceString(diffEntry.before),
|
|
84
|
+
after: typeof diffEntry.after === "boolean" || diffEntry.after === null
|
|
85
|
+
? diffEntry.after
|
|
86
|
+
: coerceString(diffEntry.after),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
entries.push({
|
|
90
|
+
id: coerceString(candidate.id) ?? nextAuditId(),
|
|
91
|
+
changedAt: coerceString(candidate.changedAt) ?? nowIso(),
|
|
92
|
+
changedBy: normalizeChangedBy(candidate.changedBy),
|
|
93
|
+
action: candidate.action === "policy.rollback" ? "policy.rollback" : "policy.update",
|
|
94
|
+
reason: normalizeReason(candidate.reason),
|
|
95
|
+
rollbackOfAuditId: coerceString(candidate.rollbackOfAuditId),
|
|
96
|
+
diff,
|
|
97
|
+
beforePolicy: {
|
|
98
|
+
frozen: Boolean(beforePolicyRaw.frozen),
|
|
99
|
+
pinnedChecksum: coerceString(beforePolicyRaw.pinnedChecksum),
|
|
100
|
+
},
|
|
101
|
+
afterPolicy: {
|
|
102
|
+
frozen: Boolean(afterPolicyRaw.frozen),
|
|
103
|
+
pinnedChecksum: coerceString(afterPolicyRaw.pinnedChecksum),
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return entries.slice(0, AUDIT_HISTORY_LIMIT);
|
|
108
|
+
}
|
|
19
109
|
export function readSkillPackState(input) {
|
|
20
110
|
const openclawDir = input?.openclawDir ?? getOpenClawDir();
|
|
21
111
|
const path = statePath(openclawDir);
|
|
@@ -29,6 +119,7 @@ export function readSkillPackState(input) {
|
|
|
29
119
|
pack: null,
|
|
30
120
|
remote: null,
|
|
31
121
|
overrides: null,
|
|
122
|
+
audit: { entries: [] },
|
|
32
123
|
};
|
|
33
124
|
try {
|
|
34
125
|
if (!existsSync(path))
|
|
@@ -43,6 +134,7 @@ export function readSkillPackState(input) {
|
|
|
43
134
|
const pack = isRecord(parsed.pack) ? parsed.pack : null;
|
|
44
135
|
const remote = isRecord(parsed.remote) ? parsed.remote : null;
|
|
45
136
|
const overrides = isRecord(parsed.overrides) ? parsed.overrides : null;
|
|
137
|
+
const audit = isRecord(parsed.audit) ? parsed.audit : null;
|
|
46
138
|
return {
|
|
47
139
|
version: STORE_VERSION,
|
|
48
140
|
updatedAt: coerceString(parsed.updatedAt) ?? nowIso(),
|
|
@@ -72,6 +164,9 @@ export function readSkillPackState(input) {
|
|
|
72
164
|
overrides: overrides
|
|
73
165
|
? overrides
|
|
74
166
|
: null,
|
|
167
|
+
audit: {
|
|
168
|
+
entries: parseAuditEntries(audit?.entries),
|
|
169
|
+
},
|
|
75
170
|
};
|
|
76
171
|
}
|
|
77
172
|
catch {
|
|
@@ -88,7 +183,12 @@ export function writeSkillPackState(state, input) {
|
|
|
88
183
|
}
|
|
89
184
|
export function updateSkillPackPolicy(input) {
|
|
90
185
|
const prev = readSkillPackState({ openclawDir: input.openclawDir });
|
|
186
|
+
const beforePolicy = clonePolicy(prev.policy);
|
|
91
187
|
const nextPolicy = { ...prev.policy };
|
|
188
|
+
const activeChecksum = prev.pack?.checksum ?? null;
|
|
189
|
+
const remoteChecksum = prev.remote?.checksum ?? null;
|
|
190
|
+
const hasInactiveRemoteCandidate = Boolean(remoteChecksum && remoteChecksum !== activeChecksum);
|
|
191
|
+
const blockedByActivationValidation = hasInactiveRemoteCandidate && hasActivationValidationFailure(prev.lastError);
|
|
92
192
|
if (typeof input.frozen === "boolean") {
|
|
93
193
|
nextPolicy.frozen = input.frozen;
|
|
94
194
|
}
|
|
@@ -96,10 +196,20 @@ export function updateSkillPackPolicy(input) {
|
|
|
96
196
|
nextPolicy.pinnedChecksum = null;
|
|
97
197
|
}
|
|
98
198
|
else if (input.pinToCurrent) {
|
|
199
|
+
if (blockedByActivationValidation) {
|
|
200
|
+
throw new Error("Cannot pin_to_current: remote config failed eval/manifest checks and is not active.");
|
|
201
|
+
}
|
|
99
202
|
nextPolicy.pinnedChecksum = prev.pack?.checksum ?? prev.remote?.checksum ?? null;
|
|
100
203
|
}
|
|
101
204
|
else if (typeof input.pinnedChecksum === "string") {
|
|
102
|
-
|
|
205
|
+
const requestedChecksum = input.pinnedChecksum.trim() || null;
|
|
206
|
+
if (requestedChecksum &&
|
|
207
|
+
remoteChecksum &&
|
|
208
|
+
requestedChecksum === remoteChecksum &&
|
|
209
|
+
blockedByActivationValidation) {
|
|
210
|
+
throw new Error("Cannot pin checksum to remote config: eval/manifest checks are failing for that candidate.");
|
|
211
|
+
}
|
|
212
|
+
nextPolicy.pinnedChecksum = requestedChecksum;
|
|
103
213
|
}
|
|
104
214
|
else if (input.pinnedChecksum === null) {
|
|
105
215
|
nextPolicy.pinnedChecksum = null;
|
|
@@ -109,48 +219,155 @@ export function updateSkillPackPolicy(input) {
|
|
|
109
219
|
updatedAt: nowIso(),
|
|
110
220
|
policy: nextPolicy,
|
|
111
221
|
};
|
|
222
|
+
const diff = computePolicyDiff(beforePolicy, next.policy);
|
|
223
|
+
if (diff.length > 0) {
|
|
224
|
+
const entry = {
|
|
225
|
+
id: nextAuditId(),
|
|
226
|
+
changedAt: next.updatedAt,
|
|
227
|
+
changedBy: normalizeChangedBy(input.changedBy),
|
|
228
|
+
action: "policy.update",
|
|
229
|
+
reason: normalizeReason(input.reason),
|
|
230
|
+
rollbackOfAuditId: null,
|
|
231
|
+
diff,
|
|
232
|
+
beforePolicy,
|
|
233
|
+
afterPolicy: clonePolicy(next.policy),
|
|
234
|
+
};
|
|
235
|
+
next.audit = {
|
|
236
|
+
entries: appendPolicyAuditEntry(prev.audit.entries, entry),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
112
239
|
writeSkillPackState(next, { openclawDir: input.openclawDir });
|
|
113
240
|
return next;
|
|
114
241
|
}
|
|
242
|
+
export function rollbackSkillPackPolicy(input) {
|
|
243
|
+
const prev = readSkillPackState({ openclawDir: input?.openclawDir });
|
|
244
|
+
const normalizedAuditId = typeof input?.auditId === "string" && input.auditId.trim().length > 0
|
|
245
|
+
? input.auditId.trim()
|
|
246
|
+
: null;
|
|
247
|
+
const target = normalizedAuditId
|
|
248
|
+
? prev.audit.entries.find((entry) => entry.id === normalizedAuditId) ?? null
|
|
249
|
+
: prev.audit.entries[0] ?? null;
|
|
250
|
+
if (!target) {
|
|
251
|
+
throw new Error("No policy audit entry available for rollback");
|
|
252
|
+
}
|
|
253
|
+
const beforePolicy = clonePolicy(prev.policy);
|
|
254
|
+
const afterPolicy = clonePolicy(target.beforePolicy);
|
|
255
|
+
const diff = computePolicyDiff(beforePolicy, afterPolicy);
|
|
256
|
+
if (diff.length === 0) {
|
|
257
|
+
return prev;
|
|
258
|
+
}
|
|
259
|
+
const changedAt = nowIso();
|
|
260
|
+
const rollbackEntry = {
|
|
261
|
+
id: nextAuditId(),
|
|
262
|
+
changedAt,
|
|
263
|
+
changedBy: normalizeChangedBy(input?.changedBy),
|
|
264
|
+
action: "policy.rollback",
|
|
265
|
+
reason: normalizeReason(input?.reason) ?? `Rollback to audit ${target.id}`,
|
|
266
|
+
rollbackOfAuditId: target.id,
|
|
267
|
+
diff,
|
|
268
|
+
beforePolicy,
|
|
269
|
+
afterPolicy,
|
|
270
|
+
};
|
|
271
|
+
const next = {
|
|
272
|
+
...prev,
|
|
273
|
+
updatedAt: changedAt,
|
|
274
|
+
policy: afterPolicy,
|
|
275
|
+
audit: {
|
|
276
|
+
entries: appendPolicyAuditEntry(prev.audit.entries, rollbackEntry),
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
writeSkillPackState(next, { openclawDir: input?.openclawDir });
|
|
280
|
+
return next;
|
|
281
|
+
}
|
|
115
282
|
function asRecord(value) {
|
|
116
283
|
return isRecord(value) ? value : null;
|
|
117
284
|
}
|
|
118
|
-
function
|
|
119
|
-
|
|
285
|
+
function asBoolean(value) {
|
|
286
|
+
return typeof value === "boolean" ? value : null;
|
|
287
|
+
}
|
|
288
|
+
function asFiniteNumber(value) {
|
|
289
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
290
|
+
}
|
|
291
|
+
function normalizeStatus(value) {
|
|
292
|
+
if (typeof value !== "string")
|
|
293
|
+
return null;
|
|
294
|
+
const normalized = value.trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
295
|
+
return normalized.length > 0 ? normalized : null;
|
|
296
|
+
}
|
|
297
|
+
function hasActivationValidationFailure(lastError) {
|
|
298
|
+
if (!lastError)
|
|
299
|
+
return false;
|
|
300
|
+
const normalized = lastError.toLowerCase();
|
|
301
|
+
return (normalized.includes("eval framework checks did not pass") ||
|
|
302
|
+
normalized.includes("eval gate blocked activation") ||
|
|
303
|
+
normalized.includes("manifest validation errors"));
|
|
304
|
+
}
|
|
305
|
+
function evalGateErrorForPack(pack) {
|
|
306
|
+
const manifest = asRecord(pack.manifest);
|
|
307
|
+
if (!manifest) {
|
|
308
|
+
return "SkillPack eval framework checks did not pass: missing manifest object";
|
|
309
|
+
}
|
|
120
310
|
const candidates = [
|
|
121
|
-
asRecord(
|
|
122
|
-
asRecord(
|
|
123
|
-
asRecord(
|
|
124
|
-
|
|
125
|
-
|
|
311
|
+
{ label: "eval_framework", value: asRecord(manifest.eval_framework) },
|
|
312
|
+
{ label: "evalFramework", value: asRecord(manifest.evalFramework) },
|
|
313
|
+
{ label: "evaluation_result", value: asRecord(manifest.evaluation_result) },
|
|
314
|
+
{ label: "evaluationResult", value: asRecord(manifest.evaluationResult) },
|
|
315
|
+
{ label: "evaluation", value: asRecord(manifest.evaluation) },
|
|
316
|
+
{ label: "quality_gate", value: asRecord(manifest.quality_gate) },
|
|
317
|
+
{ label: "qualityGate", value: asRecord(manifest.qualityGate) },
|
|
318
|
+
];
|
|
126
319
|
for (const candidate of candidates) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
320
|
+
if (!candidate.value)
|
|
321
|
+
continue;
|
|
322
|
+
const passed = asBoolean(candidate.value.passed) ??
|
|
323
|
+
asBoolean(candidate.value.ok) ??
|
|
324
|
+
asBoolean(candidate.value.success) ??
|
|
325
|
+
asBoolean(candidate.value.allowed);
|
|
326
|
+
if (passed != null) {
|
|
327
|
+
return passed
|
|
328
|
+
? null
|
|
329
|
+
: `SkillPack eval framework checks did not pass: ${candidate.label}.passed=false`;
|
|
330
|
+
}
|
|
331
|
+
const status = normalizeStatus(candidate.value.status);
|
|
332
|
+
if (status) {
|
|
333
|
+
const passStatuses = new Set(["pass", "passed", "ok", "success", "approved", "green"]);
|
|
334
|
+
const failStatuses = new Set(["fail", "failed", "rejected", "error", "blocked", "red"]);
|
|
335
|
+
if (passStatuses.has(status))
|
|
336
|
+
return null;
|
|
337
|
+
if (failStatuses.has(status)) {
|
|
338
|
+
return `SkillPack eval framework checks did not pass: ${candidate.label}.status=${status}`;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const checksTotal = asFiniteNumber(candidate.value.checks_total) ??
|
|
342
|
+
asFiniteNumber(candidate.value.total_checks);
|
|
343
|
+
const checksPassed = asFiniteNumber(candidate.value.checks_passed) ??
|
|
344
|
+
asFiniteNumber(candidate.value.passed_checks);
|
|
345
|
+
if (checksTotal != null && checksPassed != null && checksTotal > 0) {
|
|
346
|
+
return checksPassed >= checksTotal
|
|
347
|
+
? null
|
|
348
|
+
: `SkillPack eval framework checks did not pass: ${candidate.label}.checks=${checksPassed}/${checksTotal}`;
|
|
134
349
|
}
|
|
135
350
|
}
|
|
136
|
-
return
|
|
351
|
+
return "SkillPack eval framework checks did not pass: missing pass signal in manifest";
|
|
137
352
|
}
|
|
138
353
|
export function toOrgxSkillPackOverrides(input) {
|
|
139
|
-
const manifest = asRecord(input.pack.manifest)
|
|
140
|
-
const
|
|
354
|
+
const manifest = asRecord(input.pack.manifest);
|
|
355
|
+
const validation = validateOpenClawSkillPackManifest(manifest ?? {});
|
|
141
356
|
const openclaw_skills = {};
|
|
142
|
-
for (const [k, v] of Object.entries(
|
|
143
|
-
// Domains are normalized to lowercase keys in the manifest.
|
|
357
|
+
for (const [k, v] of Object.entries(validation.openclaw_skills)) {
|
|
144
358
|
openclaw_skills[k] = v;
|
|
145
359
|
}
|
|
146
360
|
return {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
361
|
+
overrides: {
|
|
362
|
+
source: "server",
|
|
363
|
+
name: input.pack.name,
|
|
364
|
+
version: input.pack.version,
|
|
365
|
+
checksum: input.pack.checksum,
|
|
366
|
+
etag: input.etag,
|
|
367
|
+
updated_at: input.pack.updated_at ?? null,
|
|
368
|
+
openclaw_skills,
|
|
369
|
+
},
|
|
370
|
+
validationErrors: validation.errors,
|
|
154
371
|
};
|
|
155
372
|
}
|
|
156
373
|
export async function refreshSkillPackState(input) {
|
|
@@ -201,7 +418,33 @@ export async function refreshSkillPackState(input) {
|
|
|
201
418
|
writeSkillPackState(next, { openclawDir: input.openclawDir });
|
|
202
419
|
return { state: next, changed: false };
|
|
203
420
|
}
|
|
204
|
-
const overrides = toOrgxSkillPackOverrides({
|
|
421
|
+
const { overrides, validationErrors } = toOrgxSkillPackOverrides({
|
|
422
|
+
pack: result.pack,
|
|
423
|
+
etag: result.etag ?? null,
|
|
424
|
+
});
|
|
425
|
+
const evalGateError = evalGateErrorForPack(result.pack);
|
|
426
|
+
const activationErrors = [];
|
|
427
|
+
if (validationErrors.length > 0) {
|
|
428
|
+
activationErrors.push(`SkillPack manifest validation errors: ${validationErrors.join("; ")}`);
|
|
429
|
+
}
|
|
430
|
+
if (evalGateError) {
|
|
431
|
+
activationErrors.push(evalGateError);
|
|
432
|
+
}
|
|
433
|
+
const activationValidationError = activationErrors.length > 0 ? activationErrors.join(" | ") : null;
|
|
434
|
+
// Guardrail: never activate a config that fails eval/manifest validation.
|
|
435
|
+
// Keep it staged in `remote` + `lastError` so operators can inspect/fix it.
|
|
436
|
+
if (activationValidationError) {
|
|
437
|
+
const next = {
|
|
438
|
+
...prev,
|
|
439
|
+
updatedAt: nowIso(),
|
|
440
|
+
lastCheckedAt: nowIso(),
|
|
441
|
+
lastError: activationValidationError,
|
|
442
|
+
etag: result.etag ?? prev.etag,
|
|
443
|
+
remote: remoteMeta,
|
|
444
|
+
};
|
|
445
|
+
writeSkillPackState(next, { openclawDir: input.openclawDir });
|
|
446
|
+
return { state: next, changed: false };
|
|
447
|
+
}
|
|
205
448
|
const next = {
|
|
206
449
|
version: STORE_VERSION,
|
|
207
450
|
updatedAt: nowIso(),
|
|
@@ -217,6 +460,7 @@ export async function refreshSkillPackState(input) {
|
|
|
217
460
|
},
|
|
218
461
|
remote: remoteMeta,
|
|
219
462
|
overrides,
|
|
463
|
+
audit: prev.audit,
|
|
220
464
|
};
|
|
221
465
|
writeSkillPackState(next, { openclawDir: input.openclawDir });
|
|
222
466
|
return { state: next, changed: prev.pack?.checksum !== next.pack?.checksum };
|
|
@@ -225,7 +469,7 @@ export async function refreshSkillPackState(input) {
|
|
|
225
469
|
...prev,
|
|
226
470
|
updatedAt: nowIso(),
|
|
227
471
|
lastCheckedAt: nowIso(),
|
|
228
|
-
lastError:
|
|
472
|
+
lastError: result.ok === false ? result.error : prev.lastError,
|
|
229
473
|
};
|
|
230
474
|
writeSkillPackState(next, { openclawDir: input.openclawDir });
|
|
231
475
|
return { state: next, changed: false };
|
package/dist/snapshot-store.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { getOrgxPluginConfigDir, getOrgxPluginConfigPath } from './paths.js';
|
|
3
3
|
import { backupCorruptFileSync, writeJsonFileAtomicSync } from './fs-utils.js';
|
|
4
|
+
import { clearStoreFileSync, ensureStoreDirSync, parseJsonSafe, } from "./stores/json-store.js";
|
|
4
5
|
function snapshotDir() {
|
|
5
6
|
return getOrgxPluginConfigDir();
|
|
6
7
|
}
|
|
@@ -8,22 +9,7 @@ function snapshotFile() {
|
|
|
8
9
|
return getOrgxPluginConfigPath('snapshot.json');
|
|
9
10
|
}
|
|
10
11
|
function ensureSnapshotDir() {
|
|
11
|
-
|
|
12
|
-
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
13
|
-
try {
|
|
14
|
-
chmodSync(dir, 0o700);
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
// best effort
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function parseJson(value) {
|
|
21
|
-
try {
|
|
22
|
-
return JSON.parse(value);
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
12
|
+
ensureStoreDirSync(snapshotDir());
|
|
27
13
|
}
|
|
28
14
|
export function readPersistedSnapshot() {
|
|
29
15
|
const file = snapshotFile();
|
|
@@ -31,7 +17,7 @@ export function readPersistedSnapshot() {
|
|
|
31
17
|
if (!existsSync(file))
|
|
32
18
|
return null;
|
|
33
19
|
const raw = readFileSync(file, 'utf8');
|
|
34
|
-
const parsed =
|
|
20
|
+
const parsed = parseJsonSafe(raw);
|
|
35
21
|
if (!parsed) {
|
|
36
22
|
backupCorruptFileSync(file);
|
|
37
23
|
return null;
|
|
@@ -57,11 +43,5 @@ export function writePersistedSnapshot(snapshot) {
|
|
|
57
43
|
return record;
|
|
58
44
|
}
|
|
59
45
|
export function clearPersistedSnapshot() {
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
rmSync(file, { force: true });
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
// best effort
|
|
66
|
-
}
|
|
46
|
+
clearStoreFileSync(snapshotFile());
|
|
67
47
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { parseJsonSafe } from "../json-utils.js";
|
|
2
|
+
export declare function ensureStoreDirSync(dir: string): void;
|
|
3
|
+
export { parseJsonSafe };
|
|
4
|
+
export declare function readJsonFileOrDefault<T>(input: {
|
|
5
|
+
file: string;
|
|
6
|
+
fallback: () => T;
|
|
7
|
+
isValid?: (value: unknown) => value is T;
|
|
8
|
+
backupOnInvalid?: boolean;
|
|
9
|
+
}): T;
|
|
10
|
+
export declare function writeJsonStoreFileSync(file: string, data: unknown, mode?: number): void;
|
|
11
|
+
export declare function clearStoreFileSync(file: string): void;
|