@useorgx/openclaw-plugin 0.4.9 → 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.
Files changed (222) hide show
  1. package/README.md +35 -0
  2. package/dashboard/dist/assets/BJgZIVUQ.js +53 -0
  3. package/dashboard/dist/assets/BJgZIVUQ.js.br +0 -0
  4. package/dashboard/dist/assets/BJgZIVUQ.js.gz +0 -0
  5. package/dashboard/dist/assets/BXWDRGm-.js +1 -0
  6. package/dashboard/dist/assets/BXWDRGm-.js.br +0 -0
  7. package/dashboard/dist/assets/BXWDRGm-.js.gz +0 -0
  8. package/dashboard/dist/assets/BgOYB78t.js +4 -0
  9. package/dashboard/dist/assets/BgOYB78t.js.br +0 -0
  10. package/dashboard/dist/assets/BgOYB78t.js.gz +0 -0
  11. package/dashboard/dist/assets/C-KIc3Wc.js.br +0 -0
  12. package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
  13. package/dashboard/dist/assets/CE38zU4U.js +1 -0
  14. package/dashboard/dist/assets/CE38zU4U.js.br +0 -0
  15. package/dashboard/dist/assets/CE38zU4U.js.gz +0 -0
  16. package/dashboard/dist/assets/CFGKRAzG.js +1 -0
  17. package/dashboard/dist/assets/CFGKRAzG.js.br +0 -0
  18. package/dashboard/dist/assets/CFGKRAzG.js.gz +0 -0
  19. package/dashboard/dist/assets/CGGR2GZh.js +1 -0
  20. package/dashboard/dist/assets/CGGR2GZh.js.br +0 -0
  21. package/dashboard/dist/assets/CGGR2GZh.js.gz +0 -0
  22. package/dashboard/dist/assets/CL_wXqR7.js +1 -0
  23. package/dashboard/dist/assets/CL_wXqR7.js.br +0 -0
  24. package/dashboard/dist/assets/CL_wXqR7.js.gz +0 -0
  25. package/dashboard/dist/assets/CPFiTmlw.js +8 -0
  26. package/dashboard/dist/assets/CPFiTmlw.js.br +0 -0
  27. package/dashboard/dist/assets/CPFiTmlw.js.gz +0 -0
  28. package/dashboard/dist/assets/CZZTvkQZ.js +1 -0
  29. package/dashboard/dist/assets/CZZTvkQZ.js.br +0 -0
  30. package/dashboard/dist/assets/CZZTvkQZ.js.gz +0 -0
  31. package/dashboard/dist/assets/{CpJsfbXo.js → CxQ08qFN.js} +2 -2
  32. package/dashboard/dist/assets/CxQ08qFN.js.br +0 -0
  33. package/dashboard/dist/assets/CxQ08qFN.js.gz +0 -0
  34. package/dashboard/dist/assets/D-bf6hEI.js +213 -0
  35. package/dashboard/dist/assets/D-bf6hEI.js.br +0 -0
  36. package/dashboard/dist/assets/D-bf6hEI.js.gz +0 -0
  37. package/dashboard/dist/assets/DG6y9wJI.js +2 -0
  38. package/dashboard/dist/assets/DG6y9wJI.js.br +0 -0
  39. package/dashboard/dist/assets/DG6y9wJI.js.gz +0 -0
  40. package/dashboard/dist/assets/DNxKz-GV.js +1 -0
  41. package/dashboard/dist/assets/DNxKz-GV.js.br +0 -0
  42. package/dashboard/dist/assets/DNxKz-GV.js.gz +0 -0
  43. package/dashboard/dist/assets/DW_rKUic.js +11 -0
  44. package/dashboard/dist/assets/DW_rKUic.js.br +0 -0
  45. package/dashboard/dist/assets/DW_rKUic.js.gz +0 -0
  46. package/dashboard/dist/assets/DbNoijHm.js +1 -0
  47. package/dashboard/dist/assets/DbNoijHm.js.br +0 -0
  48. package/dashboard/dist/assets/DbNoijHm.js.gz +0 -0
  49. package/dashboard/dist/assets/DjcdE6jC.js +2 -0
  50. package/dashboard/dist/assets/DjcdE6jC.js.br +0 -0
  51. package/dashboard/dist/assets/DjcdE6jC.js.gz +0 -0
  52. package/dashboard/dist/assets/FZYuCDnt.js +1 -0
  53. package/dashboard/dist/assets/FZYuCDnt.js.br +0 -0
  54. package/dashboard/dist/assets/FZYuCDnt.js.gz +0 -0
  55. package/dashboard/dist/assets/PAUiij_z.js +1 -0
  56. package/dashboard/dist/assets/PAUiij_z.js.br +0 -0
  57. package/dashboard/dist/assets/PAUiij_z.js.gz +0 -0
  58. package/dashboard/dist/assets/cNrhgGc1.js +8 -0
  59. package/dashboard/dist/assets/cNrhgGc1.js.br +0 -0
  60. package/dashboard/dist/assets/cNrhgGc1.js.gz +0 -0
  61. package/dashboard/dist/assets/h5biQs2I.css +1 -0
  62. package/dashboard/dist/assets/h5biQs2I.css.br +0 -0
  63. package/dashboard/dist/assets/h5biQs2I.css.gz +0 -0
  64. package/dashboard/dist/assets/ic2FaMnh.js +1 -0
  65. package/dashboard/dist/assets/ic2FaMnh.js.br +0 -0
  66. package/dashboard/dist/assets/ic2FaMnh.js.gz +0 -0
  67. package/dashboard/dist/assets/nByHNHoW.js +1 -0
  68. package/dashboard/dist/assets/nByHNHoW.js.br +0 -0
  69. package/dashboard/dist/assets/nByHNHoW.js.gz +0 -0
  70. package/dashboard/dist/assets/qm8xLgv-.css +1 -0
  71. package/dashboard/dist/assets/qm8xLgv-.css.br +0 -0
  72. package/dashboard/dist/assets/qm8xLgv-.css.gz +0 -0
  73. package/dashboard/dist/assets/tS9mbYZi.js +1 -0
  74. package/dashboard/dist/assets/tS9mbYZi.js.br +0 -0
  75. package/dashboard/dist/assets/tS9mbYZi.js.gz +0 -0
  76. package/dashboard/dist/brand/anthropic-mark.svg.br +0 -0
  77. package/dashboard/dist/brand/anthropic-mark.svg.gz +0 -0
  78. package/dashboard/dist/brand/openai-mark.svg.br +0 -0
  79. package/dashboard/dist/brand/openai-mark.svg.gz +0 -0
  80. package/dashboard/dist/brand/openclaw-mark.svg.br +0 -0
  81. package/dashboard/dist/brand/openclaw-mark.svg.gz +0 -0
  82. package/dashboard/dist/brand/xandy-orchestrator.png +0 -0
  83. package/dashboard/dist/index.html +7 -5
  84. package/dashboard/dist/index.html.br +0 -0
  85. package/dashboard/dist/index.html.gz +0 -0
  86. package/dist/activity-actor-fields.js +26 -4
  87. package/dist/activity-store.js +34 -8
  88. package/dist/agent-context-store.js +79 -17
  89. package/dist/agent-run-store.js +44 -3
  90. package/dist/agent-suite.d.ts +9 -0
  91. package/dist/agent-suite.js +149 -9
  92. package/dist/artifacts/artifact-domain-schemas.d.ts +66 -0
  93. package/dist/artifacts/artifact-domain-schemas.js +357 -0
  94. package/dist/artifacts/register-artifact.d.ts +4 -3
  95. package/dist/artifacts/register-artifact.js +170 -57
  96. package/dist/chat-store.d.ts +157 -0
  97. package/dist/chat-store.js +586 -0
  98. package/dist/cli/orgx.js +11 -0
  99. package/dist/contracts/client.d.ts +43 -3
  100. package/dist/contracts/client.js +159 -30
  101. package/dist/contracts/retro-schema.d.ts +81 -0
  102. package/dist/contracts/retro-schema.js +80 -0
  103. package/dist/contracts/shared-types.d.ts +159 -0
  104. package/dist/contracts/shared-types.js +177 -1
  105. package/dist/contracts/skill-pack-schema.d.ts +192 -0
  106. package/dist/contracts/skill-pack-schema.js +180 -0
  107. package/dist/contracts/types.d.ts +227 -2
  108. package/dist/entities/auto-assignment.js +43 -17
  109. package/dist/event-sanitization.d.ts +11 -0
  110. package/dist/event-sanitization.js +113 -0
  111. package/dist/fs-utils.js +13 -1
  112. package/dist/gateway-watchdog.d.ts +5 -0
  113. package/dist/gateway-watchdog.js +50 -0
  114. package/dist/hooks/post-reporting-event.mjs +1 -5
  115. package/dist/http/helpers/activity-headline.js +13 -132
  116. package/dist/http/helpers/auto-continue-engine.d.ts +198 -10
  117. package/dist/http/helpers/auto-continue-engine.js +2531 -186
  118. package/dist/http/helpers/autopilot-operations.d.ts +19 -0
  119. package/dist/http/helpers/autopilot-operations.js +182 -31
  120. package/dist/http/helpers/autopilot-runtime.d.ts +1 -0
  121. package/dist/http/helpers/autopilot-runtime.js +308 -20
  122. package/dist/http/helpers/autopilot-slice-utils.d.ts +18 -0
  123. package/dist/http/helpers/autopilot-slice-utils.js +516 -93
  124. package/dist/http/helpers/decision-mapper.d.ts +40 -0
  125. package/dist/http/helpers/decision-mapper.js +223 -7
  126. package/dist/http/helpers/dispatch-lifecycle.d.ts +19 -2
  127. package/dist/http/helpers/dispatch-lifecycle.js +242 -37
  128. package/dist/http/helpers/kickoff-context.js +74 -0
  129. package/dist/http/helpers/llm-client.d.ts +47 -0
  130. package/dist/http/helpers/llm-client.js +256 -0
  131. package/dist/http/helpers/mission-control.d.ts +102 -3
  132. package/dist/http/helpers/mission-control.js +498 -9
  133. package/dist/http/helpers/sentinel-catalog.d.ts +23 -0
  134. package/dist/http/helpers/sentinel-catalog.js +193 -0
  135. package/dist/http/helpers/session-classification.d.ts +9 -0
  136. package/dist/http/helpers/session-classification.js +564 -0
  137. package/dist/http/helpers/slice-experience-v2.d.ts +137 -0
  138. package/dist/http/helpers/slice-experience-v2.js +677 -0
  139. package/dist/http/helpers/slice-run-projections.d.ts +72 -0
  140. package/dist/http/helpers/slice-run-projections.js +860 -0
  141. package/dist/http/helpers/triage-mapper.d.ts +43 -0
  142. package/dist/http/helpers/triage-mapper.js +549 -0
  143. package/dist/http/helpers/value-utils.js +7 -2
  144. package/dist/http/helpers/workspace-scope.d.ts +15 -0
  145. package/dist/http/helpers/workspace-scope.js +170 -0
  146. package/dist/http/index.js +1354 -97
  147. package/dist/http/routes/agent-suite.d.ts +9 -0
  148. package/dist/http/routes/agent-suite.js +207 -8
  149. package/dist/http/routes/agents-catalog.js +64 -19
  150. package/dist/http/routes/chat.d.ts +19 -0
  151. package/dist/http/routes/chat.js +522 -0
  152. package/dist/http/routes/decision-actions.d.ts +8 -1
  153. package/dist/http/routes/decision-actions.js +42 -5
  154. package/dist/http/routes/dispatch-gateway-envelope.d.ts +25 -0
  155. package/dist/http/routes/dispatch-gateway-envelope.js +26 -0
  156. package/dist/http/routes/entities.d.ts +16 -0
  157. package/dist/http/routes/entities.js +294 -6
  158. package/dist/http/routes/live-legacy.d.ts +5 -0
  159. package/dist/http/routes/live-legacy.js +23 -509
  160. package/dist/http/routes/live-misc.d.ts +12 -0
  161. package/dist/http/routes/live-misc.js +251 -31
  162. package/dist/http/routes/live-snapshot.d.ts +48 -2
  163. package/dist/http/routes/live-snapshot.js +638 -19
  164. package/dist/http/routes/live-terminal.d.ts +11 -0
  165. package/dist/http/routes/live-terminal.js +261 -0
  166. package/dist/http/routes/live-triage.d.ts +61 -0
  167. package/dist/http/routes/live-triage.js +248 -0
  168. package/dist/http/routes/mission-control-actions.d.ts +49 -1
  169. package/dist/http/routes/mission-control-actions.js +1334 -84
  170. package/dist/http/routes/mission-control-read.d.ts +48 -3
  171. package/dist/http/routes/mission-control-read.js +1593 -20
  172. package/dist/http/routes/realtime-orchestrator.d.ts +10 -0
  173. package/dist/http/routes/realtime-orchestrator.js +74 -0
  174. package/dist/http/routes/run-control.d.ts +5 -2
  175. package/dist/http/routes/run-control.js +10 -0
  176. package/dist/http/routes/sentinels-catalog.d.ts +7 -0
  177. package/dist/http/routes/sentinels-catalog.js +24 -0
  178. package/dist/http/routes/summary.js +10 -3
  179. package/dist/http/routes/usage.d.ts +24 -0
  180. package/dist/http/routes/usage.js +362 -0
  181. package/dist/http/routes/work-artifacts.js +28 -9
  182. package/dist/index.js +165 -27
  183. package/dist/local-openclaw.js +29 -6
  184. package/dist/mcp-client-setup.js +3 -3
  185. package/dist/mcp-http-handler.js +33 -59
  186. package/dist/next-up-queue-store.d.ts +16 -1
  187. package/dist/next-up-queue-store.js +89 -7
  188. package/dist/outbox.d.ts +5 -0
  189. package/dist/outbox.js +113 -9
  190. package/dist/paths.js +24 -5
  191. package/dist/reporting/rollups.d.ts +53 -0
  192. package/dist/reporting/rollups.js +148 -0
  193. package/dist/retro/domain-templates.d.ts +45 -0
  194. package/dist/retro/domain-templates.js +297 -0
  195. package/dist/retro/quality-rubric.d.ts +33 -0
  196. package/dist/retro/quality-rubric.js +213 -0
  197. package/dist/runtime-cleanup.d.ts +18 -0
  198. package/dist/runtime-cleanup.js +87 -0
  199. package/dist/services/background.d.ts +11 -0
  200. package/dist/services/background.js +22 -0
  201. package/dist/services/experiment-randomization.d.ts +21 -0
  202. package/dist/services/experiment-randomization.js +63 -0
  203. package/dist/skill-pack-state.d.ts +36 -5
  204. package/dist/skill-pack-state.js +273 -29
  205. package/dist/sync/local-agent-telemetry.d.ts +13 -0
  206. package/dist/sync/local-agent-telemetry.js +128 -0
  207. package/dist/sync/outbox-replay.js +131 -24
  208. package/dist/team-context-store.d.ts +23 -0
  209. package/dist/team-context-store.js +116 -0
  210. package/dist/telemetry/posthog.js +4 -2
  211. package/dist/tools/core-tools.d.ts +10 -14
  212. package/dist/tools/core-tools.js +1289 -24
  213. package/dist/types.d.ts +2 -0
  214. package/dist/types.js +2 -0
  215. package/dist/worker-supervisor.js +23 -0
  216. package/package.json +14 -4
  217. package/dashboard/dist/assets/B3ziCA02.js +0 -8
  218. package/dashboard/dist/assets/B5NEElEI.css +0 -1
  219. package/dashboard/dist/assets/BhapSNAs.js +0 -215
  220. package/dashboard/dist/assets/iFdvE7lx.js +0 -1
  221. package/dashboard/dist/assets/jRJsmpYM.js +0 -1
  222. package/dashboard/dist/assets/sAhvFnpk.js +0 -4
