@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
@@ -1,270 +1,36 @@
1
- function toContextBundle(value) {
2
- return {
3
- agents: value.agents ?? {},
4
- runs: value.runs ?? {},
5
- };
6
- }
7
1
  export function registerLiveLegacyRoutes(router, deps) {
2
+ const sendDeprecated = (res, endpoint, replacement) => {
3
+ deps.sendJson(res, 410, {
4
+ error: `${endpoint} is deprecated`,
5
+ replacement,
6
+ required_scope: "workspace_id",
7
+ });
8
+ };
8
9
  async function renderLiveSessions(query, res) {
9
- try {
10
- const initiative = query.get("initiative");
11
- const limit = query.get("limit") ? Number(query.get("limit")) : undefined;
12
- let data = await deps.getLiveSessions({
13
- initiative,
14
- limit: Number.isFinite(limit) ? limit : undefined,
15
- });
16
- const runtimeInstances = initiative && initiative.trim().length > 0
17
- ? deps
18
- .listRuntimeInstances({ limit: 320 })
19
- .filter((instance) => instance.initiativeId === initiative)
20
- : deps.listRuntimeInstances({ limit: 320 });
21
- data = deps.injectRuntimeInstancesAsSessions(data, runtimeInstances);
22
- data = deps.enrichSessionsWithRuntime(data, runtimeInstances);
23
- deps.sendJson(res, 200, data);
24
- }
25
- catch (err) {
26
- try {
27
- const initiative = query.get("initiative");
28
- const limitRaw = query.get("limit") ? Number(query.get("limit")) : undefined;
29
- const limit = Number.isFinite(limitRaw) ? Math.max(1, Number(limitRaw)) : 100;
30
- let local = deps.toLocalSessionTree(await deps.loadLocalOpenClawSnapshot(Math.max(limit, 200)), limit);
31
- local = deps.applyAgentContextsToSessionTree(local, toContextBundle(deps.readAgentContexts()));
32
- if (initiative && initiative.trim().length > 0) {
33
- const filteredNodes = local.nodes.filter((node) => node.initiativeId === initiative || node.groupId === initiative);
34
- const filteredIds = new Set(filteredNodes.map((node) => node.id));
35
- const filteredGroupIds = new Set(filteredNodes.map((node) => node.groupId));
36
- local = {
37
- nodes: filteredNodes,
38
- edges: local.edges.filter((edge) => filteredIds.has(edge.parentId) && filteredIds.has(edge.childId)),
39
- groups: local.groups.filter((group) => filteredGroupIds.has(group.id)),
40
- };
41
- }
42
- deps.sendJson(res, 200, local);
43
- }
44
- catch (localErr) {
45
- deps.sendJson(res, 500, {
46
- error: deps.safeErrorMessage(err),
47
- localFallbackError: deps.safeErrorMessage(localErr),
48
- });
49
- }
50
- }
10
+ sendDeprecated(res, "/orgx/api/live/sessions", "/orgx/api/live/snapshot");
11
+ void query;
12
+ return;
51
13
  }
52
14
  router.add("GET", "live/sessions", async ({ query, res }) => renderLiveSessions(query, res), "Legacy live sessions endpoint");
53
15
  router.add("HEAD", "live/sessions", async ({ query, res }) => renderLiveSessions(query, res), "Legacy live sessions endpoint (HEAD)");
54
16
  async function renderLiveActivityPage(query, res) {
55
- const run = query.get("run");
56
- const since = query.get("since");
57
- const until = query.get("until");
58
- const cursor = query.get("cursor");
59
- const limitRaw = query.get("limit") ? Number(query.get("limit")) : undefined;
60
- const limit = Number.isFinite(limitRaw)
61
- ? Math.max(1, Math.floor(Number(limitRaw)))
62
- : 200;
63
- let page = deps.listActivityPage({
64
- limit,
65
- runId: run,
66
- since,
67
- until,
68
- cursor,
69
- });
70
- {
71
- const ctx = toContextBundle(deps.readAgentContexts());
72
- page = {
73
- ...page,
74
- activities: deps.applyAgentContextsToActivity(page.activities, ctx),
75
- };
76
- }
77
- const warmKey = `${run ?? ""}::${since ?? ""}::${until ?? ""}`;
78
- const lastWarmAt = deps.activityWarmByKey.get(warmKey) ?? 0;
79
- const shouldWarm = Date.now() - lastWarmAt > deps.activityWarmThrottleMs &&
80
- (cursor === null || cursor === "" || page.activities.length < limit);
81
- if (shouldWarm) {
82
- deps.activityWarmByKey.set(warmKey, Date.now());
83
- try {
84
- const warmLimit = Math.max(800, Math.min(6_000, limit * 10));
85
- const data = await deps.getLiveActivity({
86
- run,
87
- since,
88
- limit: warmLimit,
89
- });
90
- const remote = Array.isArray(data.activities) ? data.activities : [];
91
- {
92
- const ctx = toContextBundle(deps.readAgentContexts());
93
- const withContexts = deps.applyAgentContextsToActivity(remote, ctx);
94
- deps.appendActivityItems(withContexts);
95
- }
96
- page = deps.listActivityPage({
97
- limit,
98
- runId: run,
99
- since,
100
- until,
101
- cursor,
102
- });
103
- {
104
- const ctx = toContextBundle(deps.readAgentContexts());
105
- page = {
106
- ...page,
107
- activities: deps.applyAgentContextsToActivity(page.activities, ctx),
108
- };
109
- }
110
- }
111
- catch {
112
- // best effort
113
- }
114
- }
115
- deps.sendJson(res, 200, page);
17
+ sendDeprecated(res, "/orgx/api/live/activity/page", "/orgx/api/live/snapshot-v2");
18
+ void query;
19
+ return;
116
20
  }
117
21
  router.add("GET", "live/activity/page", async ({ query, res }) => renderLiveActivityPage(query, res), "Paginated live activity");
118
22
  router.add("HEAD", "live/activity/page", async ({ query, res }) => renderLiveActivityPage(query, res), "Paginated live activity (HEAD)");
119
23
  async function renderLiveActivity(query, res) {
120
- try {
121
- const run = query.get("run");
122
- const limit = query.get("limit") ? Number(query.get("limit")) : undefined;
123
- const since = query.get("since");
124
- const data = await deps.getLiveActivity({
125
- run,
126
- since,
127
- limit: Number.isFinite(limit) ? limit : undefined,
128
- });
129
- let activities = Array.isArray(data.activities) ? data.activities : [];
130
- let total = typeof data.total === "number" && Number.isFinite(data.total)
131
- ? Number(data.total)
132
- : activities.length;
133
- try {
134
- const buffered = await deps.outboxReadAllItems();
135
- if (buffered.length > 0) {
136
- let merged = [...activities, ...buffered];
137
- if (run && run.trim().length > 0) {
138
- merged = merged.filter((item) => item.runId === run);
139
- }
140
- if (since && since.trim().length > 0) {
141
- const sinceEpoch = Date.parse(since);
142
- if (Number.isFinite(sinceEpoch)) {
143
- merged = merged.filter((item) => Date.parse(item.timestamp) >= sinceEpoch);
144
- }
145
- }
146
- merged.sort((a, b) => Date.parse(b.timestamp) - Date.parse(a.timestamp));
147
- const deduped = [];
148
- const seen = new Set();
149
- for (const item of merged) {
150
- if (seen.has(item.id))
151
- continue;
152
- seen.add(item.id);
153
- deduped.push(item);
154
- }
155
- total = deduped.length;
156
- if (Number.isFinite(limit)) {
157
- const cap = Math.max(1, Math.floor(Number(limit)));
158
- activities = deduped.slice(0, cap);
159
- }
160
- else {
161
- activities = deduped;
162
- }
163
- }
164
- }
165
- catch {
166
- // best effort
167
- }
168
- try {
169
- const ctx = toContextBundle(deps.readAgentContexts());
170
- const withContexts = deps.applyAgentContextsToActivity(activities, ctx);
171
- if (withContexts.length > 0)
172
- deps.appendActivityItems(withContexts);
173
- deps.sendJson(res, 200, { ...data, activities: withContexts, total });
174
- }
175
- catch {
176
- deps.sendJson(res, 200, { ...data, activities, total });
177
- }
178
- }
179
- catch (err) {
180
- try {
181
- const run = query.get("run");
182
- const limitRaw = query.get("limit") ? Number(query.get("limit")) : undefined;
183
- const since = query.get("since");
184
- const limit = Number.isFinite(limitRaw) ? Math.max(1, Number(limitRaw)) : 240;
185
- const localSnapshot = await deps.loadLocalOpenClawSnapshot(Math.max(limit, 240));
186
- let local = await deps.toLocalLiveActivity(localSnapshot, Math.max(limit, 240));
187
- if (run && run.trim().length > 0) {
188
- local = {
189
- activities: local.activities.filter((item) => item.runId === run),
190
- total: local.activities.filter((item) => item.runId === run).length,
191
- };
192
- }
193
- if (since && since.trim().length > 0) {
194
- const sinceEpoch = Date.parse(since);
195
- if (Number.isFinite(sinceEpoch)) {
196
- const filtered = local.activities.filter((item) => Date.parse(item.timestamp) >= sinceEpoch);
197
- local = {
198
- activities: filtered,
199
- total: filtered.length,
200
- };
201
- }
202
- }
203
- const ctx = toContextBundle(deps.readAgentContexts());
204
- const activitiesWithContexts = deps.applyAgentContextsToActivity(local.activities, ctx);
205
- let merged = activitiesWithContexts;
206
- try {
207
- const buffered = await deps.outboxReadAllItems();
208
- if (buffered.length > 0) {
209
- const byId = new Map();
210
- for (const item of [...merged, ...buffered]) {
211
- if (!item || typeof item.id !== "string")
212
- continue;
213
- byId.set(item.id, item);
214
- }
215
- merged = Array.from(byId.values()).sort((a, b) => Date.parse(b.timestamp) - Date.parse(a.timestamp));
216
- }
217
- }
218
- catch {
219
- // best effort
220
- }
221
- try {
222
- deps.appendActivityItems(merged);
223
- }
224
- catch {
225
- // best effort
226
- }
227
- deps.sendJson(res, 200, {
228
- activities: merged.slice(0, limit),
229
- total: merged.length,
230
- });
231
- }
232
- catch (localErr) {
233
- deps.sendJson(res, 500, {
234
- error: deps.safeErrorMessage(err),
235
- localFallbackError: deps.safeErrorMessage(localErr),
236
- });
237
- }
238
- }
24
+ sendDeprecated(res, "/orgx/api/live/activity", "/orgx/api/live/snapshot");
25
+ void query;
26
+ return;
239
27
  }
240
28
  router.add("GET", "live/activity", async ({ query, res }) => renderLiveActivity(query, res), "Legacy live activity endpoint");
241
29
  router.add("HEAD", "live/activity", async ({ query, res }) => renderLiveActivity(query, res), "Legacy live activity endpoint (HEAD)");
242
30
  async function renderLiveActivityDetail(query, res) {
243
- const turnId = query.get("turnId") ?? query.get("turn_id");
244
- const sessionKey = query.get("sessionKey") ?? query.get("session_key");
245
- const run = query.get("run");
246
- if (!turnId || turnId.trim().length === 0) {
247
- deps.sendJson(res, 400, { error: "turnId is required" });
248
- return;
249
- }
250
- try {
251
- const detail = await deps.loadLocalTurnDetail({
252
- turnId,
253
- sessionKey,
254
- runId: run,
255
- });
256
- if (!detail) {
257
- deps.sendJson(res, 404, {
258
- error: "Turn detail unavailable",
259
- turnId,
260
- });
261
- return;
262
- }
263
- deps.sendJson(res, 200, { detail });
264
- }
265
- catch (err) {
266
- deps.sendJson(res, 500, { error: deps.safeErrorMessage(err), turnId });
267
- }
31
+ sendDeprecated(res, "/orgx/api/live/activity/detail", "/orgx/api/live/snapshot-v2");
32
+ void query;
33
+ return;
268
34
  }
269
35
  router.add("GET", "live/activity/detail", async ({ query, res }) => renderLiveActivityDetail(query, res), "Detailed activity turn view");
270
36
  router.add("HEAD", "live/activity/detail", async ({ query, res }) => renderLiveActivityDetail(query, res), "Detailed activity turn view (HEAD)");
@@ -336,262 +102,10 @@ export function registerLiveLegacyRoutes(router, deps) {
336
102
  deps.sendJson(res, 405, { error: "Use GET /orgx/api/live/filesystem/open?path=..." });
337
103
  }, "Reject unsupported methods for live/filesystem/open");
