@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.
Files changed (284) 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 +38 -26
  88. package/dist/agent-context-store.js +84 -42
  89. package/dist/agent-run-store.js +49 -28
  90. package/dist/agent-suite.d.ts +9 -0
  91. package/dist/agent-suite.js +150 -17
  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/auth/flows.d.ts +47 -0
  97. package/dist/auth/flows.js +169 -0
  98. package/dist/auth-store.js +6 -26
  99. package/dist/byok-store.js +5 -19
  100. package/dist/chat-store.d.ts +157 -0
  101. package/dist/chat-store.js +586 -0
  102. package/dist/cli/orgx.d.ts +66 -0
  103. package/dist/cli/orgx.js +102 -0
  104. package/dist/config/refresh.d.ts +32 -0
  105. package/dist/config/refresh.js +55 -0
  106. package/dist/config/resolution.d.ts +37 -0
  107. package/dist/config/resolution.js +178 -0
  108. package/dist/contracts/client.d.ts +43 -3
  109. package/dist/contracts/client.js +159 -30
  110. package/dist/contracts/retro-schema.d.ts +81 -0
  111. package/dist/contracts/retro-schema.js +80 -0
  112. package/dist/contracts/shared-types.d.ts +306 -0
  113. package/dist/contracts/shared-types.js +179 -0
  114. package/dist/contracts/skill-pack-schema.d.ts +192 -0
  115. package/dist/contracts/skill-pack-schema.js +180 -0
  116. package/dist/contracts/types.d.ts +224 -132
  117. package/dist/contracts/types.js +5 -0
  118. package/dist/entities/auto-assignment.d.ts +36 -0
  119. package/dist/entities/auto-assignment.js +141 -0
  120. package/dist/entity-comment-store.js +5 -25
  121. package/dist/event-sanitization.d.ts +11 -0
  122. package/dist/event-sanitization.js +113 -0
  123. package/dist/fs-utils.js +13 -1
  124. package/dist/gateway-watchdog.d.ts +5 -0
  125. package/dist/gateway-watchdog.js +50 -0
  126. package/dist/hash-utils.d.ts +2 -0
  127. package/dist/hash-utils.js +12 -0
  128. package/dist/hooks/post-reporting-event.mjs +1 -5
  129. package/dist/http/helpers/activity-headline.d.ts +10 -0
  130. package/dist/http/helpers/activity-headline.js +73 -0
  131. package/dist/http/helpers/artifact-fallback.d.ts +13 -0
  132. package/dist/http/helpers/artifact-fallback.js +148 -0
  133. package/dist/http/helpers/auto-continue-engine.d.ts +486 -0
  134. package/dist/http/helpers/auto-continue-engine.js +3563 -0
  135. package/dist/http/helpers/autopilot-operations.d.ts +176 -0
  136. package/dist/http/helpers/autopilot-operations.js +554 -0
  137. package/dist/http/helpers/autopilot-runtime.d.ts +43 -0
  138. package/dist/http/helpers/autopilot-runtime.js +607 -0
  139. package/dist/http/helpers/autopilot-slice-utils.d.ts +56 -0
  140. package/dist/http/helpers/autopilot-slice-utils.js +899 -0
  141. package/dist/http/helpers/decision-mapper.d.ts +52 -0
  142. package/dist/http/helpers/decision-mapper.js +260 -0
  143. package/dist/http/helpers/dispatch-lifecycle.d.ts +119 -0
  144. package/dist/http/helpers/dispatch-lifecycle.js +809 -0
  145. package/dist/http/helpers/hash-utils.d.ts +1 -0
  146. package/dist/http/helpers/hash-utils.js +1 -0
  147. package/dist/http/helpers/kickoff-context.d.ts +12 -0
  148. package/dist/http/helpers/kickoff-context.js +228 -0
  149. package/dist/http/helpers/llm-client.d.ts +47 -0
  150. package/dist/http/helpers/llm-client.js +256 -0
  151. package/dist/http/helpers/mission-control.d.ts +193 -0
  152. package/dist/http/helpers/mission-control.js +1383 -0
  153. package/dist/http/helpers/openclaw-cli.d.ts +37 -0
  154. package/dist/http/helpers/openclaw-cli.js +283 -0
  155. package/dist/http/helpers/runtime-sse.d.ts +20 -0
  156. package/dist/http/helpers/runtime-sse.js +110 -0
  157. package/dist/http/helpers/sentinel-catalog.d.ts +23 -0
  158. package/dist/http/helpers/sentinel-catalog.js +193 -0
  159. package/dist/http/helpers/session-classification.d.ts +9 -0
  160. package/dist/http/helpers/session-classification.js +564 -0
  161. package/dist/http/helpers/slice-experience-v2.d.ts +137 -0
  162. package/dist/http/helpers/slice-experience-v2.js +677 -0
  163. package/dist/http/helpers/slice-run-projections.d.ts +72 -0
  164. package/dist/http/helpers/slice-run-projections.js +860 -0
  165. package/dist/http/helpers/triage-mapper.d.ts +43 -0
  166. package/dist/http/helpers/triage-mapper.js +549 -0
  167. package/dist/http/helpers/value-utils.d.ts +6 -0
  168. package/dist/http/helpers/value-utils.js +72 -0
  169. package/dist/http/helpers/workspace-scope.d.ts +15 -0
  170. package/dist/http/helpers/workspace-scope.js +170 -0
  171. package/dist/http/index.d.ts +88 -0
  172. package/dist/http/index.js +3610 -0
  173. package/dist/http/router.d.ts +23 -0
  174. package/dist/http/router.js +23 -0
  175. package/dist/http/routes/agent-control.d.ts +79 -0
  176. package/dist/http/routes/agent-control.js +684 -0
  177. package/dist/http/routes/agent-suite.d.ts +38 -0
  178. package/dist/http/routes/agent-suite.js +397 -0
  179. package/dist/http/routes/agents-catalog.d.ts +40 -0
  180. package/dist/http/routes/agents-catalog.js +128 -0
  181. package/dist/http/routes/billing.d.ts +23 -0
  182. package/dist/http/routes/billing.js +55 -0
  183. package/dist/http/routes/chat.d.ts +19 -0
  184. package/dist/http/routes/chat.js +522 -0
  185. package/dist/http/routes/debug.d.ts +14 -0
  186. package/dist/http/routes/debug.js +21 -0
  187. package/dist/http/routes/decision-actions.d.ts +20 -0
  188. package/dist/http/routes/decision-actions.js +103 -0
  189. package/dist/http/routes/delegation.d.ts +19 -0
  190. package/dist/http/routes/delegation.js +32 -0
  191. package/dist/http/routes/dispatch-gateway-envelope.d.ts +25 -0
  192. package/dist/http/routes/dispatch-gateway-envelope.js +26 -0
  193. package/dist/http/routes/entities.d.ts +63 -0
  194. package/dist/http/routes/entities.js +440 -0
  195. package/dist/http/routes/entity-dynamic.d.ts +25 -0
  196. package/dist/http/routes/entity-dynamic.js +191 -0
  197. package/dist/http/routes/health.d.ts +22 -0
  198. package/dist/http/routes/health.js +49 -0
  199. package/dist/http/routes/live-legacy.d.ts +115 -0
  200. package/dist/http/routes/live-legacy.js +112 -0
  201. package/dist/http/routes/live-misc.d.ts +81 -0
  202. package/dist/http/routes/live-misc.js +426 -0
  203. package/dist/http/routes/live-snapshot.d.ts +136 -0
  204. package/dist/http/routes/live-snapshot.js +916 -0
  205. package/dist/http/routes/live-terminal.d.ts +11 -0
  206. package/dist/http/routes/live-terminal.js +261 -0
  207. package/dist/http/routes/live-triage.d.ts +61 -0
  208. package/dist/http/routes/live-triage.js +248 -0
  209. package/dist/http/routes/mission-control-actions.d.ts +131 -0
  210. package/dist/http/routes/mission-control-actions.js +1791 -0
  211. package/dist/http/routes/mission-control-read.d.ts +73 -0
  212. package/dist/http/routes/mission-control-read.js +1640 -0
  213. package/dist/http/routes/onboarding.d.ts +34 -0
  214. package/dist/http/routes/onboarding.js +101 -0
  215. package/dist/http/routes/realtime-orchestrator.d.ts +10 -0
  216. package/dist/http/routes/realtime-orchestrator.js +74 -0
  217. package/dist/http/routes/run-control.d.ts +27 -0
  218. package/dist/http/routes/run-control.js +96 -0
  219. package/dist/http/routes/runtime-hooks.d.ts +69 -0
  220. package/dist/http/routes/runtime-hooks.js +437 -0
  221. package/dist/http/routes/sentinels-catalog.d.ts +7 -0
  222. package/dist/http/routes/sentinels-catalog.js +24 -0
  223. package/dist/http/routes/settings-byok.d.ts +23 -0
  224. package/dist/http/routes/settings-byok.js +163 -0
  225. package/dist/http/routes/summary.d.ts +18 -0
  226. package/dist/http/routes/summary.js +49 -0
  227. package/dist/http/routes/usage.d.ts +24 -0
  228. package/dist/http/routes/usage.js +362 -0
  229. package/dist/http/routes/work-artifacts.d.ts +9 -0
  230. package/dist/http/routes/work-artifacts.js +55 -0
  231. package/dist/http/shared-state.d.ts +16 -0
  232. package/dist/http/shared-state.js +1 -0
  233. package/dist/http-handler.d.ts +1 -88
  234. package/dist/http-handler.js +1 -10605
  235. package/dist/index.js +287 -2284
  236. package/dist/json-utils.d.ts +1 -0
  237. package/dist/json-utils.js +8 -0
  238. package/dist/local-openclaw.js +29 -6
  239. package/dist/mcp-client-setup.js +3 -3
  240. package/dist/mcp-http-handler.js +33 -59
  241. package/dist/next-up-queue-store.d.ts +16 -1
  242. package/dist/next-up-queue-store.js +93 -25
  243. package/dist/outbox.d.ts +5 -0
  244. package/dist/outbox.js +113 -9
  245. package/dist/paths.js +24 -5
  246. package/dist/reporting/rollups.d.ts +53 -0
  247. package/dist/reporting/rollups.js +148 -0
  248. package/dist/retro/domain-templates.d.ts +45 -0
  249. package/dist/retro/domain-templates.js +297 -0
  250. package/dist/retro/quality-rubric.d.ts +33 -0
  251. package/dist/retro/quality-rubric.js +213 -0
  252. package/dist/runtime-cleanup.d.ts +18 -0
  253. package/dist/runtime-cleanup.js +87 -0
  254. package/dist/runtime-instance-store.js +5 -31
  255. package/dist/services/background.d.ts +34 -0
  256. package/dist/services/background.js +45 -0
  257. package/dist/services/experiment-randomization.d.ts +21 -0
  258. package/dist/services/experiment-randomization.js +63 -0
  259. package/dist/services/instrumentation.d.ts +29 -0
  260. package/dist/services/instrumentation.js +136 -0
  261. package/dist/skill-pack-state.d.ts +36 -5
  262. package/dist/skill-pack-state.js +273 -29
  263. package/dist/snapshot-store.js +5 -25
  264. package/dist/stores/json-store.d.ts +11 -0
  265. package/dist/stores/json-store.js +42 -0
  266. package/dist/sync/local-agent-telemetry.d.ts +13 -0
  267. package/dist/sync/local-agent-telemetry.js +128 -0
  268. package/dist/sync/outbox-replay.d.ts +55 -0
  269. package/dist/sync/outbox-replay.js +621 -0
  270. package/dist/team-context-store.d.ts +23 -0
  271. package/dist/team-context-store.js +116 -0
  272. package/dist/telemetry/posthog.js +4 -2
  273. package/dist/tools/core-tools.d.ts +72 -0
  274. package/dist/tools/core-tools.js +2270 -0
  275. package/dist/types.d.ts +2 -0
  276. package/dist/types.js +2 -0
  277. package/dist/worker-supervisor.js +23 -0
  278. package/package.json +14 -4
  279. package/dashboard/dist/assets/B3ziCA02.js +0 -8
  280. package/dashboard/dist/assets/BNeJ0kpF.js +0 -1
  281. package/dashboard/dist/assets/BzkiMPmM.js +0 -215
  282. package/dashboard/dist/assets/CUV9IHHi.js +0 -1
  283. package/dashboard/dist/assets/Ie7d9Iq2.css +0 -1
  284. package/dashboard/dist/assets/sAhvFnpk.js +0 -4