@@ -2,8 +2,11 @@ import type { Router } from "../router.js";
2
2
  type JsonRecord = Record<string, unknown>;
3
3
  type ReadSkillPackStateFn = typeof import("../../skill-pack-state.js").readSkillPackState;
4
4
  type UpdateSkillPackPolicyFn = typeof import("../../skill-pack-state.js").updateSkillPackPolicy;
5
+ type RollbackSkillPackPolicyFn = typeof import("../../skill-pack-state.js").rollbackSkillPackPolicy;
5
6
  type ComputeOrgxAgentSuitePlanFn = typeof import("../../agent-suite.js").computeOrgxAgentSuitePlan;
6
7
  type ApplyOrgxAgentSuitePlanFn = typeof import("../../agent-suite.js").applyOrgxAgentSuitePlan;
8
+ type ClientRuntimeSettingsResponse = import("../../contracts/types.js").ClientRuntimeSettingsResponse;
9
+ type ClientRuntimeSettingsUpdateRequest = import("../../contracts/types.js").ClientRuntimeSettingsUpdateRequest;
7
10
  type OrgxSkillPackOverrides = import("../../agent-suite.js").OrgxSkillPackOverrides;
8
11
  type RegisterAgentSuiteRoutesDeps<TReq, TRes> = {
9
12
  pluginVersion: string | null | undefined;
@@ -17,6 +20,12 @@ type RegisterAgentSuiteRoutesDeps<TReq, TRes> = {
17
20
  applyOrgxAgentSuitePlan: ApplyOrgxAgentSuitePlanFn;
18
21
  generateAgentSuiteOperationId: () => string;
19
22
  updateSkillPackPolicy: UpdateSkillPackPolicyFn;
23
+ rollbackSkillPackPolicy: RollbackSkillPackPolicyFn;
24
+ fetchAgentRuntimeSettings: (input?: {
25
+ workspaceId?: string | null;
26
+ projectId?: string | null;
27
+ }) => Promise<ClientRuntimeSettingsResponse>;
28
+ updateAgentRuntimeSettings: (payload: ClientRuntimeSettingsUpdateRequest) => Promise<ClientRuntimeSettingsResponse>;
20
29
  posthogCapture: (input: {
21
30
  event: string;
22
31
  distinctId: string;
@@ -21,6 +21,64 @@ function computeUpdateAvailable(state) {
21
21
  state.pack?.checksum &&
22
22
  state.remote.checksum !== state.pack.checksum);
23
23
  }
24
+ function toOptionalString(value) {
25
+ return typeof value === "string" ? value : undefined;
26
+ }
27
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
28
+ function toOptionalUuid(value) {
29
+ if (typeof value !== "string")
30
+ return undefined;
31
+ const trimmed = value.trim();
32
+ return UUID_RE.test(trimmed) ? trimmed : undefined;
33
+ }
34
+ function readOptionalBoolean(payload, ...keys) {
35
+ for (const key of keys) {
36
+ const value = payload[key];
37
+ if (typeof value === "boolean") {
38
+ return value;
39
+ }
40
+ }
41
+ return undefined;
42
+ }
43
+ function normalizeRuntimeSettingsPatch(payload) {
44
+ const runtime = toRecord(payload.runtime_settings ?? payload.runtimeSettings);
45
+ const patch = {};
46
+ const decisionV2Enabled = readOptionalBoolean(runtime, "decision_v2_enabled", "decisionV2Enabled");
47
+ if (typeof decisionV2Enabled === "boolean") {
48
+ patch.decision_v2_enabled = decisionV2Enabled;
49
+ }
50
+ const decisionDedupeEnabled = readOptionalBoolean(runtime, "decision_dedupe_enabled", "decisionDedupeEnabled");
51
+ if (typeof decisionDedupeEnabled === "boolean") {
52
+ patch.decision_dedupe_enabled = decisionDedupeEnabled;
53
+ }
54
+ const decisionEvidenceRequiredForBlocking = readOptionalBoolean(runtime, "decision_evidence_required_for_blocking", "decisionEvidenceRequiredForBlocking");
55
+ if (typeof decisionEvidenceRequiredForBlocking === "boolean") {
56
+ patch.decision_evidence_required_for_blocking =
57
+ decisionEvidenceRequiredForBlocking;
58
+ }
59
+ const decisionAutoResolveGuardedEnabled = readOptionalBoolean(runtime, "decision_auto_resolve_guarded_enabled", "decisionAutoResolveGuardedEnabled");
60
+ if (typeof decisionAutoResolveGuardedEnabled === "boolean") {
61
+ patch.decision_auto_resolve_guarded_enabled =
62
+ decisionAutoResolveGuardedEnabled;
63
+ }
64
+ const customRunInstructions = toOptionalString(runtime.custom_run_instructions ?? runtime.customRunInstructions);
65
+ if (typeof customRunInstructions === "string") {
66
+ patch.custom_run_instructions = customRunInstructions.slice(0, 4000);
67
+ }
68
+ return patch;
69
+ }
70
+ function buildRuntimeSettingsFallbackEnvelope(workspaceId) {
71
+ const normalizedWorkspaceId = typeof workspaceId === "string" && workspaceId.trim().length > 0
72
+ ? workspaceId.trim()
73
+ : null;
74
+ return {
75
+ ok: true,
76
+ workspace_id: normalizedWorkspaceId,
77
+ command_center_id: normalizedWorkspaceId,
78
+ project_id: normalizedWorkspaceId,
79
+ agents: [],
80
+ };
81
+ }
24
82
  export function registerAgentSuiteRoutes(router, deps) {
25
83
  async function renderStatus(res) {
26
84
  try {
@@ -54,6 +112,102 @@ export function registerAgentSuiteRoutes(router, deps) {
54
112
  }
55
113
  router.add("GET", "agent-suite/status", async ({ res }) => renderStatus(res), "Agent suite installation status");
56
114
  router.add("HEAD", "agent-suite/status", async ({ res }) => renderStatus(res), "Agent suite installation status (HEAD)");
115
+ router.add("GET", "agent-suite/runtime-settings", async ({ req, res }) => {
116
+ const requestUrl = new URL(String(req.url ?? "/"), "http://localhost");
117
+ const workspaceId = toOptionalUuid(requestUrl.searchParams.get("workspace_id") ??
118
+ requestUrl.searchParams.get("workspaceId") ??
119
+ requestUrl.searchParams.get("command_center_id") ??
120
+ requestUrl.searchParams.get("commandCenterId") ??
121
+ requestUrl.searchParams.get("project_id"));
122
+ try {
123
+ const response = await deps.fetchAgentRuntimeSettings({
124
+ workspaceId: workspaceId ?? null,
125
+ });
126
+ if (!response?.ok) {
127
+ deps.sendJson(res, 200, {
128
+ ok: true,
129
+ data: {
130
+ ...buildRuntimeSettingsFallbackEnvelope(workspaceId ?? null),
131
+ warning: response?.error ?? "Failed to load agent runtime settings",
132
+ },
133
+ });
134
+ return;
135
+ }
136
+ deps.sendJson(res, 200, {
137
+ ok: true,
138
+ data: response,
139
+ });
140
+ }
141
+ catch (err) {
142
+ deps.sendJson(res, 200, {
143
+ ok: true,
144
+ data: {
145
+ ...buildRuntimeSettingsFallbackEnvelope(workspaceId ?? null),
146
+ warning: deps.safeErrorMessage(err),
147
+ },
148
+ });
149
+ }
150
+ }, "List agent runtime settings");
151
+ router.add("PATCH", "agent-suite/runtime-settings", async ({ req, res }) => {
152
+ try {
153
+ const payload = toRecord(await deps.parseJsonRequest(req));
154
+ const agentId = toOptionalString(payload.agent_id ?? payload.agentId)?.trim();
155
+ if (!agentId) {
156
+ deps.sendJson(res, 400, {
157
+ ok: false,
158
+ error: "agent_id is required",
159
+ });
160
+ return;
161
+ }
162
+ const runtimeSettingsPatch = normalizeRuntimeSettingsPatch(payload);
163
+ if (Object.keys(runtimeSettingsPatch).length === 0) {
164
+ deps.sendJson(res, 400, {
165
+ ok: false,
166
+ error: "runtime_settings must include at least one mutable field",
167
+ });
168
+ return;
169
+ }
170
+ const workspaceId = toOptionalUuid(payload.workspace_id ??
171
+ payload.workspaceId ??
172
+ payload.command_center_id ??
173
+ payload.commandCenterId ??
174
+ payload.project_id ??
175
+ payload.projectId);
176
+ const response = await deps.updateAgentRuntimeSettings({
177
+ agent_id: agentId,
178
+ ...(workspaceId
179
+ ? {
180
+ workspace_id: workspaceId,
181
+ command_center_id: workspaceId,
182
+ }
183
+ : {}),
184
+ runtime_settings: runtimeSettingsPatch,
185
+ });
186
+ if (!response?.ok) {
187
+ deps.sendJson(res, 502, {
188
+ ok: false,
189
+ error: response?.error ?? "Failed to update agent runtime settings",
190
+ });
191
+ return;
192
+ }
193
+ deps.sendJson(res, 200, {
194
+ ok: true,
195
+ data: response,
196
+ });
197
+ }
198
+ catch (err) {
199
+ deps.sendJson(res, 500, {
200
+ ok: false,
201
+ error: deps.safeErrorMessage(err),
202
+ });
203
+ }
204
+ }, "Update agent runtime settings");
205
+ router.add("*", "agent-suite/runtime-settings", ({ res }) => {
206
+ deps.sendJson(res, 405, {
207
+ ok: false,
208
+ error: "Use GET/PATCH /orgx/api/agent-suite/runtime-settings",
209
+ });
210
+ }, "Reject unsupported methods for agent-suite/runtime-settings");
57
211
  router.add("POST", "agent-suite/install", async ({ req, res }) => {
58
212
  try {
59
213
  const payload = toRecord(await deps.parseJsonRequest(req));
@@ -141,6 +295,7 @@ export function registerAgentSuiteRoutes(router, deps) {
141
295
  ok: true,
142
296
  data: {
143
297
  policy: state.policy,
298
+ audit: state.audit,
144
299
  pack: state.pack,
145
300
  remote: state.remote,
146
301
  updateAvailable: computeUpdateAvailable(state),
@@ -156,18 +311,56 @@ export function registerAgentSuiteRoutes(router, deps) {
156
311
  const frozen = typeof frozenRaw === "boolean" ? frozenRaw : undefined;
157
312
  const pinToCurrent = readBoolean(payload, "pinToCurrent", "pin_to_current");
158
313
  const clearPin = readBoolean(payload, "clearPin", "clear_pin");
159
- const pinnedChecksumRaw = payload.pinnedChecksum;
314
+ const changedByRaw = payload.changedBy ?? payload.changed_by;
315
+ const changedBy = typeof changedByRaw === "string" ? changedByRaw : undefined;
316
+ const reasonRaw = payload.reason;
317
+ const reason = typeof reasonRaw === "string" ? reasonRaw : undefined;
318
+ const actionRaw = payload.action;
319
+ const action = typeof actionRaw === "string" ? actionRaw.trim().toLowerCase() : "";
320
+ const rollbackToAuditIdRaw = payload.rollbackToAuditId ?? payload.rollback_to_audit_id;
321
+ const rollbackToAuditId = toOptionalString(rollbackToAuditIdRaw)?.trim() || undefined;
322
+ const pinnedChecksumRaw = payload.pinnedChecksum ?? payload.pinned_checksum;
160
323
  const pinnedChecksum = typeof pinnedChecksumRaw === "string"
161
324
  ? pinnedChecksumRaw
162
325
  : pinnedChecksumRaw === null
163
326
  ? null
164
327
  : undefined;
165
- const state = deps.updateSkillPackPolicy({
166
- frozen,
167
- pinToCurrent,
168
- clearPin,
169
- pinnedChecksum,
170
- });
328
+ const hasFrozen = typeof frozen === "boolean";
329
+ const hasPinnedChecksum = typeof pinnedChecksum === "string" || pinnedChecksum === null;
330
+ const hasPinToCurrent = pinToCurrent === true;
331
+ const hasClearPin = clearPin === true;
332
+ const isRollback = action === "rollback" || typeof rollbackToAuditId === "string";
333
+ if (action.length > 0 && action !== "rollback") {
334
+ throw new Error("action must be 'rollback' when provided.");
335
+ }
336
+ if (hasPinToCurrent && hasClearPin) {
337
+ throw new Error("pinToCurrent and clearPin cannot both be true.");
338
+ }
339
+ if (typeof pinnedChecksum === "string" && !pinnedChecksum.trim()) {
340
+ throw new Error("pinnedChecksum must be a non-empty string when provided.");
341
+ }
342
+ if (isRollback) {
343
+ if (hasFrozen || hasPinnedChecksum || hasPinToCurrent || hasClearPin) {
344
+ throw new Error("Rollback requests cannot include update fields (frozen, pinnedChecksum, pinToCurrent, clearPin).");
345
+ }
346
+ }
347
+ else if (!hasFrozen && !hasPinnedChecksum && !hasPinToCurrent && !hasClearPin) {
348
+ throw new Error("Include at least one mutable field: frozen, pinnedChecksum, pinToCurrent, or clearPin.");
349
+ }
350
+ const state = isRollback
351
+ ? deps.rollbackSkillPackPolicy({
352
+ auditId: rollbackToAuditId,
353
+ changedBy,
354
+ reason,
355
+ })
356
+ : deps.updateSkillPackPolicy({
357
+ frozen,
358
+ pinToCurrent,
359
+ clearPin,
360
+ pinnedChecksum: typeof pinnedChecksum === "string" ? pinnedChecksum.trim() : pinnedChecksum,
361
+ changedBy,
362
+ reason,
363
+ });
171
364
  void deps
172
365
  .posthogCapture({
173
366
  event: "openclaw_skill_pack_policy_updated",
@@ -183,7 +376,13 @@ export function registerAgentSuiteRoutes(router, deps) {
183
376
  .catch(() => {
184
377
  // best effort
185
378
  });
186
- deps.sendJson(res, 200, { ok: true, data: state.policy });
379
+ deps.sendJson(res, 200, {
380
+ ok: true,
381
+ data: {
382
+ policy: state.policy,
383
+ audit: state.audit,
384
+ },
385
+ });
187
386
  }
188
387
  catch (err) {
189
388
  deps.sendJson(res, 400, { ok: false, error: deps.safeErrorMessage(err) });
@@ -1,13 +1,26 @@
1
1
  export function registerAgentsCatalogRoutes(router, deps) {
2
2
  async function handle(res) {
3
3
  try {
4
- const [openclawAgents, localSnapshot] = await Promise.all([
5
- deps.listAgents(),
6
- deps.loadLocalSnapshot(),
7
- ]);
4
+ let openclawAgents = [];
5
+ let openclawAgentsError = null;
6
+ try {
7
+ const fetched = await deps.listAgents();
8
+ openclawAgents = Array.isArray(fetched) ? fetched : [];
9
+ }
10
+ catch (err) {
11
+ openclawAgentsError = deps.safeErrorMessage(err);
12
+ }
13
+ const localSnapshot = await deps.loadLocalSnapshot().catch(() => null);
14
+ const localAgents = Array.isArray(localSnapshot?.agents)
15
+ ? localSnapshot.agents
16
+ : [];
17
+ const warnings = [];
18
+ if (openclawAgentsError) {
19
+ warnings.push(`openclaw agent discovery unavailable: ${openclawAgentsError}`);
20
+ }
8
21
  const localById = new Map();
9
- if (localSnapshot) {
10
- for (const agent of localSnapshot.agents) {
22
+ if (localAgents.length > 0) {
23
+ for (const agent of localAgents) {
11
24
  localById.set(agent.id, {
12
25
  status: agent.status,
13
26
  currentTask: agent.currentTask,
@@ -17,9 +30,22 @@ export function registerAgentsCatalogRoutes(router, deps) {
17
30
  });
18
31
  }
19
32
  }
20
- const contexts = deps.readAgentContexts().agents;
21
- const runs = deps.readAgentRuns().runs;
33
+ let contexts = {};
34
+ try {
35
+ contexts = deps.readAgentContexts().agents ?? {};
36
+ }
37
+ catch (err) {
38
+ warnings.push(`agent context snapshot unavailable: ${deps.safeErrorMessage(err)}`);
39
+ }
40
+ let runs = {};
41
+ try {
42
+ runs = deps.readAgentRuns().runs ?? {};
43
+ }
44
+ catch (err) {
45
+ warnings.push(`agent run snapshot unavailable: ${deps.safeErrorMessage(err)}`);
46
+ }
22
47
  const latestRunByAgent = new Map();
48
+ const openclawById = new Map();
23
49
  for (const run of Object.values(runs)) {
24
50
  if (!run || typeof run !== "object")
25
51
  continue;
@@ -43,21 +69,39 @@ export function registerAgentsCatalogRoutes(router, deps) {
43
69
  latestRunByAgent.set(agentId, run);
44
70
  }
45
71
  }
46
- const agents = openclawAgents.map((entry) => {
72
+ for (const entry of openclawAgents) {
47
73
  const id = typeof entry.id === "string" ? entry.id.trim() : "";
48
- const name = typeof entry.name === "string" && entry.name.trim().length > 0
74
+ if (!id)
75
+ continue;
76
+ openclawById.set(id, entry);
77
+ }
78
+ const candidateAgentIds = new Set();
79
+ for (const id of openclawById.keys())
80
+ candidateAgentIds.add(id);
81
+ for (const id of localById.keys())
82
+ candidateAgentIds.add(id);
83
+ for (const id of Object.keys(contexts ?? {})) {
84
+ const normalized = id.trim();
85
+ if (normalized)
86
+ candidateAgentIds.add(normalized);
87
+ }
88
+ for (const id of latestRunByAgent.keys())
89
+ candidateAgentIds.add(id);
90
+ const agents = [...candidateAgentIds].sort((a, b) => a.localeCompare(b)).map((agentId) => {
91
+ const entry = openclawById.get(agentId) ?? null;
92
+ const name = typeof entry?.name === "string" && entry.name.trim().length > 0
49
93
  ? entry.name.trim()
50
- : id || "unknown";
51
- const local = id ? localById.get(id) ?? null : null;
52
- const context = id ? contexts[id] ?? null : null;
53
- const runFromSession = id && local?.runId ? runs[local.runId] ?? null : null;
54
- const run = runFromSession ?? (id ? latestRunByAgent.get(id) ?? null : null);
94
+ : agentId || "unknown";
95
+ const local = localById.get(agentId) ?? null;
96
+ const context = contexts[agentId] ?? null;
97
+ const runFromSession = local?.runId ? runs[local.runId] ?? null : null;
98
+ const run = runFromSession ?? (latestRunByAgent.get(agentId) ?? null);
55
99
  return {
56
- id,
100
+ id: agentId,
57
101
  name,
58
- workspace: typeof entry.workspace === "string" ? entry.workspace : null,
59
- model: typeof entry.model === "string" ? entry.model : null,
60
- isDefault: Boolean(entry.isDefault),
102
+ workspace: typeof entry?.workspace === "string" ? entry.workspace : null,
103
+ model: typeof entry?.model === "string" ? entry.model : null,
104
+ isDefault: Boolean(entry?.isDefault),
61
105
  status: local?.status ?? null,
62
106
  currentTask: local?.currentTask ?? null,
63
107
  runId: local?.runId ?? null,
@@ -70,6 +114,7 @@ export function registerAgentsCatalogRoutes(router, deps) {
70
114
  deps.sendJson(res, 200, {
71
115
  generatedAt: new Date().toISOString(),
72
116
  agents,
117
+ ...(warnings.length > 0 ? { warnings } : {}),
73
118
  });
74
119
  }
75
120
  catch (err) {
@@ -0,0 +1,19 @@
1
+ import type { Router } from "../router.js";
2
+ type JsonRecord = Record<string, unknown>;
3
+ type RegisterChatRoutesDeps<TReq, TRes> = {
4
+ parseJsonRequest: (req: TReq) => Promise<JsonRecord>;
5
+ pickString: (input: Record<string, unknown>, keys: string[]) => string | null;
6
+ parsePositiveInt: (raw: string | null, fallback: number) => number;
7
+ emitActivitySafe?: (input: {
8
+ initiativeId: string | null;
9
+ sourceClient?: string;
10
+ message: string;
11
+ phase: "intent" | "execution" | "blocked" | "review" | "handoff" | "completed";
12
+ progressPct?: number;
13
+ metadata?: Record<string, unknown>;
14
+ }) => Promise<unknown>;
15
+ sendJson: (res: TRes, status: number, payload: unknown) => void;
16
+ safeErrorMessage: (err: unknown) => string;
17
+ };
18
+ export declare function registerChatRoutes<TReq, TRes>(router: Router<Record<string, never>, TReq, TRes>, deps: RegisterChatRoutesDeps<TReq, TRes>): void;
19
+ export {};