338
104
  async function renderLiveStream(query, req, res) {
339
- const write = res.write?.bind(res);
340
- if (!write) {
341
- deps.sendJson(res, 501, { error: "Streaming not supported" });
342
- return;
343
- }
344
- const queryString = query.toString();
345
- const target = `${deps.config.baseUrl.replace(/\/+$/, "")}/api/client/live/stream${queryString ? `?${queryString}` : ""}`;
346
- let upstreamAbortController = null;
347
- let reader = null;
348
- let closed = false;
349
- let streamOpened = false;
350
- let idleTimer = null;
351
- let heartbeatTimer = null;
352
- let heartbeatBackpressure = false;
353
- const sseDecoder = new TextDecoder("utf-8");
354
- let sseBuffer = "";
355
- const consumeSseText = (chunk) => {
356
- if (!chunk)
357
- return;
358
- sseBuffer += chunk.replace(/\r\n/g, "\n");
359
- while (true) {
360
- const boundary = sseBuffer.indexOf("\n\n");
361
- if (boundary === -1)
362
- return;
363
- const rawEvent = sseBuffer.slice(0, boundary);
364
- sseBuffer = sseBuffer.slice(boundary + 2);
365
- const lines = rawEvent.split("\n").map((l) => l.replace(/\r$/, ""));
366
- let eventName = null;
367
- const dataLines = [];
368
- for (const line of lines) {
369
- if (!line)
370
- continue;
371
- if (line.startsWith(":"))
372
- continue;
373
- if (line.startsWith("event:")) {
374
- eventName = line.slice("event:".length).trim() || null;
375
- continue;
376
- }
377
- if (line.startsWith("data:")) {
378
- dataLines.push(line.slice("data:".length).trimStart());
379
- continue;
380
- }
381
- }
382
- if (!eventName || dataLines.length === 0)
383
- continue;
384
- const dataText = dataLines.join("\n").trim();
385
- if (!dataText)
386
- continue;
387
- try {
388
- if (eventName === "activity.appended") {
389
- const parsed = JSON.parse(dataText);
390
- const list = Array.isArray(parsed) ? parsed : [];
391
- if (list.length > 0) {
392
- const ctx = toContextBundle(deps.readAgentContexts());
393
- deps.appendActivityItems(deps.applyAgentContextsToActivity(list, ctx));
394
- }
395
- }
396
- else if (eventName === "snapshot") {
397
- const parsed = JSON.parse(dataText);
398
- const list = Array.isArray(parsed?.activity) ? parsed.activity : [];
399
- if (list.length > 0) {
400
- const ctx = toContextBundle(deps.readAgentContexts());
401
- deps.appendActivityItems(deps.applyAgentContextsToActivity(list, ctx));
402
- }
403
- }
404
- }
405
- catch {
406
- // ignore malformed payloads
407
- }
408
- }
409
- };
410
- const clearIdleTimer = () => {
411
- if (idleTimer) {
412
- clearTimeout(idleTimer);
413
- idleTimer = null;
414
- }
415
- };
416
- const clearHeartbeatTimer = () => {
417
- if (heartbeatTimer) {
418
- clearInterval(heartbeatTimer);
419
- heartbeatTimer = null;
420
- }
421
- };
422
- const abortUpstream = () => {
423
- try {
424
- upstreamAbortController?.abort();
425
- }
426
- catch {
427
- // best effort
428
- }
429
- upstreamAbortController = null;
430
- };
431
- const closeStream = () => {
432
- if (closed)
433
- return;
434
- closed = true;
435
- clearIdleTimer();
436
- clearHeartbeatTimer();
437
- abortUpstream();
438
- if (reader) {
439
- void reader.cancel().catch(() => undefined);
440
- }
441
- if (streamOpened && !res.writableEnded) {
442
- res.end();
443
- }
444
- };
445
- const resetIdleTimer = () => {
446
- clearIdleTimer();
447
- idleTimer = setTimeout(() => {
448
- closeStream();
449
- }, deps.streamIdleTimeoutMs);
450
- };
451
- try {
452
- const includeUserHeader = Boolean(deps.config.userId && deps.config.userId.trim().length > 0) &&
453
- !deps.isUserScopedApiKey(deps.config.apiKey);
454
- res.writeHead(200, {
455
- "Content-Type": "text/event-stream; charset=utf-8",
456
- "Cache-Control": "no-cache, no-transform",
457
- Connection: "keep-alive",
458
- ...deps.securityHeaders,
459
- ...deps.corsHeaders,
460
- });
461
- streamOpened = true;
462
- heartbeatTimer = setInterval(() => {
463
- if (closed || heartbeatBackpressure)
464
- return;
465
- try {
466
- const accepted = write(Buffer.from(`: ping ${Date.now()}\n`, "utf8"));
467
- resetIdleTimer();
468
- if (accepted === false) {
469
- heartbeatBackpressure = true;
470
- if (typeof res.once === "function") {
471
- res.once("drain", () => {
472
- heartbeatBackpressure = false;
473
- if (!closed)
474
- resetIdleTimer();
475
- });
476
- }
477
- }
478
- }
479
- catch {
480
- closeStream();
481
- }
482
- }, 20_000);
483
- heartbeatTimer.unref?.();
484
- req.on?.("close", closeStream);
485
- req.on?.("aborted", closeStream);
486
- res.on?.("close", closeStream);
487
- res.on?.("finish", closeStream);
488
- const waitForDrain = async () => {
489
- if (typeof res.once === "function") {
490
- await new Promise((resolve) => {
491
- res.once?.("drain", () => resolve());
492
- });
493
- }
494
- };
495
- const sleep = async (ms) => {
496
- await new Promise((resolve) => setTimeout(resolve, ms));
497
- };
498
- const connectAndPump = async () => {
499
- let attempt = 0;
500
- while (!closed) {
501
- abortUpstream();
502
- upstreamAbortController = new AbortController();
503
- let upstream = null;
504
- try {
505
- upstream = await fetch(target, {
506
- method: "GET",
507
- headers: {
508
- Authorization: `Bearer ${deps.config.apiKey}`,
509
- Accept: "text/event-stream",
510
- ...(includeUserHeader ? { "X-Orgx-User-Id": deps.config.userId } : {}),
511
- },
512
- signal: upstreamAbortController.signal,
513
- });
514
- }
515
- catch {
516
- upstream = null;
517
- }
518
- const contentType = upstream?.headers.get("content-type")?.toLowerCase() ?? "";
519
- if (!upstream ||
520
- !upstream.ok ||
521
- !contentType.includes("text/event-stream") ||
522
- !upstream.body) {
523
- const status = upstream?.status ?? null;
524
- const preview = upstream
525
- ? (await upstream.text().catch(() => ""))
526
- .replace(/\s+/g, " ")
527
- .slice(0, 200)
528
- : null;
529
- try {
530
- write(Buffer.from(`: upstream unavailable status=${status ?? "error"} ${preview ? `preview=${JSON.stringify(preview)}` : ""}\n`, "utf8"));
531
- }
532
- catch {
533
- closeStream();
534
- return;
535
- }
536
- resetIdleTimer();
537
- attempt += 1;
538
- const backoffMs = Math.min(15_000, 750 * Math.pow(1.6, Math.min(attempt, 10)));
539
- await sleep(backoffMs);
540
- continue;
541
- }
542
- attempt = 0;
543
- reader = upstream.body.getReader();
544
- const streamReader = reader;
545
- resetIdleTimer();
546
- try {
547
- while (!closed) {
548
- const { done, value } = await streamReader.read();
549
- if (done)
550
- break;
551
- if (!value || value.byteLength === 0)
552
- continue;
553
- resetIdleTimer();
554
- try {
555
- consumeSseText(sseDecoder.decode(value, { stream: true }));
556
- }
557
- catch {
558
- // best effort
559
- }
560
- const accepted = write(Buffer.from(value));
561
- if (accepted === false) {
562
- await waitForDrain();
563
- }
564
- }
565
- }
566
- catch {
567
- // swallow; we'll reconnect unless the client is gone
568
- }
569
- finally {
570
- try {
571
- await streamReader.cancel();
572
- }
573
- catch {
574
- // ignore
575
- }
576
- if (reader === streamReader) {
577
- reader = null;
578
- }
579
- }
580
- if (!closed) {
581
- await sleep(300);
582
- }
583
- }
584
- };
585
- void connectAndPump();
586
- }
587
- catch (err) {
588
- closeStream();
589
- if (!streamOpened && !res.writableEnded) {
590
- deps.sendJson(res, 500, {
591
- error: deps.safeErrorMessage(err),
592
- });
593
- }
594
- }
105
+ sendDeprecated(res, "/orgx/api/live/stream", "/orgx/api/live/snapshot-v2");
106
+ void query;
107
+ void req;
108
+ return;
595
109
  }
