@useorgx/openclaw-plugin 0.7.20 → 0.7.23

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 (160) hide show
  1. package/dashboard/dist/assets/9gFmK3Kr.js +1 -0
  2. package/dashboard/dist/assets/9gFmK3Kr.js.br +0 -0
  3. package/dashboard/dist/assets/9gFmK3Kr.js.gz +0 -0
  4. package/dashboard/dist/assets/{BoDhb8_y.js → BrMXbzQ-.js} +2 -2
  5. package/dashboard/dist/assets/BrMXbzQ-.js.br +0 -0
  6. package/dashboard/dist/assets/BrMXbzQ-.js.gz +0 -0
  7. package/dashboard/dist/assets/By0MIBj_.js +1 -0
  8. package/dashboard/dist/assets/By0MIBj_.js.br +0 -0
  9. package/dashboard/dist/assets/By0MIBj_.js.gz +0 -0
  10. package/dashboard/dist/assets/C1u2SGin.css +1 -0
  11. package/dashboard/dist/assets/C1u2SGin.css.br +0 -0
  12. package/dashboard/dist/assets/C1u2SGin.css.gz +0 -0
  13. package/dashboard/dist/assets/{DAr4MfFk.js → CGJiHCIx.js} +1 -1
  14. package/dashboard/dist/assets/CGJiHCIx.js.br +0 -0
  15. package/dashboard/dist/assets/CGJiHCIx.js.gz +0 -0
  16. package/dashboard/dist/assets/CSd4rSuU.js +212 -0
  17. package/dashboard/dist/assets/CSd4rSuU.js.br +0 -0
  18. package/dashboard/dist/assets/CSd4rSuU.js.gz +0 -0
  19. package/dashboard/dist/assets/{DibzNd0I.js → CZXS5i_5.js} +1 -1
  20. package/dashboard/dist/assets/CZXS5i_5.js.br +0 -0
  21. package/dashboard/dist/assets/CZXS5i_5.js.gz +0 -0
  22. package/dashboard/dist/assets/{wa4jJQK9.js → CbVWL74-.js} +1 -1
  23. package/dashboard/dist/assets/CbVWL74-.js.br +0 -0
  24. package/dashboard/dist/assets/CbVWL74-.js.gz +0 -0
  25. package/dashboard/dist/assets/{Dm0CfDGr.js → D-FuHfT8.js} +1 -1
  26. package/dashboard/dist/assets/D-FuHfT8.js.br +0 -0
  27. package/dashboard/dist/assets/D-FuHfT8.js.gz +0 -0
  28. package/dashboard/dist/assets/{DXVs61e1.js → D0PN5_vY.js} +1 -1
  29. package/dashboard/dist/assets/D0PN5_vY.js.br +0 -0
  30. package/dashboard/dist/assets/D0PN5_vY.js.gz +0 -0
  31. package/dashboard/dist/assets/{_zpQCpjm.js → DDCPrZRt.js} +1 -1
  32. package/dashboard/dist/assets/DDCPrZRt.js.br +0 -0
  33. package/dashboard/dist/assets/DDCPrZRt.js.gz +0 -0
  34. package/dashboard/dist/assets/{BYb6DARX.js → DNQ-iFO2.js} +1 -1
  35. package/dashboard/dist/assets/DNQ-iFO2.js.br +0 -0
  36. package/dashboard/dist/assets/DNQ-iFO2.js.gz +0 -0
  37. package/dashboard/dist/assets/{BGY6oI8h.js → DhPuHPK7.js} +1 -1
  38. package/dashboard/dist/assets/DhPuHPK7.js.br +0 -0
  39. package/dashboard/dist/assets/DhPuHPK7.js.gz +0 -0
  40. package/dashboard/dist/assets/Dhz7qPtn.js +1 -0
  41. package/dashboard/dist/assets/Dhz7qPtn.js.br +0 -0
  42. package/dashboard/dist/assets/Dhz7qPtn.js.gz +0 -0
  43. package/dashboard/dist/assets/LOFrVoPD.js +1 -0
  44. package/dashboard/dist/assets/LOFrVoPD.js.br +0 -0
  45. package/dashboard/dist/assets/LOFrVoPD.js.gz +0 -0
  46. package/dashboard/dist/assets/OlLPtzdz.js +1 -0
  47. package/dashboard/dist/assets/OlLPtzdz.js.br +0 -0
  48. package/dashboard/dist/assets/OlLPtzdz.js.gz +0 -0
  49. package/dashboard/dist/assets/{B014hrCe.js → RN4M9u9W.js} +2 -2
  50. package/dashboard/dist/assets/RN4M9u9W.js.br +0 -0
  51. package/dashboard/dist/assets/RN4M9u9W.js.gz +0 -0
  52. package/dashboard/dist/assets/VCHu272d.js +1 -0
  53. package/dashboard/dist/assets/VCHu272d.js.br +0 -0
  54. package/dashboard/dist/assets/VCHu272d.js.gz +0 -0
  55. package/dashboard/dist/assets/m2smti3F.js +1 -0
  56. package/dashboard/dist/assets/m2smti3F.js.br +0 -0
  57. package/dashboard/dist/assets/m2smti3F.js.gz +0 -0
  58. package/dashboard/dist/assets/{CV0sWMbv.js → nra1yvJX.js} +1 -1
  59. package/dashboard/dist/assets/nra1yvJX.js.br +0 -0
  60. package/dashboard/dist/assets/nra1yvJX.js.gz +0 -0
  61. package/dashboard/dist/assets/qLX6NZ-J.js +1 -0
  62. package/dashboard/dist/assets/qLX6NZ-J.js.br +0 -0
  63. package/dashboard/dist/assets/qLX6NZ-J.js.gz +0 -0
  64. package/dashboard/dist/index.html +2 -2
  65. package/dashboard/dist/index.html.br +0 -0
  66. package/dashboard/dist/index.html.gz +0 -0
  67. package/dist/agent-run-store.js +162 -24
  68. package/dist/cli/orgx.d.ts +3 -0
  69. package/dist/config/resolution.d.ts +7 -0
  70. package/dist/config/resolution.js +13 -5
  71. package/dist/contracts/onboarding-state.d.ts +2 -0
  72. package/dist/contracts/onboarding-state.js +23 -0
  73. package/dist/contracts/shared-types.d.ts +17 -0
  74. package/dist/http/helpers/auto-continue-engine.d.ts +23 -0
  75. package/dist/http/helpers/auto-continue-engine.js +233 -53
  76. package/dist/http/helpers/autopilot-runtime.js +5 -1
  77. package/dist/http/helpers/autopilot-slice-utils.js +25 -1
  78. package/dist/http/helpers/decision-mapper.d.ts +1 -0
  79. package/dist/http/helpers/decision-mapper.js +19 -2
  80. package/dist/http/helpers/dispatch-lifecycle.js +3 -0
  81. package/dist/http/helpers/mission-control.d.ts +1 -0
  82. package/dist/http/helpers/mission-control.js +5 -2
  83. package/dist/http/helpers/slice-run-projections.d.ts +27 -0
  84. package/dist/http/helpers/slice-run-projections.js +198 -10
  85. package/dist/http/helpers/triage-mapper.js +220 -6
  86. package/dist/http/index.d.ts +1 -0
  87. package/dist/http/index.js +92 -45
  88. package/dist/http/router.js +64 -9
  89. package/dist/http/routes/live-legacy.d.ts +19 -2
  90. package/dist/http/routes/live-legacy.js +110 -27
  91. package/dist/http/routes/live-snapshot.d.ts +16 -2
  92. package/dist/http/routes/live-snapshot.js +169 -25
  93. package/dist/http/routes/mission-control-actions.js +28 -0
  94. package/dist/http/routes/mission-control-read.d.ts +4 -0
  95. package/dist/http/routes/mission-control-read.js +67 -219
  96. package/dist/http/routes/onboarding.d.ts +1 -0
  97. package/dist/http/routes/onboarding.js +17 -0
  98. package/dist/index.d.ts +5 -0
  99. package/dist/index.js +199 -123
  100. package/dist/outbox.d.ts +0 -2
  101. package/dist/outbox.js +259 -148
  102. package/dist/reporting/rollups.js +18 -11
  103. package/dist/runtime-instance-store.js +212 -58
  104. package/dist/stores/materialized-snapshot-store.d.ts +18 -0
  105. package/dist/stores/materialized-snapshot-store.js +91 -0
  106. package/dist/stores/sqlite-state.d.ts +6 -0
  107. package/dist/stores/sqlite-state.js +179 -0
  108. package/package.json +5 -1
  109. package/dashboard/dist/assets/B014hrCe.js.br +0 -0
  110. package/dashboard/dist/assets/B014hrCe.js.gz +0 -0
  111. package/dashboard/dist/assets/BCudUvwg.js +0 -1
  112. package/dashboard/dist/assets/BCudUvwg.js.br +0 -0
  113. package/dashboard/dist/assets/BCudUvwg.js.gz +0 -0
  114. package/dashboard/dist/assets/BGY6oI8h.js.br +0 -0
  115. package/dashboard/dist/assets/BGY6oI8h.js.gz +0 -0
  116. package/dashboard/dist/assets/BJI1Iy5v.css +0 -1
  117. package/dashboard/dist/assets/BJI1Iy5v.css.br +0 -0
  118. package/dashboard/dist/assets/BJI1Iy5v.css.gz +0 -0
  119. package/dashboard/dist/assets/BUvcp_7V.js +0 -1
  120. package/dashboard/dist/assets/BUvcp_7V.js.br +0 -0
  121. package/dashboard/dist/assets/BUvcp_7V.js.gz +0 -0
  122. package/dashboard/dist/assets/BV2Tf8S2.js +0 -212
  123. package/dashboard/dist/assets/BV2Tf8S2.js.br +0 -0
  124. package/dashboard/dist/assets/BV2Tf8S2.js.gz +0 -0
  125. package/dashboard/dist/assets/BYb6DARX.js.br +0 -0
  126. package/dashboard/dist/assets/BYb6DARX.js.gz +0 -0
  127. package/dashboard/dist/assets/BoDhb8_y.js.br +0 -0
  128. package/dashboard/dist/assets/BoDhb8_y.js.gz +0 -0
  129. package/dashboard/dist/assets/Bqk_l0k6.js +0 -1
  130. package/dashboard/dist/assets/Bqk_l0k6.js.br +0 -0
  131. package/dashboard/dist/assets/Bqk_l0k6.js.gz +0 -0
  132. package/dashboard/dist/assets/C-MOJWHs.js +0 -1
  133. package/dashboard/dist/assets/C-MOJWHs.js.br +0 -0
  134. package/dashboard/dist/assets/C-MOJWHs.js.gz +0 -0
  135. package/dashboard/dist/assets/CV0sWMbv.js.br +0 -0
  136. package/dashboard/dist/assets/CV0sWMbv.js.gz +0 -0
  137. package/dashboard/dist/assets/CaAkScfa.js +0 -1
  138. package/dashboard/dist/assets/CaAkScfa.js.br +0 -0
  139. package/dashboard/dist/assets/CaAkScfa.js.gz +0 -0
  140. package/dashboard/dist/assets/Ck5KlsPN.js +0 -1
  141. package/dashboard/dist/assets/Ck5KlsPN.js.br +0 -0
  142. package/dashboard/dist/assets/Ck5KlsPN.js.gz +0 -0
  143. package/dashboard/dist/assets/D2G51wQm.js +0 -1
  144. package/dashboard/dist/assets/D2G51wQm.js.br +0 -0
  145. package/dashboard/dist/assets/D2G51wQm.js.gz +0 -0
  146. package/dashboard/dist/assets/DAr4MfFk.js.br +0 -0
  147. package/dashboard/dist/assets/DAr4MfFk.js.gz +0 -0
  148. package/dashboard/dist/assets/DXVs61e1.js.br +0 -0
  149. package/dashboard/dist/assets/DXVs61e1.js.gz +0 -0
  150. package/dashboard/dist/assets/DibzNd0I.js.br +0 -0
  151. package/dashboard/dist/assets/DibzNd0I.js.gz +0 -0
  152. package/dashboard/dist/assets/Dm0CfDGr.js.br +0 -0
  153. package/dashboard/dist/assets/Dm0CfDGr.js.gz +0 -0
  154. package/dashboard/dist/assets/_zpQCpjm.js.br +0 -0
  155. package/dashboard/dist/assets/_zpQCpjm.js.gz +0 -0
  156. package/dashboard/dist/assets/uNGpYMSH.js +0 -1
  157. package/dashboard/dist/assets/uNGpYMSH.js.br +0 -0
  158. package/dashboard/dist/assets/uNGpYMSH.js.gz +0 -0
  159. package/dashboard/dist/assets/wa4jJQK9.js.br +0 -0
  160. package/dashboard/dist/assets/wa4jJQK9.js.gz +0 -0
