@useorgx/openclaw-plugin 0.4.9 → 0.7.2

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 (224) hide show
  1. package/README.md +77 -11
  2. package/dashboard/dist/assets/6mILZQ2a.js +1 -0
  3. package/dashboard/dist/assets/6mILZQ2a.js.br +0 -0
  4. package/dashboard/dist/assets/6mILZQ2a.js.gz +0 -0
  5. package/dashboard/dist/assets/8dksYiq4.js +2 -0
  6. package/dashboard/dist/assets/8dksYiq4.js.br +0 -0
  7. package/dashboard/dist/assets/8dksYiq4.js.gz +0 -0
  8. package/dashboard/dist/assets/B5zYRHc3.js +1 -0
  9. package/dashboard/dist/assets/B5zYRHc3.js.br +0 -0
  10. package/dashboard/dist/assets/B5zYRHc3.js.gz +0 -0
  11. package/dashboard/dist/assets/B6wPWJ35.js +1 -0
  12. package/dashboard/dist/assets/B6wPWJ35.js.br +0 -0
  13. package/dashboard/dist/assets/B6wPWJ35.js.gz +0 -0
  14. package/dashboard/dist/assets/BJgZIVUQ.js +53 -0
  15. package/dashboard/dist/assets/BJgZIVUQ.js.br +0 -0
  16. package/dashboard/dist/assets/BJgZIVUQ.js.gz +0 -0
  17. package/dashboard/dist/assets/BWEwjt1W.js +1 -0
  18. package/dashboard/dist/assets/BWEwjt1W.js.br +0 -0
  19. package/dashboard/dist/assets/BWEwjt1W.js.gz +0 -0
  20. package/dashboard/dist/assets/BgOYB78t.js +4 -0
  21. package/dashboard/dist/assets/BgOYB78t.js.br +0 -0
  22. package/dashboard/dist/assets/BgOYB78t.js.gz +0 -0
  23. package/dashboard/dist/assets/BzRbDCAD.css +1 -0
  24. package/dashboard/dist/assets/BzRbDCAD.css.br +0 -0
  25. package/dashboard/dist/assets/BzRbDCAD.css.gz +0 -0
  26. package/dashboard/dist/assets/C-KIc3Wc.js.br +0 -0
  27. package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
  28. package/dashboard/dist/assets/C8uM3AX8.js +1 -0
  29. package/dashboard/dist/assets/C8uM3AX8.js.br +0 -0
  30. package/dashboard/dist/assets/C8uM3AX8.js.gz +0 -0
  31. package/dashboard/dist/assets/C9jy61eu.js +212 -0
  32. package/dashboard/dist/assets/C9jy61eu.js.br +0 -0
  33. package/dashboard/dist/assets/C9jy61eu.js.gz +0 -0
  34. package/dashboard/dist/assets/CC63EwFD.js +1 -0
  35. package/dashboard/dist/assets/CC63EwFD.js.br +0 -0
  36. package/dashboard/dist/assets/CC63EwFD.js.gz +0 -0
  37. package/dashboard/dist/assets/CL_wXqR7.js +1 -0
  38. package/dashboard/dist/assets/CL_wXqR7.js.br +0 -0
  39. package/dashboard/dist/assets/CL_wXqR7.js.gz +0 -0
  40. package/dashboard/dist/assets/CZaT3ob_.js +1 -0
  41. package/dashboard/dist/assets/CZaT3ob_.js.br +0 -0
  42. package/dashboard/dist/assets/CZaT3ob_.js.gz +0 -0
  43. package/dashboard/dist/assets/CgaottFX.js +1 -0
  44. package/dashboard/dist/assets/CgaottFX.js.br +0 -0
  45. package/dashboard/dist/assets/CgaottFX.js.gz +0 -0
  46. package/dashboard/dist/assets/{CpJsfbXo.js → CxQ08qFN.js} +2 -2
  47. package/dashboard/dist/assets/CxQ08qFN.js.br +0 -0
  48. package/dashboard/dist/assets/CxQ08qFN.js.gz +0 -0
  49. package/dashboard/dist/assets/CzCxAZlW.js +1 -0
  50. package/dashboard/dist/assets/CzCxAZlW.js.br +0 -0
  51. package/dashboard/dist/assets/CzCxAZlW.js.gz +0 -0
  52. package/dashboard/dist/assets/D3iMTYEj.js +1 -0
  53. package/dashboard/dist/assets/D3iMTYEj.js.br +0 -0
  54. package/dashboard/dist/assets/D3iMTYEj.js.gz +0 -0
  55. package/dashboard/dist/assets/D8JNX8kq.js +2 -0
  56. package/dashboard/dist/assets/D8JNX8kq.js.br +0 -0
  57. package/dashboard/dist/assets/D8JNX8kq.js.gz +0 -0
  58. package/dashboard/dist/assets/DnA8dpj6.js +1 -0
  59. package/dashboard/dist/assets/DnA8dpj6.js.br +0 -0
  60. package/dashboard/dist/assets/DnA8dpj6.js.gz +0 -0
  61. package/dashboard/dist/assets/IUexzymk.js +1 -0
  62. package/dashboard/dist/assets/IUexzymk.js.br +0 -0
  63. package/dashboard/dist/assets/IUexzymk.js.gz +0 -0
  64. package/dashboard/dist/assets/cNrhgGc1.js +8 -0
  65. package/dashboard/dist/assets/cNrhgGc1.js.br +0 -0
  66. package/dashboard/dist/assets/cNrhgGc1.js.gz +0 -0
  67. package/dashboard/dist/assets/ic2FaMnh.js +1 -0
  68. package/dashboard/dist/assets/ic2FaMnh.js.br +0 -0
  69. package/dashboard/dist/assets/ic2FaMnh.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/rttbDbEx.js +1 -0
  74. package/dashboard/dist/assets/rttbDbEx.js.br +0 -0
  75. package/dashboard/dist/assets/rttbDbEx.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/practice-exercise-schema.d.ts +216 -0
  102. package/dist/contracts/practice-exercise-schema.js +314 -0
  103. package/dist/contracts/retro-schema.d.ts +81 -0
  104. package/dist/contracts/retro-schema.js +80 -0
  105. package/dist/contracts/shared-types.d.ts +159 -0
  106. package/dist/contracts/shared-types.js +199 -1
  107. package/dist/contracts/skill-pack-schema.d.ts +192 -0
  108. package/dist/contracts/skill-pack-schema.js +180 -0
  109. package/dist/contracts/types.d.ts +247 -2
  110. package/dist/entities/auto-assignment.js +43 -17
  111. package/dist/event-sanitization.d.ts +11 -0
  112. package/dist/event-sanitization.js +113 -0
  113. package/dist/gateway-watchdog.d.ts +5 -0
  114. package/dist/gateway-watchdog.js +50 -0
  115. package/dist/hooks/post-reporting-event.mjs +1 -5
  116. package/dist/http/helpers/activity-headline.js +13 -132
  117. package/dist/http/helpers/auto-continue-engine.d.ts +198 -10
  118. package/dist/http/helpers/auto-continue-engine.js +3145 -186
  119. package/dist/http/helpers/autopilot-operations.d.ts +19 -0
  120. package/dist/http/helpers/autopilot-operations.js +182 -31
  121. package/dist/http/helpers/autopilot-runtime.d.ts +1 -0
  122. package/dist/http/helpers/autopilot-runtime.js +328 -25
  123. package/dist/http/helpers/autopilot-slice-utils.d.ts +18 -0
  124. package/dist/http/helpers/autopilot-slice-utils.js +514 -93
  125. package/dist/http/helpers/decision-mapper.d.ts +40 -0
  126. package/dist/http/helpers/decision-mapper.js +223 -7
  127. package/dist/http/helpers/dispatch-lifecycle.d.ts +19 -2
  128. package/dist/http/helpers/dispatch-lifecycle.js +242 -37
  129. package/dist/http/helpers/kickoff-context.js +104 -0
  130. package/dist/http/helpers/llm-client.d.ts +47 -0
  131. package/dist/http/helpers/llm-client.js +256 -0
  132. package/dist/http/helpers/mission-control.d.ts +102 -3
  133. package/dist/http/helpers/mission-control.js +498 -9
  134. package/dist/http/helpers/sentinel-catalog.d.ts +23 -0
  135. package/dist/http/helpers/sentinel-catalog.js +193 -0
  136. package/dist/http/helpers/session-classification.d.ts +9 -0
  137. package/dist/http/helpers/session-classification.js +564 -0
  138. package/dist/http/helpers/slice-experience-v2.d.ts +137 -0
  139. package/dist/http/helpers/slice-experience-v2.js +677 -0
  140. package/dist/http/helpers/slice-run-projections.d.ts +72 -0
  141. package/dist/http/helpers/slice-run-projections.js +877 -0
  142. package/dist/http/helpers/triage-mapper.d.ts +43 -0
  143. package/dist/http/helpers/triage-mapper.js +549 -0
  144. package/dist/http/helpers/value-utils.js +7 -2
  145. package/dist/http/helpers/workspace-scope.d.ts +15 -0
  146. package/dist/http/helpers/workspace-scope.js +170 -0
  147. package/dist/http/index.js +1420 -105
  148. package/dist/http/routes/agent-suite.d.ts +9 -0
  149. package/dist/http/routes/agent-suite.js +294 -8
  150. package/dist/http/routes/agents-catalog.js +64 -19
  151. package/dist/http/routes/chat.d.ts +19 -0
  152. package/dist/http/routes/chat.js +522 -0
  153. package/dist/http/routes/decision-actions.d.ts +8 -1
  154. package/dist/http/routes/decision-actions.js +42 -5
  155. package/dist/http/routes/dispatch-gateway-envelope.d.ts +25 -0
  156. package/dist/http/routes/dispatch-gateway-envelope.js +26 -0
  157. package/dist/http/routes/entities.d.ts +16 -0
  158. package/dist/http/routes/entities.js +232 -6
  159. package/dist/http/routes/live-legacy.d.ts +5 -0
  160. package/dist/http/routes/live-legacy.js +23 -509
  161. package/dist/http/routes/live-misc.d.ts +12 -0
  162. package/dist/http/routes/live-misc.js +251 -31
  163. package/dist/http/routes/live-snapshot.d.ts +49 -2
  164. package/dist/http/routes/live-snapshot.js +653 -23
  165. package/dist/http/routes/live-terminal.d.ts +11 -0
  166. package/dist/http/routes/live-terminal.js +154 -0
  167. package/dist/http/routes/live-triage.d.ts +61 -0
  168. package/dist/http/routes/live-triage.js +192 -0
  169. package/dist/http/routes/mission-control-actions.d.ts +49 -1
  170. package/dist/http/routes/mission-control-actions.js +1246 -84
  171. package/dist/http/routes/mission-control-read.d.ts +48 -3
  172. package/dist/http/routes/mission-control-read.js +1658 -20
  173. package/dist/http/routes/realtime-orchestrator.d.ts +10 -0
  174. package/dist/http/routes/realtime-orchestrator.js +74 -0
  175. package/dist/http/routes/run-control.d.ts +5 -2
  176. package/dist/http/routes/run-control.js +10 -0
  177. package/dist/http/routes/sentinels-catalog.d.ts +7 -0
  178. package/dist/http/routes/sentinels-catalog.js +24 -0
  179. package/dist/http/routes/summary.js +10 -3
  180. package/dist/http/routes/usage.d.ts +24 -0
  181. package/dist/http/routes/usage.js +362 -0
  182. package/dist/http/routes/work-artifacts.js +28 -9
  183. package/dist/index.js +165 -27
  184. package/dist/local-openclaw.js +29 -6
  185. package/dist/mcp-client-setup.js +3 -3
  186. package/dist/mcp-http-handler.d.ts +3 -0
  187. package/dist/mcp-http-handler.js +34 -60
  188. package/dist/next-up-queue-store.d.ts +16 -1
  189. package/dist/next-up-queue-store.js +89 -7
  190. package/dist/outbox.d.ts +5 -0
  191. package/dist/outbox.js +113 -9
  192. package/dist/paths.js +36 -5
  193. package/dist/reporting/rollups.d.ts +41 -0
  194. package/dist/reporting/rollups.js +113 -0
  195. package/dist/retro/domain-templates.d.ts +45 -0
  196. package/dist/retro/domain-templates.js +297 -0
  197. package/dist/retro/quality-rubric.d.ts +33 -0
  198. package/dist/retro/quality-rubric.js +213 -0
  199. package/dist/runtime-cleanup.d.ts +18 -0
  200. package/dist/runtime-cleanup.js +87 -0
  201. package/dist/services/background.d.ts +11 -0
  202. package/dist/services/background.js +22 -0
  203. package/dist/services/experiment-randomization.d.ts +21 -0
  204. package/dist/services/experiment-randomization.js +63 -0
  205. package/dist/skill-pack-state.d.ts +36 -5
  206. package/dist/skill-pack-state.js +273 -29
  207. package/dist/sync/local-agent-telemetry.d.ts +13 -0
  208. package/dist/sync/local-agent-telemetry.js +128 -0
  209. package/dist/sync/outbox-replay.js +131 -24
  210. package/dist/team-context-store.d.ts +23 -0
  211. package/dist/team-context-store.js +116 -0
  212. package/dist/telemetry/posthog.js +4 -2
  213. package/dist/tools/core-tools.d.ts +10 -14
  214. package/dist/tools/core-tools.js +1289 -24
  215. package/dist/types.d.ts +2 -0
  216. package/dist/types.js +2 -0
  217. package/dist/worker-supervisor.js +23 -0
  218. package/package.json +20 -6
  219. package/dashboard/dist/assets/B3ziCA02.js +0 -8
  220. package/dashboard/dist/assets/B5NEElEI.css +0 -1
  221. package/dashboard/dist/assets/BhapSNAs.js +0 -215
  222. package/dashboard/dist/assets/iFdvE7lx.js +0 -1
  223. package/dashboard/dist/assets/jRJsmpYM.js +0 -1
  224. package/dashboard/dist/assets/sAhvFnpk.js +0 -4