596
110
  router.add("GET", "live/stream", async ({ query, req, res }) => renderLiveStream(query, req, res), "Proxy live SSE stream");
597
111
  router.add("HEAD", "live/stream", async ({ query, req, res }) => renderLiveStream(query, req, res), "Proxy live SSE stream (HEAD)");
@@ -4,6 +4,11 @@ type JsonRecord = Record<string, unknown>;
4
4
  type LiveInitiativesResponse = {
5
5
  initiatives: unknown[];
6
6
  total?: number;
7
+ pagination?: {
8
+ limit?: number;
9
+ offset?: number;
10
+ has_more?: boolean;
11
+ };
7
12
  };
8
13
  type LiveDecisionsResponse = {
9
14
  decisions: Entity[];
@@ -27,17 +32,24 @@ type RegisterLiveMiscRoutesDeps<TReq, TRes> = {
27
32
  }>;
28
33
  getLiveAgents: (input: {
29
34
  initiative: string | null;
35
+ projectId: string | null;
30
36
  includeIdle: boolean | undefined;
31
37
  }) => Promise<unknown>;
32
38
  getLiveInitiatives: (input: {
33
39
  id: string | null;
40
+ projectId: string | null;
34
41
  limit: number | undefined;
42
+ offset: number | undefined;
35
43
  }) => Promise<LiveInitiativesResponse>;
36
44
  getLiveDecisions: (input: {
37
45
  status: string;
46
+ projectId: string | null;
38
47
  limit: number;
39
48
  }) => Promise<LiveDecisionsResponse>;
40
49
  getHandoffs: () => Promise<HandoffsResponse>;
50
+ listInitiativeIdsForProject: (input: {
51
+ projectId: string;
52
+ }) => Promise<string[]>;
41
53
  loadLocalOpenClawSnapshot: (limit: number) => Promise<LocalSnapshot>;
42
54
  toLocalLiveAgents: (snapshot: LocalSnapshot) => {
43
55
  agents: Array<{