@@ -1,5 +1,6 @@
1
1
  import { listBuiltInSentinels } from "../helpers/sentinel-catalog.js";
2
2
  import { resolveWorkspaceScope, workspaceScopeFromHeaders, } from "../helpers/workspace-scope.js";
3
+ import { isDoneStatus, normalizeMissionControlStatus, } from "../helpers/mission-control.js";
3
4
  import { asRecord, asString, asNumber, asArray, asStringArray, } from "../../lib/type-coercion.js";
4
5
  // asRecord, asString, asArray, asNumber, asStringArray imported from ../../lib/type-coercion.js
5
6
  function normalizeRunnerValue(value) {
@@ -313,7 +314,7 @@ async function requestCanonicalWithLegacyFallback(deps, input) {
313
314
  return await withSoftTimeout(deps.rawRequest("GET", input.legacyPath), Math.min(input.timeoutMs, 1_500), `${input.label} (legacy fallback)`);
314
315
  }
315
316
  function normalizeQueueState(value) {
316
- const normalized = normalizeStatus(asString(value));
317
+ const normalized = normalizeMissionControlStatus(asString(value));
317
318
  if (normalized === "running" || normalized === "in_progress") {
318
319
  return "running";
319
320
  }
@@ -336,19 +337,6 @@ function normalizeQueueState(value) {
336
337
  return "completed";
337
338
  return "idle";
338
339
  }
339
- function normalizeStatus(value) {
340
- return (value ?? "").trim().toLowerCase().replace(/[\s-]+/g, "_");
341
- }
342
- function isDoneStatus(value) {
343
- const normalized = normalizeStatus(value);
344
- return (normalized === "done" ||
345
- normalized === "completed" ||
346
- normalized === "resolved" ||
347
- normalized === "cancelled" ||
348
- normalized === "canceled" ||
349
- normalized === "archived" ||
350
- normalized === "closed");
351
- }
352
340
  function queueStateRank(state) {
353
341
  if (state === "running")
354
342
  return 0;
@@ -476,7 +464,7 @@ function normalizeQueueItems(input) {
476
464
  ? runnerSourceHint ?? "inferred"
477
465
  : "fallback";
478
466
  const queueState = normalizeQueueState(record.queueState ?? record.queue_state);
479
- const normalizedSliceScope = normalizeStatus(asString(record.sliceScope) ?? asString(record.slice_scope));
467
+ const normalizedSliceScope = normalizeMissionControlStatus(asString(record.sliceScope) ?? asString(record.slice_scope));
480
468
  const sliceScope = normalizedSliceScope === "task" ||
481
469
  normalizedSliceScope === "milestone" ||
482
470
  normalizedSliceScope === "workstream"
@@ -561,6 +549,34 @@ function normalizeQueueItems(input) {
561
549
  return left.workstreamTitle.localeCompare(right.workstreamTitle);
562
550
  });
563
551
  }
552
+ function summarizeQueueItems(items) {
553
+ const stateCounts = {
554
+ queued: 0,
555
+ running: 0,
556
+ blocked: 0,
557
+ idle: 0,
558
+ completed: 0,
559
+ };
560
+ for (const item of items) {
561
+ stateCounts[item.queueState] += 1;
562
+ }
563
+ return {
564
+ visibleTotal: items.filter((item) => item.queueState !== "running" && item.queueState !== "completed").length,
565
+ stateCounts,
566
+ };
567
+ }
568
+ function dedupeQueueItemsByLineage(items) {
569
+ const seen = new Set();
570
+ const deduped = [];
571
+ for (const item of items) {
572
+ const key = `${item.initiativeId}:${item.workstreamId}`;
573
+ if (seen.has(key))
574
+ continue;
575
+ seen.add(key);
576
+ deduped.push(item);
577
+ }
578
+ return deduped;
579
+ }
564
580
  function isHighSeverityQueueItem(item) {
565
581
  if (item.scoringTier === "urgent")
566
582
  return true;
@@ -613,134 +629,6 @@ function applyQueueNoiseControls(items, options) {
613
629
  }
614
630
  return deduped;
615
631
  }
616
- function mapCanonicalSlicesToQueueItems(input) {
617
- const queueLike = [];
618
- for (const entry of input) {
619
- const record = asRecord(entry);
620
- if (!record)
621
- continue;
622
- const sliceKind = (asString(record.sliceKind) ?? asString(record.slice_kind) ?? "")
623
- .trim()
624
- .toLowerCase();
625
- if (sliceKind && sliceKind !== "work_slice")
626
- continue;
627
- const initiativeId = asString(record.initiativeId) ?? asString(record.initiative_id);
628
- const workstreamId = asString(record.workstreamId) ?? asString(record.workstream_id);
629
- if (!initiativeId || !workstreamId)
630
- continue;
631
- const dispatch = asRecord(record.dispatch) ?? {};
632
- const lineage = asRecord(record.lineage) ?? {};
633
- const taskId = asString(record.taskId) ?? asString(record.task_id);
634
- const sliceTaskIds = dedupeStrings([
635
- ...asStringArray(record.sliceTaskIds),
636
- ...asStringArray(record.slice_task_ids),
637
- ...asStringArray(lineage.taskIds),
638
- ...asStringArray(lineage.task_ids),
639
- ...(taskId ? [taskId] : []),
640
- ]);
641
- const rawStatus = asString(record.status) ?? "active";
642
- const normalizedStatus = normalizeStatus(rawStatus);
643
- const runnable = Boolean(dispatch.runnable);
644
- let queueState;
645
- if (isDoneStatus(rawStatus)) {
646
- queueState = "completed";
647
- }
648
- else if (normalizedStatus === "running" || normalizedStatus === "in_progress") {
649
- queueState = "running";
650
- }
651
- else if (normalizedStatus === "blocked" ||
652
- normalizedStatus === "waiting_dependency" ||
653
- normalizedStatus === "needs_decision" ||
654
- normalizedStatus === "waiting_on_decision" ||
655
- normalizedStatus === "paused" ||
656
- !runnable) {
657
- queueState = "blocked";
658
- }
659
- else if (normalizedStatus === "idle" ||
660
- normalizedStatus === "not_started" ||
661
- normalizedStatus === "draft") {
662
- queueState = "idle";
663
- }
664
- else {
665
- queueState = "queued";
666
- }
667
- const runnerAgentIdRaw = normalizeRunnerValue(record.runnerAgentId) ?? normalizeRunnerValue(record.runner_agent_id);
668
- const runnerAgentNameRaw = normalizeRunnerValue(record.runnerAgentName) ?? normalizeRunnerValue(record.runner_agent_name);
669
- const runnerAgents = mergeRunnerAgents(normalizeRunnerAgents(record.runnerAgents), normalizeRunnerAgents(record.runner_agents), runnerAgentIdRaw || runnerAgentNameRaw
670
- ? [
671
- {
672
- id: runnerAgentIdRaw ?? runnerAgentNameRaw ?? "Unassigned",
673
- name: runnerAgentNameRaw ?? runnerAgentIdRaw ?? "Unassigned",
674
- },
675
- ]
676
- : []);
677
- const runnerSourceHint = normalizeRunnerSource(record.runnerSource) ?? normalizeRunnerSource(record.runner_source);
678
- const runnerSource = runnerAgents.length > 0 ? runnerSourceHint ?? "inferred" : "fallback";
679
- const suggestedScope = normalizeStatus(asString(dispatch.suggestedScope) ??
680
- asString(dispatch.suggested_scope) ??
681
- asString(record.level));
682
- const sliceScope = suggestedScope === "task" ||
683
- suggestedScope === "milestone" ||
684
- suggestedScope === "workstream"
685
- ? suggestedScope
686
- : null;
687
- const order = asRecord(record.order) ?? {};
688
- const manualRank = asNumber(order.manualRank ?? order.manual_rank);
689
- const iwmt = asRecord(record.iwmt);
690
- const objective = asRecord(record.objective);
691
- queueLike.push({
692
- initiativeId,
693
- initiativeTitle: asString(record.initiativeTitle) ??
694
- asString(record.initiative_title) ??
695
- initiativeId,
696
- initiativeStatus: asString(record.initiativeStatus) ??
697
- asString(record.initiative_status) ??
698
- "active",
699
- initiativePriority: asString(record.initiativePriority) ?? asString(record.initiative_priority),
700
- initiativePriorityNum: asNumber(record.initiativePriorityNum ?? record.initiative_priority_num),
701
- workstreamId,
702
- workstreamTitle: asString(record.workstreamTitle) ??
703
- asString(record.workstream_title) ??
704
- asString(record.title) ??
705
- workstreamId,
706
- workstreamStatus: asString(record.workstreamStatus) ??
707
- asString(record.workstream_status) ??
708
- rawStatus,
709
- nextTaskId: taskId ?? sliceTaskIds[0] ?? null,
710
- nextTaskTitle: asString(record.nextTaskTitle) ?? asString(record.next_task_title),
711
- nextTaskPriority: asNumber(record.priorityNum ??
712
- record.priority_num ??
713
- record.nextTaskPriority ??
714
- record.next_task_priority),
715
- nextTaskDueAt: asString(record.dueAt) ??
716
- asString(record.due_at) ??
717
- asString(record.nextTaskDueAt) ??
718
- asString(record.next_task_due_at),
719
- nextTaskMilestoneId: asString(record.milestoneId) ?? asString(record.milestone_id),
720
- runnerAgentId: runnerAgentIdRaw,
721
- runnerAgentName: runnerAgentNameRaw,
722
- runnerAgents,
723
- runnerSource,
724
- queueState,
725
- blockReason: asString(dispatch.blockReason) ??
726
- asString(dispatch.block_reason) ??
727
- null,
728
- sliceScope,
729
- sliceTaskIds,
730
- sliceTaskCount: sliceTaskIds.length,
731
- sliceMilestoneId: asString(record.milestoneId) ?? asString(record.milestone_id),
732
- isPinned: typeof manualRank === "number",
733
- pinnedRank: manualRank,
734
- compositeScore: asNumber(iwmt?.mixScore ?? objective?.objectiveScore),
735
- objectiveScore: asNumber(objective?.objectiveScore) ?? undefined,
736
- roiPerToken: asNumber(iwmt?.roiPerToken) ?? undefined,
737
- expectedTokens: asNumber(iwmt?.expectedTokens) ?? undefined,
738
- expectedValueUsd: asNumber(iwmt?.expectedValueUsd) ?? undefined,
739
- updatedAt: asString(record.updatedAt) ?? asString(record.updated_at) ?? null,
740
- });
741
- }
742
- return normalizeQueueItems(queueLike);
743
- }
744
632
  async function loadInitiativeGraphIndex(deps, initiativeId) {
745
633
  const graphRaw = deps.applyLocalInitiativeOverrideToGraph(await deps.buildMissionControlGraph(initiativeId));
746
634
  const graph = asRecord(graphRaw);
@@ -1024,6 +912,35 @@ export function registerMissionControlReadRoutes(router, deps) {
1024
912
  limit: pageSize,
1025
913
  total: canonicalTotal,
1026
914
  });
915
+ let canonicalSummaryItems = canonicalItems;
916
+ const summaryPageSize = Math.max(pageSize, Math.min(canonicalTotal, 200));
917
+ if (canonicalTotal > canonicalItems.length) {
918
+ const summaryItems = [];
919
+ for (let summaryOffset = 0; summaryOffset < canonicalTotal; summaryOffset += summaryPageSize) {
920
+ const summaryParams = new URLSearchParams(params);
921
+ summaryParams.set("offset", String(summaryOffset));
922
+ summaryParams.set("limit", String(summaryPageSize));
923
+ const summaryPage = await requestCanonicalWithLegacyFallback(deps, {
924
+ timeoutMs: CANONICAL_NEXT_UP_TIMEOUT_MS,
925
+ label: "canonical next-up summary",
926
+ modernPath: `/api/client/mission-control/next-up?${summaryParams.toString()}`,
927
+ legacyPath: `/api/mission-control/next-up?${summaryParams.toString()}`,
928
+ });
929
+ const summaryRecord = asRecord(summaryPage);
930
+ if (!summaryRecord || !Array.isArray(summaryRecord.items)) {
931
+ throw new Error("invalid canonical next-up summary payload");
932
+ }
933
+ const normalizedSummaryItems = applyQueueNoiseControls(normalizeQueueItems(summaryRecord.items).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs });
934
+ summaryItems.push(...normalizedSummaryItems);
935
+ if (normalizedSummaryItems.length < summaryPageSize) {
936
+ break;
937
+ }
938
+ }
939
+ canonicalSummaryItems =
940
+ summaryItems.length > 0
941
+ ? dedupeQueueItemsByLineage(summaryItems)
942
+ : canonicalItems;
943
+ }
1027
944
  const shouldRepaginateCanonically = canonicalItems.length > pageSize ||
1028
945
  canonicalPagination.offset !== offset ||
1029
946
  canonicalPagination.limit !== pageSize;
@@ -1036,11 +953,13 @@ export function registerMissionControlReadRoutes(router, deps) {
1036
953
  })