@@ -12,9 +12,16 @@ type EntityClientLike = {
12
12
  createEntity: (type: string, data: Record<string, unknown>) => Promise<Entity>;
13
13
  updateEntity: (type: string, id: string, updates: Record<string, unknown>) => Promise<Entity>;
14
14
  listEntities: (type: string, input: {
15
+ id?: string;
16
+ ids?: string[] | string;
17
+ search?: string;
15
18
  status?: string;
16
19
  initiative_id?: string;
20
+ project_id?: string;
21
+ workspace_id?: string;
22
+ command_center_id?: string;
17
23
  limit?: number;
24
+ offset?: number;
18
25
  }) => Promise<unknown>;
19
26
  };
20
27
  type RegisterEntitiesRoutesDeps<TReq, TRes> = {
@@ -40,6 +47,15 @@ type RegisterEntitiesRoutesDeps<TReq, TRes> = {
40
47
  progress?: number | null;
41
48
  }>;
42
49
  getSnapshot: () => OrgSnapshot | null;
50
+ scheduleWorkstreamReassignment?: (input: {
51
+ initiativeId: string;
52
+ workstreamId: string;
53
+ status: string | null;
54
+ event: string;
55
+ }) => Promise<{
56
+ requestId?: string | null;
57
+ dueAt?: string | null;
58
+ } | null>;
43
59
  sendJson: (res: TRes, status: number, payload: unknown) => void;
44
60
  safeErrorMessage: (err: unknown) => string;
45
61
  };