@@ -0,0 +1,426 @@
1
+ import { resolveWorkspaceScope, workspaceScopeFromHeaders, } from "../helpers/workspace-scope.js";
2
+ function asRecord(input) {
3
+ if (!input || typeof input !== "object" || Array.isArray(input))
4
+ return null;
5
+ return input;
6
+ }
7
+ function pickStringFromRecord(input, keys) {
8
+ if (!input)
9
+ return null;
10
+ for (const key of keys) {
11
+ const value = input[key];
12
+ if (typeof value !== "string")
13
+ continue;
14
+ const normalized = value.trim();
15
+ if (normalized.length > 0)
16
+ return normalized;
17
+ }
18
+ return null;
19
+ }
20
+ function resolveInitiativeIdFromRecord(input) {
21
+ const direct = pickStringFromRecord(input, ["initiativeId", "initiative_id", "initiative"]);
22
+ if (direct)
23
+ return direct;
24
+ const metadata = asRecord(input.metadata);
25
+ return pickStringFromRecord(metadata, ["initiativeId", "initiative_id", "initiative"]);
26
+ }
27
+ export function registerLiveMiscRoutes(router, deps) {
28
+ async function resolveProjectInitiativeSet(projectIdRaw) {
29
+ const projectId = projectIdRaw?.trim() ?? "";
30
+ if (!projectId)
31
+ return null;
32
+ const ids = await deps.listInitiativeIdsForProject({ projectId });
33
+ return new Set(ids);
34
+ }
35
+ router.add("POST", "live/activity/headline", async ({ req, res }) => {
36
+ try {
37
+ const payload = await deps.parseJsonRequest(req);
38
+ const text = deps.pickString(payload, ["text", "summary", "detail", "content"]);
39
+ if (!text) {
40
+ deps.sendJson(res, 400, { error: "text is required" });
41
+ return;
42
+ }
43
+ const title = deps.pickString(payload, ["title", "name"]);
44
+ const type = deps.pickString(payload, ["type", "kind"]);
45
+ const result = await deps.summarizeActivityHeadline({
46
+ text,
47
+ title,
48
+ type,
49
+ });
50
+ deps.sendJson(res, 200, {
51
+ headline: result.headline,
52
+ source: result.source,
53
+ model: result.model,
54
+ });
55
+ }
56
+ catch (err) {
57
+ deps.sendJson(res, 500, {
58
+ error: deps.safeErrorMessage(err),
59
+ });
60
+ }
61
+ }, "Summarize an activity headline");
62
+ router.add("*", "live/activity/headline", ({ res }) => {
63
+ deps.sendJson(res, 405, { error: "Use POST /orgx/api/live/activity/headline" });
64
+ }, "Reject unsupported methods for live/activity/headline");
65
+ async function renderLiveAgents(query, res, headerScope) {
66
+ const scope = resolveWorkspaceScope(query, headerScope, {
67
+ allowProjectScope: false,
68
+ });
69
+ if (scope.error) {
70
+ deps.sendJson(res, 400, { error: scope.error });
71
+ return;
72
+ }
73
+ const workspaceId = scope.workspaceId;
74
+ try {
75
+ const initiative = query.get("initiative");
76
+ const projectInitiatives = await resolveProjectInitiativeSet(workspaceId);
77
+ const includeIdleRaw = query.get("include_idle");
78
+ const includeIdle = includeIdleRaw === null ? undefined : includeIdleRaw !== "false";
79
+ const data = (await deps.getLiveAgents({
80
+ initiative,
81
+ projectId: workspaceId,
82
+ includeIdle,
83
+ }));
84
+ const agents = Array.isArray(data.agents) ? data.agents : [];
85
+ const scopedAgents = agents.filter((entry) => {
86
+ const row = asRecord(entry);
87
+ if (!row)
88
+ return false;
89
+ const initiativeId = resolveInitiativeIdFromRecord(row);
90
+ if (initiative && initiative.trim().length > 0 && initiativeId !== initiative)
91
+ return false;
92
+ if (projectInitiatives && (!initiativeId || !projectInitiatives.has(initiativeId))) {
93
+ return false;
94
+ }
95
+ if (includeIdle === false) {
96
+ const status = pickStringFromRecord(row, ["status"]);
97
+ if (status === "idle")
98
+ return false;
99
+ }
100
+ return true;
101
+ });
102
+ const summary = scopedAgents.reduce((acc, entry) => {
103
+ const row = asRecord(entry);
104
+ const status = pickStringFromRecord(row, ["status"]) ?? "unknown";
105
+ acc[status] = (acc[status] ?? 0) + 1;
106
+ return acc;
107
+ }, {});
108
+ deps.sendJson(res, 200, {
109
+ ...data,
110
+ agents: scopedAgents,
111
+ summary,
112
+ });
113
+ }
114
+ catch (err) {
115
+ try {
116
+ const initiative = query.get("initiative");
117
+ const projectInitiatives = await resolveProjectInitiativeSet(workspaceId);
118
+ const includeIdleRaw = query.get("include_idle");
119
+ const includeIdle = includeIdleRaw === null ? undefined : includeIdleRaw !== "false";
120
+ const localSnapshot = await deps.loadLocalOpenClawSnapshot(240);
121
+ const local = deps.toLocalLiveAgents(localSnapshot);
122
+ let agents = local.agents;
123
+ if (initiative && initiative.trim().length > 0) {
124
+ agents = agents.filter((agent) => agent.initiativeId === initiative);
125
+ }
126
+ if (projectInitiatives) {
127
+ agents = agents.filter((agent) => {
128
+ const initiativeId = typeof agent.initiativeId === "string" ? agent.initiativeId : "";
129
+ return initiativeId.length > 0 && projectInitiatives.has(initiativeId);
130
+ });
131
+ }
132
+ if (includeIdle === false) {
133
+ agents = agents.filter((agent) => agent.status !== "idle");
134
+ }
135
+ const summary = agents.reduce((acc, agent) => {
136
+ acc[agent.status] = (acc[agent.status] ?? 0) + 1;
137
+ return acc;
138
+ }, {});
139
+ deps.sendJson(res, 200, { agents, summary });
140
+ }
141
+ catch (localErr) {
142
+ deps.sendJson(res, 500, {
143
+ error: deps.safeErrorMessage(err),
144
+ localFallbackError: deps.safeErrorMessage(localErr),
145
+ });
146
+ }
147
+ }
148
+ }
149
+ router.add("GET", "live/agents", async ({ query, res, req }) => renderLiveAgents(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live agents");
150
+ router.add("HEAD", "live/agents", async ({ query, res, req }) => renderLiveAgents(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live agents (HEAD)");
151
+ async function renderLiveInitiatives(query, res, headerScope) {
152
+ const scope = resolveWorkspaceScope(query, headerScope, {
153
+ allowProjectScope: false,
154
+ });
155
+ if (scope.error) {
156
+ deps.sendJson(res, 400, { error: scope.error });
157
+ return;
158
+ }
159
+ const workspaceId = scope.workspaceId;
160
+ try {
161
+ const id = query.get("id");
162
+ const projectInitiatives = await resolveProjectInitiativeSet(workspaceId);
163
+ const limitRaw = query.get("limit") ? Number(query.get("limit")) : undefined;
164
+ const offsetRaw = query.get("offset") ? Number(query.get("offset")) : undefined;
165
+ const requestedLimit = Number.isFinite(limitRaw)
166
+ ? Math.max(1, Math.floor(Number(limitRaw)))
167
+ : null;
168
+ const requestedOffset = Number.isFinite(offsetRaw)
169
+ ? Math.max(0, Math.floor(Number(offsetRaw)))
170
+ : 0;
171
+ const data = await deps.getLiveInitiatives({
172
+ id,
173
+ projectId: workspaceId,
174
+ limit: requestedLimit ?? undefined,
175
+ offset: requestedOffset,
176
+ });
177
+ const payload = data;
178
+ const rawInitiatives = Array.isArray(payload.initiatives) ? payload.initiatives : [];
179
+ const applyLocalOverrides = (rows) => rows.map((entry) => {
180
+ if (!entry || typeof entry !== "object")
181
+ return entry;
182
+ const row = entry;
183
+ const initiativeId = deps.pickString(row, ["id"]);
184
+ if (!initiativeId)
185
+ return entry;
186
+ const override = deps.localInitiativeStatusOverrides.get(initiativeId) ?? null;
187
+ if (!override)
188
+ return entry;
189
+ return {
190
+ ...row,
191
+ status: override.status,
192
+ updatedAt: deps.pickString(row, ["updatedAt", "updated_at"]) ?? override.updatedAt,
193
+ };
194
+ });
195
+ let initiatives = Array.isArray(payload.initiatives)
196
+ ? payload.initiatives
197
+ .filter((entry) => {
198
+ const row = asRecord(entry);
199
+ if (!row)
200
+ return false;
201
+ const initiativeId = deps.pickString(row, ["id"]);
202
+ if (!initiativeId)
203
+ return false;
204
+ if (id && id.trim().length > 0 && initiativeId !== id)
205
+ return false;
206
+ if (projectInitiatives && !projectInitiatives.has(initiativeId))
207
+ return false;
208
+ return true;
209
+ })
210
+ .map((entry) => entry)
211
+ : payload.initiatives;
212
+ initiatives = Array.isArray(initiatives) ? applyLocalOverrides(initiatives) : initiatives;
213
+ let fallbackHydratedFromScope = false;
214
+ if (Array.isArray(initiatives) &&
215
+ initiatives.length === 0 &&
216
+ !id &&
217
+ projectInitiatives &&
218
+ projectInitiatives.size > 0) {
219
+ const scopedIds = Array.from(projectInitiatives.values()).slice(requestedOffset, requestedOffset + (requestedLimit ?? 50));
220
+ const hydrated = [];
221
+ for (const initiativeId of scopedIds) {
222
+ try {
223
+ const single = await deps.getLiveInitiatives({
224
+ id: initiativeId,
225
+ projectId: null,
226
+ limit: 1,
227
+ offset: 0,
228
+ });
229
+ const singleRows = Array.isArray(single?.initiatives)
230
+ ? single.initiatives
231
+ : [];
232
+ const match = singleRows.find((entry) => {
233
+ const row = asRecord(entry);
234
+ const rowId = deps.pickString(row ?? {}, ["id"]);
235
+ return rowId === initiativeId;
236
+ });
237
+ if (match)
238
+ hydrated.push(match);
239
+ }
240
+ catch {
241
+ // Ignore per-initiative hydration failures and continue with remaining IDs.
242
+ }
243
+ }
244
+ if (hydrated.length > 0) {
245
+ initiatives = applyLocalOverrides(hydrated);
246
+ fallbackHydratedFromScope = true;
247
+ }
248
+ }
249
+ const remotePagination = asRecord(payload.pagination);
250
+ const remoteHasMoreComputed = typeof remotePagination?.has_more === "boolean"
251
+ ? remotePagination.has_more
252
+ : typeof payload.total === "number"
253
+ ? requestedOffset + rawInitiatives.length < payload.total
254
+ : requestedLimit !== null
255
+ ? rawInitiatives.length >= requestedLimit
256
+ : false;
257
+ const scopedTotal = fallbackHydratedFromScope && projectInitiatives
258
+ ? projectInitiatives.size
259
+ : Array.isArray(initiatives)
260
+ ? initiatives.length
261
+ : 0;
262
+ const scopedHasMore = fallbackHydratedFromScope && projectInitiatives
263
+ ? requestedOffset + (Array.isArray(initiatives) ? initiatives.length : 0) <
264
+ projectInitiatives.size
265
+ : remoteHasMoreComputed;
266
+ deps.sendJson(res, 200, {
267
+ ...payload,
268
+ initiatives,
269
+ total: scopedTotal,
270
+ pagination: {
271
+ ...(remotePagination ?? {}),
272
+ limit: typeof remotePagination?.limit === "number"
273
+ ? remotePagination.limit
274
+ : (requestedLimit ?? rawInitiatives.length),
275
+ offset: typeof remotePagination?.offset === "number"
276
+ ? remotePagination.offset
277
+ : requestedOffset,
278
+ has_more: scopedHasMore,
279
+ },
280
+ ...(fallbackHydratedFromScope
281
+ ? {
282
+ scopedFallback: true,
283
+ scopedFallbackReason: "upstream live initiatives page did not contain requested workspace rows",
284
+ }
285
+ : {}),
286
+ });
287
+ }
288
+ catch (err) {
289
+ try {
290
+ const id = query.get("id");
291
+ const projectInitiatives = await resolveProjectInitiativeSet(workspaceId);
292
+ const limitRaw = query.get("limit") ? Number(query.get("limit")) : undefined;
293
+ const offsetRaw = query.get("offset") ? Number(query.get("offset")) : undefined;
294
+ const limit = Number.isFinite(limitRaw) ? Math.max(1, Number(limitRaw)) : 100;
295
+ const offset = Number.isFinite(offsetRaw) ? Math.max(0, Number(offsetRaw)) : 0;
296
+ const local = deps.toLocalLiveInitiatives(await deps.loadLocalOpenClawSnapshot(240));
297
+ let initiatives = local.initiatives;
298
+ if (id && id.trim().length > 0) {
299
+ initiatives = initiatives.filter((item) => item.id === id);
300
+ }
301
+ if (projectInitiatives) {
302
+ initiatives = initiatives.filter((item) => projectInitiatives.has(item.id));
303
+ }
304
+ initiatives = initiatives.map((item) => {
305
+ const override = deps.localInitiativeStatusOverrides.get(item.id) ?? null;
306
+ if (!override)
307
+ return item;
308
+ return {
309
+ ...item,
310
+ status: override.status,
311
+ updatedAt: item.updatedAt ?? override.updatedAt,
312
+ };
313
+ });
314
+ const requestedId = id?.trim() ?? "";
315
+ if (requestedId.length > 0) {
316
+ const override = deps.localInitiativeStatusOverrides.get(requestedId) ?? null;
317
+ const allowedByProject = !projectInitiatives || projectInitiatives.has(requestedId);
318
+ if (override &&
319
+ allowedByProject &&
320
+ !initiatives.some((item) => item.id === requestedId)) {
321
+ initiatives.push({
322
+ id: requestedId,
323
+ title: `Initiative ${requestedId.slice(0, 8)}`,
324
+ status: override.status,
325
+ updatedAt: override.updatedAt,
326
+ sessionCount: 0,
327
+ activeAgents: 0,
328
+ });
329
+ }
330
+ }
331
+ else {
332
+ for (const [initiativeId, override] of deps.localInitiativeStatusOverrides.entries()) {
333
+ if (projectInitiatives && !projectInitiatives.has(initiativeId))
334
+ continue;
335
+ if (initiatives.some((item) => item.id === initiativeId))
336
+ continue;
337
+ initiatives.push({
338
+ id: initiativeId,
339
+ title: `Initiative ${initiativeId.slice(0, 8)}`,
340
+ status: override.status,
341
+ updatedAt: override.updatedAt,
342
+ sessionCount: 0,
343
+ activeAgents: 0,
344
+ });
345
+ }
346
+ }
347
+ const total = initiatives.length;
348
+ const page = initiatives.slice(offset, offset + limit);
349
+ deps.sendJson(res, 200, {
350
+ initiatives: page,
351
+ total,
352
+ pagination: {
353
+ limit,
354
+ offset,
355
+ has_more: offset + page.length < total,
356
+ },
357
+ localFallback: true,
358
+ warning: deps.safeErrorMessage(err),
359
+ });
360
+ }
361
+ catch (localErr) {
362
+ deps.sendJson(res, 500, {
363
+ error: deps.safeErrorMessage(err),
364
+ localFallbackError: deps.safeErrorMessage(localErr),
365
+ });
366
+ }
367
+ }
368
+ }
369
+ router.add("GET", "live/initiatives", async ({ query, res, req }) => renderLiveInitiatives(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live initiatives");
370
+ router.add("HEAD", "live/initiatives", async ({ query, res, req }) => renderLiveInitiatives(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live initiatives (HEAD)");
371
+ async function renderLiveDecisions(query, res, headerScope) {
372
+ const scope = resolveWorkspaceScope(query, headerScope, {
373
+ allowProjectScope: false,
374
+ });
375
+ if (scope.error) {
376
+ deps.sendJson(res, 400, { error: scope.error });
377
+ return;
378
+ }
379
+ const workspaceId = scope.workspaceId;
380
+ try {
381
+ const status = query.get("status") ?? "pending";
382
+ const projectInitiatives = await resolveProjectInitiativeSet(workspaceId);
383
+ const limit = query.get("limit") ? Number(query.get("limit")) : 100;
384
+ const data = await deps.getLiveDecisions({
385
+ status,
386
+ projectId: workspaceId,
387
+ limit: Number.isFinite(limit) ? limit : 100,
388
+ });
389
+ const decisions = data.decisions
390
+ .map(deps.mapDecisionEntity)
391
+ .filter((entry) => {
392
+ if (!projectInitiatives)
393
+ return true;
394
+ const row = asRecord(entry);
395
+ if (!row)
396
+ return false;
397
+ const initiativeId = resolveInitiativeIdFromRecord(row);
398
+ return Boolean(initiativeId && projectInitiatives.has(initiativeId));
399
+ })
400
+ .sort((a, b) => b.waitingMinutes - a.waitingMinutes);
401
+ deps.sendJson(res, 200, {
402
+ decisions,
403
+ total: decisions.length,
404
+ });
405
+ }
406
+ catch {
407
+ deps.sendJson(res, 200, {
408
+ decisions: [],
409
+ total: 0,
410
+ });
411
+ }
412
+ }
413
+ router.add("GET", "live/decisions", async ({ query, res, req }) => renderLiveDecisions(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live decisions");
414
+ router.add("HEAD", "live/decisions", async ({ query, res, req }) => renderLiveDecisions(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live decisions (HEAD)");
415
+ async function renderHandoffs(res) {
416
+ try {
417
+ const data = await deps.getHandoffs();
418
+ deps.sendJson(res, 200, data);
419
+ }
420
+ catch {
421
+ deps.sendJson(res, 200, { handoffs: [] });
422
+ }
423
+ }
424
+ router.add("GET", "handoffs", async ({ res }) => renderHandoffs(res), "Get handoffs");
425
+ router.add("HEAD", "handoffs", async ({ res }) => renderHandoffs(res), "Get handoffs (HEAD)");
426
+ }
@@ -0,0 +1,136 @@
1
+ import type { HandoffSummary, LiveActivityItem, SessionTreeResponse } from "../../types.js";
2
+ import type { RuntimeInstanceRecord } from "../../runtime-instance-store.js";
3
+ import type { OutboxSummary } from "../../outbox.js";
4
+ import type { ChatThreadSummary } from "../../chat-store.js";
5
+ import type { AgentLaunchContext, RunLaunchContext } from "../../agent-context-store.js";
6
+ import type { Router } from "../router.js";
7
+ type LocalSnapshot = Awaited<ReturnType<typeof import("../../local-openclaw.js").loadLocalOpenClawSnapshot>>;
8
+ type AgentContextState = {
9
+ agents: Record<string, AgentLaunchContext>;
10
+ runs?: Record<string, RunLaunchContext>;
11
+ };
12
+ type SnapshotPersistState = {
13
+ lastFingerprint: string;
14
+ lastPersistAt: number;
15
+ };
16
+ type LiveSnapshotRoutesDeps<TReq, TRes> = {
17
+ parsePositiveInt: (raw: string | null, fallback: number) => number;
18
+ readSnapshotResponseCache: (key: string) => Record<string, unknown> | null;
19
+ writeSnapshotResponseCache: (key: string, payload: Record<string, unknown>) => void;
20
+ safeErrorMessage: (err: unknown) => string;
21
+ readAgentContexts: () => AgentContextState;
22
+ getScopedAgentIds: (contexts: Record<string, AgentLaunchContext>) => Set<string>;
23
+ readDiagnosticsOutboxStatus: () => Promise<Record<string, unknown> | null>;
24
+ readOutboxSummary: () => Promise<OutboxSummary>;
25
+ readOutboxItems: () => Promise<LiveActivityItem[]>;
26
+ loadLocalOpenClawSnapshot: (limit: number) => Promise<LocalSnapshot>;
27
+ toLocalSessionTree: (snapshot: LocalSnapshot, limit?: number) => SessionTreeResponse;
28
+ toLocalLiveActivity: (snapshot: LocalSnapshot, limit?: number) => Promise<{
29
+ activities: LiveActivityItem[];
30
+ total: number;
31
+ }>;
32
+ toLocalLiveAgents: (snapshot: LocalSnapshot) => {
33
+ agents: Array<{
34
+ initiativeId: string | null;
35
+ status: string;
36
+ } & Record<string, unknown>>;
37
+ };
38
+ getLiveSessions: (input: {
39
+ initiative: string | null;
40
+ projectId: string | null;
41
+ limit: number;
42
+ }) => Promise<SessionTreeResponse>;
43
+ getLiveActivity: (input: {
44
+ run: string | null;
45
+ since: string | null;
46
+ projectId: string | null;
47
+ limit: number;
48
+ }) => Promise<{
49
+ activities: LiveActivityItem[];
50
+ }>;
51
+ getHandoffs: () => Promise<{
52
+ handoffs: HandoffSummary[];
53
+ }>;
54
+ getLiveDecisions: (input: {
55
+ status: string;
56
+ projectId: string | null;
57
+ limit: number;
58
+ }) => Promise<{
59
+ decisions: unknown[];
60
+ }>;
61
+ getLiveAgents: (input: {
62
+ initiative: string | null;
63
+ projectId: string | null;
64
+ includeIdle: boolean | undefined;
65
+ }) => Promise<{
66
+ agents?: unknown[];
67
+ }>;
68
+ listInitiativeIdsForProject: (input: {
69
+ projectId: string;
70
+ }) => Promise<string[]>;
71
+ mapDecisionEntity: (entry: unknown) => Record<string, unknown> & {
72
+ waitingMinutes: number;
73
+ };
74
+ applyAgentContextsToSessionTree: (input: SessionTreeResponse, contexts: {
75
+ agents: Record<string, AgentLaunchContext>;
76
+ runs: Record<string, RunLaunchContext>;
77
+ }) => SessionTreeResponse;
78
+ applyAgentContextsToActivity: (input: LiveActivityItem[], contexts: {
79
+ agents: Record<string, AgentLaunchContext>;
80
+ runs: Record<string, RunLaunchContext>;
81
+ }) => LiveActivityItem[];
82
+ mergeSessionTrees: (base: SessionTreeResponse, extra: SessionTreeResponse) => SessionTreeResponse;
83
+ mergeActivities: (base: LiveActivityItem[], extra: LiveActivityItem[], limit: number) => LiveActivityItem[];
84
+ listRuntimeInstances: (input: {
85
+ limit: number;
86
+ }) => RuntimeInstanceRecord[];
87
+ injectRuntimeInstancesAsSessions: (input: SessionTreeResponse, instances: RuntimeInstanceRecord[]) => SessionTreeResponse;
88
+ enrichSessionsWithRuntime: (input: SessionTreeResponse, instances: RuntimeInstanceRecord[]) => SessionTreeResponse;
89
+ enrichActivityWithRuntime: (input: LiveActivityItem[], instances: RuntimeInstanceRecord[]) => LiveActivityItem[];
90
+ snapshotActivityFingerprint: (items: LiveActivityItem[]) => string;
91
+ appendActivityItems: (items: LiveActivityItem[]) => void;
92
+ snapshotActivityPersistMinIntervalMs: number;
93
+ readSnapshotPersistState: () => SnapshotPersistState;
94
+ writeSnapshotPersistState: (state: SnapshotPersistState) => void;
95
+ parseJsonRequest?: (req: TReq) => Promise<Record<string, unknown>>;
96
+ buildNextUpQueue?: (input: {
97
+ initiativeId?: string | null;
98
+ projectId?: string | null;
99
+ }) => Promise<{
100
+ items: Array<Record<string, unknown>>;
101
+ degraded: string[];
102
+ }>;
103
+ bulkDecideDecisions?: (ids: string[], action: "approve" | "reject", input?: {
104
+ note?: string;
105
+ optionId?: string;
106
+ }) => Promise<Array<{
107
+ id?: string;
108
+ ok?: boolean;
109
+ error?: string;
110
+ }>>;
111
+ emitDecisionResolvedActivity?: (input: {
112
+ ids: string[];
113
+ action: "approve" | "reject";
114
+ note?: string | null;
115
+ optionId?: string | null;
116
+ sliceRunId?: string | null;
117
+ initiativeId?: string | null;
118
+ }) => Promise<void>;
119
+ runAction?: (runId: string, action: "pause" | "resume" | "cancel" | "rollback", input?: {
120
+ checkpointId?: string;
121
+ reason?: string;
122
+ }) => Promise<unknown>;
123
+ listChatThreads?: (input: {
124
+ commandCenterId?: string | null;
125
+ initiativeId?: string | null;
126
+ limit?: number;
127
+ offset?: number;
128
+ }) => {
129
+ threads: ChatThreadSummary[];
130
+ total: number;
131
+ updatedAt: string;
132
+ };
133
+ sendJson: (res: TRes, status: number, payload: unknown) => void;
134
+ };
135
+ export declare function registerLiveSnapshotRoutes<TReq, TRes>(router: Router<Record<string, never>, TReq, TRes>, deps: LiveSnapshotRoutesDeps<TReq, TRes>): void;
136
+ export {};