1037
954
  : null;
1038
955
  const degraded = dedupeStrings(asStringArray(canonicalRecord.degraded));
956
+ const canonicalSummary = summarizeQueueItems(canonicalSummaryItems);
1039
957
  const responsePayload = {
1040
958
  ok: true,
1041
959
  generatedAt: asString(canonicalRecord.generatedAt) ?? new Date().toISOString(),
1042
960
  total: paged ? paged.filtered.length : canonicalPagination.total,
1043
961
  items: paged ? paged.paged : canonicalItems,
962
+ summary: canonicalSummary,
1044
963
  pagination: paged ? paged.pagination : canonicalPagination,
1045
964
  source: "canonical",
1046
965
  degraded,
@@ -1109,79 +1028,6 @@ export function registerMissionControlReadRoutes(router, deps) {
1109
1028
  return;
1110
1029
  }
1111
1030
  canonicalFallbackReason = `canonical next-up unavailable (${deps.safeErrorMessage(err)})`;
1112
- if (projectId || useAllScope) {
1113
- try {
1114
- const bridgeParams = new URLSearchParams();
1115
- if (initiativeId)
1116
- bridgeParams.set("initiative_id", initiativeId);
1117
- if (projectId) {
1118
- bridgeParams.set("workspace_id", projectId);
1119
- bridgeParams.set("command_center_id", projectId);
1120
- }
1121
- else if (useAllScope) {
1122
- bridgeParams.set("workspace_id", "all");
1123
- bridgeParams.set("command_center_id", "all");
1124
- }
1125
- bridgeParams.set("level", "workstream");
1126
- bridgeParams.set("offset", String(Math.max(0, offset)));
1127
- bridgeParams.set("limit", String(Math.min(300, Math.max(pageSize, offset + pageSize))));
1128
- bridgeParams.set("include_completed", includeCompleted ? "1" : "0");
1129
- bridgeParams.set("noise_threshold", noiseThreshold);
1130
- bridgeParams.set("dedup_window", String(dedupWindowMs));
1131
- bridgeParams.set("mix_policy", requestedMixPolicy ?? "iwmt_v1");
1132
- if (requestedOrderMode) {
1133
- bridgeParams.set("order_mode", requestedOrderMode);
1134
- }
1135
- const canonicalSlices = await requestCanonicalWithLegacyFallback(deps, {
1136
- timeoutMs: CANONICAL_SLICES_TIMEOUT_MS,
1137
- label: "canonical slices bridge",
1138
- modernPath: `/api/client/mission-control/slices?${bridgeParams.toString()}`,
1139
- legacyPath: `/api/mission-control/slices?${bridgeParams.toString()}`,
1140
- });
1141
- const canonicalSlicesRecord = asRecord(canonicalSlices);
1142
- if (!canonicalSlicesRecord || !Array.isArray(canonicalSlicesRecord.items)) {
1143
- throw new Error("invalid canonical slices payload");
1144
- }
1145
- if (isCanonicalAllScopeMismatch(canonicalSlicesRecord, useAllScope)) {
1146
- throw new Error("canonical slices all-workspaces scope mismatch");
1147
- }
1148
- const bridgedItems = await enrichWithMilestoneBreakdown(applyQueueNoiseControls(mapCanonicalSlicesToQueueItems(canonicalSlicesRecord.items).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs }), deps);
1149
- if (bridgedItems.length > 0) {
1150
- const paged = applySliceSearchAndPagination({
1151
- items: bridgedItems,
1152
- searchTerm: "",
1153
- offset,
1154
- limit: pageSize,
1155
- });
1156
- const degraded = dedupeStrings([
1157
- ...(Array.isArray(canonicalSlicesRecord.degraded)
1158
- ? canonicalSlicesRecord.degraded
1159
- : []),
1160
- ...(canonicalFallbackReason ? [canonicalFallbackReason] : []),
1161
- "Next Up derived from canonical slices.",
1162
- ]);
1163
- const responsePayload = {
1164
- ok: true,
1165
- generatedAt: asString(canonicalSlicesRecord.generatedAt) ??
1166
- new Date().toISOString(),
1167
- total: paged.filtered.length,
1168
- items: paged.paged,
1169
- pagination: paged.pagination,
1170
- source: "canonical_slices_bridge",
1171
- degraded,
1172
- };
1173
- writeCanonicalReadCache(nextUpCanonicalCacheKey, responsePayload);
1174
- deps.sendJson(res, 200, responsePayload);
1175
- return;
1176
- }
1177
- }
1178
- catch (bridgeErr) {
1179
- canonicalFallbackReason = dedupeStrings([
1180
- canonicalFallbackReason ?? "",
1181
- `canonical slices bridge unavailable (${deps.safeErrorMessage(bridgeErr)})`,
1182
- ]).join(" | ");
1183
- }
1184
- }
1185
1031
  // Continue to local fallback.