@@ -1,3 +1,43 @@
1
+ import { resolveWorkspaceScope, workspaceScopeFromHeaders, } from "../helpers/workspace-scope.js";
2
+ const WORKSTREAM_REASSIGNMENT_FIELDS = [
3
+ "domain",
4
+ "role",
5
+ "assigned_agents",
6
+ "assignedAgents",
7
+ "assigned_agent_ids",
8
+ "assignedAgentIds",
9
+ "assigned_agent_names",
10
+ "assignedAgentNames",
11
+ ];
12
+ function hasOwn(input, key) {
13
+ return Object.prototype.hasOwnProperty.call(input, key);
14
+ }
15
+ function hasMeaningfulReassignmentValue(value) {
16
+ if (typeof value === "string")
17
+ return value.trim().length > 0;
18
+ if (Array.isArray(value))
19
+ return value.length > 0;
20
+ return value !== null && value !== undefined;
21
+ }
22
+ function includesWorkstreamReassignmentMutation(payload) {
23
+ return WORKSTREAM_REASSIGNMENT_FIELDS.some((field) => hasOwn(payload, field) && hasMeaningfulReassignmentValue(payload[field]));
24
+ }
25
+ function isActiveOrReadyStatus(status) {
26
+ const normalized = (status ?? "").trim().toLowerCase();
27
+ if (!normalized)
28
+ return false;
29
+ return (normalized === "active" ||
30
+ normalized === "ready" ||
31
+ normalized === "in_progress" ||
32
+ normalized === "running" ||
33
+ normalized === "queued" ||
34
+ normalized === "pending");
35
+ }
36
+ function toObjectArray(input) {
37
+ if (!Array.isArray(input))
38
+ return [];
39
+ return input.filter((item) => Boolean(item) && typeof item === "object");
40
+ }
1
41
  export function registerEntitiesRoutes(router, deps) {
2
42
  router.add("POST", "entities", async ({ req, res }) => {
3
43
  try {
@@ -59,10 +99,103 @@ export function registerEntitiesRoutes(router, deps) {
59
99
  const normalizedType = type.trim().toLowerCase();
60
100
  const normalizedUpdates = deps.normalizeEntityMutationPayload(updates);
61
101
  const entity = await deps.client.updateEntity(type, id, normalizedUpdates);
102
+ let reassignment = null;
103
+ let initiativeReassignment = null;
104
+ if (normalizedType === "workstream" &&
105
+ deps.scheduleWorkstreamReassignment &&
106
+ includesWorkstreamReassignmentMutation(normalizedUpdates)) {
107
+ const entityRecord = entity && typeof entity === "object"
108
+ ? entity
109
+ : {};
110
+ const initiativeId = deps.pickString(entityRecord, ["initiative_id", "initiativeId"]) ??
111
+ deps.pickString(normalizedUpdates, ["initiative_id", "initiativeId"]) ??
112
+ null;
113
+ const workstreamStatus = deps.pickString(entityRecord, ["status"]) ??
114
+ deps.pickString(normalizedUpdates, ["status"]) ??
115
+ null;
116
+ if (!initiativeId) {
117
+ reassignment = { scheduled: false, reason: "missing_initiative" };
118
+ }
119
+ else if (!isActiveOrReadyStatus(workstreamStatus)) {
120
+ reassignment = { scheduled: false, reason: "workstream_not_active_or_ready" };
121
+ }
122
+ else {
123
+ try {
124
+ const scheduled = await deps.scheduleWorkstreamReassignment({
125
+ initiativeId,
126
+ workstreamId: id,
127
+ status: workstreamStatus,
128
+ event: "workstream_reassigned",
129
+ });
130
+ reassignment = {
131
+ scheduled: true,
132
+ requestId: scheduled && typeof scheduled === "object"
133
+ ? (deps.pickString(scheduled, ["requestId"]) ?? null)
134
+ : null,
135
+ dueAt: scheduled && typeof scheduled === "object"
136
+ ? (deps.pickString(scheduled, ["dueAt"]) ?? null)
137
+ : null,
138
+ };
139
+ }
140
+ catch (reassignmentErr) {
141
+ reassignment = {
142
+ scheduled: false,
143
+ reason: `schedule_failed:${deps.safeErrorMessage(reassignmentErr)}`,
144
+ };
145
+ }
146
+ }
147
+ }
148
+ if (normalizedType === "initiative" &&
149
+ deps.scheduleWorkstreamReassignment &&
150
+ includesWorkstreamReassignmentMutation(normalizedUpdates)) {
151
+ const workstreams = await deps.client.listEntities("workstream", {
152
+ initiative_id: id,
153
+ limit: 200,
154
+ });
155
+ const workstreamRows = toObjectArray(workstreams && typeof workstreams === "object"
156
+ ? workstreams.data
157
+ : []);
158
+ const failures = [];
159
+ let requested = 0;
160
+ let scheduled = 0;
161
+ let skipped = 0;
162
+ for (const row of workstreamRows) {
163
+ const workstreamId = deps.pickString(row, ["id"]);
164
+ if (!workstreamId) {
165
+ skipped += 1;
166
+ continue;
167
+ }
168
+ const workstreamStatus = deps.pickString(row, ["status"]);
169
+ requested += 1;
170
+ if (!isActiveOrReadyStatus(workstreamStatus)) {
171
+ skipped += 1;
172
+ continue;
173
+ }
174
+ try {
175
+ await deps.scheduleWorkstreamReassignment({
176
+ initiativeId: id,
177
+ workstreamId,
178
+ status: workstreamStatus,
179
+ event: "initiative_reassigned",
180
+ });
181
+ scheduled += 1;
182
+ }
183
+ catch (reassignmentErr) {
184
+ failures.push(`${workstreamId}:${deps.safeErrorMessage(reassignmentErr)}`);
185
+ }
186
+ }
187
+ initiativeReassignment = {
188
+ triggered: true,
189
+ requested,
190
+ scheduled,
191
+ skipped,
192
+ failures,
193
+ };
194
+ }
62
195
  if (normalizedType === "initiative") {
63
196
  deps.clearLocalInitiativeStatusOverride(id);
64
197
  }
65
- deps.sendJson(res, 200, { ok: true, entity });
198
+ deps.sendJson(res, 200, { ok: true, entity, reassignment, initiative_reassignment: initiativeReassignment });
66
199
  }
67
200
  catch (err) {
68
201
  if (type?.trim().toLowerCase() === "initiative" &&
@@ -87,7 +220,7 @@ export function registerEntitiesRoutes(router, deps) {
87
220
  });
88
221
  }
89
222
  }, "Update entity");
90
- async function renderEntityList(query, res) {
223
+ async function renderEntityList(query, res, headerScope) {
91
224
  const type = query.get("type");
92
225
  if (!type) {
93
226
  deps.sendJson(res, 400, {
@@ -95,23 +228,92 @@ export function registerEntitiesRoutes(router, deps) {
95
228
  });
96
229
  return;
97
230
  }
231
+ const workspaceScope = resolveWorkspaceScope(query, headerScope, {
232
+ allowProjectScope: false,
233
+ });
234
+ if (workspaceScope.error) {
235
+ deps.sendJson(res, 400, { error: workspaceScope.error });
236
+ return;
237
+ }
98
238
  const status = query.get("status") ?? undefined;
239
+ const id = query.get("id") ?? undefined;
240
+ const ids = query
241
+ .get("ids")
242
+ ?.split(",")
243
+ .map((value) => value.trim())
244
+ .filter((value) => value.length > 0);
245
+ const search = query.get("search")?.trim() || undefined;
99
246
  const initiativeId = query.get("initiative_id") ?? undefined;
247
+ const workspaceId = workspaceScope.workspaceId ?? undefined;
100
248
  const limit = query.get("limit") ? Number(query.get("limit")) : undefined;
249
+ const offset = query.get("offset") ? Number(query.get("offset")) : undefined;
101
250
  try {
102
251
  const data = await deps.client.listEntities(type, {
252
+ id,
253
+ ids,
254
+ search,
103
255
  status,
104
256
  initiative_id: initiativeId,
257
+ workspace_id: workspaceId,
258
+ command_center_id: workspaceId,
105
259
  limit: Number.isFinite(limit) ? limit : undefined,
260
+ offset: Number.isFinite(offset) ? offset : undefined,
106
261
  });
107
262
  if (type.trim().toLowerCase() === "initiative") {
108
263
  const payload = data;
109
- const rows = Array.isArray(payload.data)
264
+ const rawRows = Array.isArray(payload.data)
110
265
  ? payload.data.filter((row) => Boolean(row && typeof row === "object"))
111
266
  : [];
267
+ const filteredById = rawRows.filter((row) => {
268
+ const rowId = deps.pickString(row, ["id"])?.trim();
269
+ if (!rowId)
270
+ return false;
271
+ if (id && rowId !== id.trim())
272
+ return false;
273
+ if (ids && ids.length > 0 && !ids.includes(rowId))
274
+ return false;
275
+ return true;
276
+ });
277
+ const searchTokens = typeof search === "string" && search.length > 0
278
+ ? Array.from(new Set(search
279
+ .toLowerCase()
280
+ .split(/\s+/)
281
+ .map((token) => token.trim())
282
+ .filter((token) => token.length > 0)))
283
+ : [];
284
+ const searchedRows = searchTokens.length > 0
285
+ ? filteredById.filter((row) => {
286
+ const haystack = [
287
+ deps.pickString(row, ["title", "name"]) ?? "",
288
+ deps.pickString(row, ["summary", "description"]) ?? "",
289
+ deps.pickString(row, ["status"]) ?? "",
290
+ ]
291
+ .join(" ")
292
+ .toLowerCase();
293
+ return searchTokens.every((token) => haystack.includes(token));
294
+ })
295
+ : filteredById;
296
+ const workspaceScopeId = (workspaceId ?? "").trim();
297
+ const rows = workspaceScopeId.length > 0
298
+ ? searchedRows.filter((row) => {
299
+ const rowScope = deps.pickString(row, [
300
+ "workspace_id",
301
+ "workspaceId",
302
+ "command_center_id",
303
+ "commandCenterId",
304
+ ]) ?? "";
305
+ return rowScope.trim() === workspaceScopeId;
306
+ })
307
+ : searchedRows;
112
308
  deps.sendJson(res, 200, {
113
309
  ...payload,
114
310
  data: deps.applyLocalInitiativeOverrides(rows),
311
+ pagination: payload.pagination && typeof payload.pagination === "object"
312
+ ? {
313
+ ...payload.pagination,
314
+ total: rows.length,
315
+ }
316
+ : payload.pagination,
115
317
  });
116
318
  return;
117
319
  }
@@ -131,7 +333,22 @@ export function registerEntitiesRoutes(router, deps) {
131
333
  created_at: null,
132
334
  updated_at: null,
133
335
  }))
134
- .filter((item) => (initiativeId ? item.id === initiativeId : true));
336
+ .filter((item) => (initiativeId ? item.id === initiativeId : true))
337
+ .filter((item) => (id ? item.id === id : true))
338
+ .filter((item) => ids && ids.length > 0 ? ids.includes(item.id) : true)
339
+ .filter((item) => {
340
+ if (!search)
341
+ return true;
342
+ const searchTokens = search
343
+ .toLowerCase()
344
+ .split(/\s+/)
345
+ .map((token) => token.trim())
346
+ .filter((token) => token.length > 0);
347
+ if (searchTokens.length === 0)
348
+ return true;
349
+ const haystack = `${item.title} ${item.summary ?? ""} ${item.status ?? ""}`.toLowerCase();
350
+ return searchTokens.every((token) => haystack.includes(token));
351
+ });
135
352
  deps.sendJson(res, 200, {
136
353
  data: deps.applyLocalInitiativeOverrides(snapshotInitiatives),
137
354
  localFallback: true,
@@ -139,13 +356,22 @@ export function registerEntitiesRoutes(router, deps) {
139
356
  });
140
357
  return;
141
358
  }
359
+ if (type.trim().toLowerCase() === "command_center") {
360
+ deps.sendJson(res, 200, {
361
+ data: [],
362
+ pagination: { total: 0, has_more: false },
363
+ localFallback: true,
364
+ warning: deps.safeErrorMessage(err),
365
+ });
366
+ return;
367
+ }
142
368
  deps.sendJson(res, 500, {
143
369
  error: deps.safeErrorMessage(err),
144
370
  });
145
371
  }
146
372
  }
147
- router.add("GET", "entities", async ({ query, res }) => renderEntityList(query, res), "List entities");
148
- router.add("HEAD", "entities", async ({ query, res }) => renderEntityList(query, res), "List entities (HEAD)");
373
+ router.add("GET", "entities", async ({ query, res, req }) => renderEntityList(query, res, workspaceScopeFromHeaders(req?.headers)), "List entities");
374
+ router.add("HEAD", "entities", async ({ query, res, req }) => renderEntityList(query, res, workspaceScopeFromHeaders(req?.headers)), "List entities (HEAD)");
149
375
  router.add("*", "entities", ({ res }) => {
150
376
  deps.sendJson(res, 405, { error: "Method not allowed" });
151
377
  }, "Reject unsupported methods for entities");
@@ -37,13 +37,18 @@ type RouteResLike = {
37
37
  type RegisterLiveLegacyRoutesDeps<TRes extends RouteResLike> = {
38
38
  getLiveSessions: (input: {
39
39
  initiative: string | null;
40
+ projectId: string | null;
40
41
  limit: number | undefined;
41
42
  }) => Promise<LiveSessionsResponse>;
42
43
  getLiveActivity: (input: {
43
44
  run: string | null;
44
45
  since: string | null;
46
+ projectId: string | null;
45
47
  limit: number | undefined;
46
48
  }) => Promise<LiveActivityResponse>;
49
+ listInitiativeIdsForProject: (input: {
50
+ projectId: string;
51
+ }) => Promise<string[]>;
47
52
  listRuntimeInstances: (input: {
48
53
  limit: number;
49
54
  }) => RuntimeInstanceRecord[];