1186
1032
  try {
1187
1033
  const queue = await deps.buildNextUpQueue({
@@ -1204,6 +1050,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1204
1050
  generatedAt: new Date().toISOString(),
1205
1051
  total: paged.filtered.length,
1206
1052
  items: paged.paged,
1053
+ summary: summarizeQueueItems(items),
1207
1054
  pagination: paged.pagination,
1208
1055
  source: "local_fallback",
1209
1056
  degraded,
@@ -1237,6 +1084,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1237
1084
  generatedAt: new Date().toISOString(),
1238
1085
  total: paged.filtered.length,
1239
1086
  items: paged.paged,
1087
+ summary: summarizeQueueItems(items),
1240
1088
  pagination: paged.pagination,
1241
1089
  source: "local",
1242
1090
  degraded: dedupeStrings(degraded),
@@ -1608,7 +1456,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1608
1456
  const taskBuckets = new Map();
1609
1457
  for (const taskId of selectedTaskIds) {
1610
1458
  const task = graphIndex?.tasksById.get(taskId) ?? null;
1611
- if (!includeCompleted && isDoneStatus(task?.status ?? null))
1459
+ if (!includeCompleted && isDoneStatus(task?.status ?? ""))
1612
1460
  continue;
1613
1461
  const milestoneId = task?.milestoneId ??
1614
1462
  item.sliceMilestoneId ??
@@ -1687,7 +1535,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1687
1535
  ]);
1688
1536
  for (const taskId of selectedTaskIds) {
1689
1537
  const task = graphIndex?.tasksById.get(taskId) ?? null;
1690
- if (!includeCompleted && isDoneStatus(task?.status ?? null))
1538
+ if (!includeCompleted && isDoneStatus(task?.status ?? ""))
1691
1539
  continue;
1692
1540
  const taskTitle = task?.title ??
1693
1541
  (taskId === item.nextTaskId ? item.nextTaskTitle : null) ??
@@ -1708,7 +1556,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1708
1556
  : null,
1709
1557
  taskId,
1710
1558
  taskTitle,
1711
- queueState: isDoneStatus(task?.status ?? null) ? "completed" : item.queueState,
1559
+ queueState: isDoneStatus(task?.status ?? "") ? "completed" : item.queueState,
1712
1560
  sourceWorkstreamIds: [item.workstreamId],
1713
1561
  runnerAgentId: (item.runnerAgents ?? [])[0]?.id ?? item.runnerAgentId ?? null,
1714
1562
  runnerAgentName: (item.runnerAgents ?? [])[0]?.name ?? item.runnerAgentName ?? "Unassigned",
@@ -18,6 +18,7 @@ type OnboardingControllerLike = {
18
18
  apiKey: string;
19
19
  userId?: string;
20
20
  }) => Promise<OnboardingState>;
21
+ cancelPairing?: () => Promise<OnboardingState>;
21
22
  disconnect: () => Promise<OnboardingState>;
22
23
  };
23
24
  type RegisterOnboardingRoutesDeps<TReq, TRes> = {
@@ -83,6 +83,23 @@ export function registerOnboardingRoutes(router, deps) {
83
83
  });
84
84
  }
85
85
  }, "Submit manual OrgX API key");
86
+ router.add("POST", "onboarding/cancel", async ({ res }) => {
87
+ try {
88
+ const state = deps.onboarding.cancelPairing
89
+ ? await deps.onboarding.cancelPairing()
90
+ : await deps.onboarding.getStatus();
91
+ deps.sendJson(res, 200, {
92
+ ok: true,
93
+ data: deps.getOnboardingState(state),
94
+ });
95
+ }
96
+ catch (err) {
97
+ deps.sendJson(res, 500, {
98
+ ok: false,
99
+ error: deps.safeErrorMessage(err),
100
+ });
101
+ }
102
+ }, "Cancel onboarding pairing flow");
86
103
  router.add("POST", "onboarding/disconnect", async ({ res }) => {
87
104
  try {
88
105
  const state = await deps.onboarding.disconnect();
package/dist/index.d.ts CHANGED
@@ -22,6 +22,11 @@ export interface PluginAPI {
22
22
  dashboardEnabled: boolean;
23
23
  }>;
24
24
  };
25
+ "openclaw-plugin"?: {
26
+ config?: Partial<OrgXConfig & {
27
+ dashboardEnabled: boolean;
28
+ }>;
29
+ };
25
30
  };
26
31
  };
27
32
  };