@useorgx/openclaw-plugin 0.7.20 → 0.7.24

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 (165) hide show
  1. package/dashboard/dist/assets/B6VftyY6.js +1 -0
  2. package/dashboard/dist/assets/B6VftyY6.js.br +0 -0
  3. package/dashboard/dist/assets/B6VftyY6.js.gz +0 -0
  4. package/dashboard/dist/assets/{Dm0CfDGr.js → BANQdlC4.js} +1 -1
  5. package/dashboard/dist/assets/BANQdlC4.js.br +0 -0
  6. package/dashboard/dist/assets/BANQdlC4.js.gz +0 -0
  7. package/dashboard/dist/assets/{_zpQCpjm.js → BPL4CL3c.js} +1 -1
  8. package/dashboard/dist/assets/BPL4CL3c.js.br +0 -0
  9. package/dashboard/dist/assets/BPL4CL3c.js.gz +0 -0
  10. package/dashboard/dist/assets/{DXVs61e1.js → BZCkOZ20.js} +1 -1
  11. package/dashboard/dist/assets/BZCkOZ20.js.br +0 -0
  12. package/dashboard/dist/assets/BZCkOZ20.js.gz +0 -0
  13. package/dashboard/dist/assets/{BYb6DARX.js → B_LdOJUa.js} +1 -1
  14. package/dashboard/dist/assets/B_LdOJUa.js.br +0 -0
  15. package/dashboard/dist/assets/B_LdOJUa.js.gz +0 -0
  16. package/dashboard/dist/assets/Bfp-wdwb.css +1 -0
  17. package/dashboard/dist/assets/Bfp-wdwb.css.br +0 -0
  18. package/dashboard/dist/assets/Bfp-wdwb.css.gz +0 -0
  19. package/dashboard/dist/assets/{DibzNd0I.js → BvFcH_Iy.js} +1 -1
  20. package/dashboard/dist/assets/BvFcH_Iy.js.br +0 -0
  21. package/dashboard/dist/assets/BvFcH_Iy.js.gz +0 -0
  22. package/dashboard/dist/assets/By0MIBj_.js +1 -0
  23. package/dashboard/dist/assets/By0MIBj_.js.br +0 -0
  24. package/dashboard/dist/assets/By0MIBj_.js.gz +0 -0
  25. package/dashboard/dist/assets/C0i7ABUU.js +212 -0
  26. package/dashboard/dist/assets/C0i7ABUU.js.br +0 -0
  27. package/dashboard/dist/assets/C0i7ABUU.js.gz +0 -0
  28. package/dashboard/dist/assets/CFB0MM7j.js +1 -0
  29. package/dashboard/dist/assets/CFB0MM7j.js.br +0 -0
  30. package/dashboard/dist/assets/CFB0MM7j.js.gz +0 -0
  31. package/dashboard/dist/assets/CQSRb1yu.js +1 -0
  32. package/dashboard/dist/assets/CQSRb1yu.js.br +0 -0
  33. package/dashboard/dist/assets/CQSRb1yu.js.gz +0 -0
  34. package/dashboard/dist/assets/{wa4jJQK9.js → CUoQoSm-.js} +1 -1
  35. package/dashboard/dist/assets/CUoQoSm-.js.br +0 -0
  36. package/dashboard/dist/assets/CUoQoSm-.js.gz +0 -0
  37. package/dashboard/dist/assets/Ckd1R1iE.js +1 -0
  38. package/dashboard/dist/assets/Ckd1R1iE.js.br +0 -0
  39. package/dashboard/dist/assets/Ckd1R1iE.js.gz +0 -0
  40. package/dashboard/dist/assets/{BGY6oI8h.js → CqRNb2EL.js} +1 -1
  41. package/dashboard/dist/assets/CqRNb2EL.js.br +0 -0
  42. package/dashboard/dist/assets/CqRNb2EL.js.gz +0 -0
  43. package/dashboard/dist/assets/{DAr4MfFk.js → DClUc9rw.js} +1 -1
  44. package/dashboard/dist/assets/DClUc9rw.js.br +0 -0
  45. package/dashboard/dist/assets/DClUc9rw.js.gz +0 -0
  46. package/dashboard/dist/assets/DF2PMTwT.js +1 -0
  47. package/dashboard/dist/assets/DF2PMTwT.js.br +0 -0
  48. package/dashboard/dist/assets/DF2PMTwT.js.gz +0 -0
  49. package/dashboard/dist/assets/{B014hrCe.js → DJYl7gyA.js} +2 -2
  50. package/dashboard/dist/assets/DJYl7gyA.js.br +0 -0
  51. package/dashboard/dist/assets/DJYl7gyA.js.gz +0 -0
  52. package/dashboard/dist/assets/{BoDhb8_y.js → DZtNMX0t.js} +2 -2
  53. package/dashboard/dist/assets/DZtNMX0t.js.br +0 -0
  54. package/dashboard/dist/assets/DZtNMX0t.js.gz +0 -0
  55. package/dashboard/dist/assets/DlEa8PI0.js +1 -0
  56. package/dashboard/dist/assets/DlEa8PI0.js.br +0 -0
  57. package/dashboard/dist/assets/DlEa8PI0.js.gz +0 -0
  58. package/dashboard/dist/assets/M4QxcXjh.js +1 -0
  59. package/dashboard/dist/assets/M4QxcXjh.js.br +0 -0
  60. package/dashboard/dist/assets/M4QxcXjh.js.gz +0 -0
  61. package/dashboard/dist/assets/{CV0sWMbv.js → MrW1ixGx.js} +1 -1
  62. package/dashboard/dist/assets/MrW1ixGx.js.br +0 -0
  63. package/dashboard/dist/assets/MrW1ixGx.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/activity-store.js +68 -8
  68. package/dist/agent-run-store.js +162 -24
  69. package/dist/cli/orgx.d.ts +3 -0
  70. package/dist/config/resolution.d.ts +7 -0
  71. package/dist/config/resolution.js +13 -5
  72. package/dist/contracts/onboarding-state.d.ts +2 -0
  73. package/dist/contracts/onboarding-state.js +23 -0
  74. package/dist/contracts/shared-types.d.ts +45 -0
  75. package/dist/http/helpers/auto-continue-engine.d.ts +23 -0
  76. package/dist/http/helpers/auto-continue-engine.js +468 -85
  77. package/dist/http/helpers/autopilot-runtime.js +5 -1
  78. package/dist/http/helpers/autopilot-slice-utils.js +25 -1
  79. package/dist/http/helpers/decision-mapper.d.ts +1 -0
  80. package/dist/http/helpers/decision-mapper.js +19 -2
  81. package/dist/http/helpers/dispatch-lifecycle.js +3 -0
  82. package/dist/http/helpers/mission-control.d.ts +1 -0
  83. package/dist/http/helpers/mission-control.js +5 -2
  84. package/dist/http/helpers/slice-run-projections.d.ts +27 -0
  85. package/dist/http/helpers/slice-run-projections.js +198 -10
  86. package/dist/http/helpers/triage-mapper.js +499 -6
  87. package/dist/http/helpers/value-utils.d.ts +1 -0
  88. package/dist/http/helpers/value-utils.js +17 -0
  89. package/dist/http/index.d.ts +1 -0
  90. package/dist/http/index.js +179 -46
  91. package/dist/http/router.js +64 -9
  92. package/dist/http/routes/live-legacy.d.ts +19 -2
  93. package/dist/http/routes/live-legacy.js +110 -27
  94. package/dist/http/routes/live-snapshot.d.ts +16 -2
  95. package/dist/http/routes/live-snapshot.js +169 -25
  96. package/dist/http/routes/live-triage.js +6 -1
  97. package/dist/http/routes/mission-control-actions.d.ts +9 -0
  98. package/dist/http/routes/mission-control-actions.js +185 -7
  99. package/dist/http/routes/mission-control-read.d.ts +13 -0
  100. package/dist/http/routes/mission-control-read.js +100 -219
  101. package/dist/http/routes/onboarding.d.ts +1 -0
  102. package/dist/http/routes/onboarding.js +17 -0
  103. package/dist/index.d.ts +5 -0
  104. package/dist/index.js +199 -123
  105. package/dist/outbox.d.ts +0 -2
  106. package/dist/outbox.js +259 -148
  107. package/dist/reporting/rollups.js +18 -11
  108. package/dist/runtime-instance-store.js +212 -58
  109. package/dist/stores/materialized-snapshot-store.d.ts +18 -0
  110. package/dist/stores/materialized-snapshot-store.js +91 -0
  111. package/dist/stores/sqlite-state.d.ts +6 -0
  112. package/dist/stores/sqlite-state.js +330 -0
  113. package/package.json +5 -1
  114. package/dashboard/dist/assets/B014hrCe.js.br +0 -0
  115. package/dashboard/dist/assets/B014hrCe.js.gz +0 -0
  116. package/dashboard/dist/assets/BCudUvwg.js +0 -1
  117. package/dashboard/dist/assets/BCudUvwg.js.br +0 -0
  118. package/dashboard/dist/assets/BCudUvwg.js.gz +0 -0
  119. package/dashboard/dist/assets/BGY6oI8h.js.br +0 -0
  120. package/dashboard/dist/assets/BGY6oI8h.js.gz +0 -0
  121. package/dashboard/dist/assets/BJI1Iy5v.css +0 -1
  122. package/dashboard/dist/assets/BJI1Iy5v.css.br +0 -0
  123. package/dashboard/dist/assets/BJI1Iy5v.css.gz +0 -0
  124. package/dashboard/dist/assets/BUvcp_7V.js +0 -1
  125. package/dashboard/dist/assets/BUvcp_7V.js.br +0 -0
  126. package/dashboard/dist/assets/BUvcp_7V.js.gz +0 -0
  127. package/dashboard/dist/assets/BV2Tf8S2.js +0 -212
  128. package/dashboard/dist/assets/BV2Tf8S2.js.br +0 -0
  129. package/dashboard/dist/assets/BV2Tf8S2.js.gz +0 -0
  130. package/dashboard/dist/assets/BYb6DARX.js.br +0 -0
  131. package/dashboard/dist/assets/BYb6DARX.js.gz +0 -0
  132. package/dashboard/dist/assets/BoDhb8_y.js.br +0 -0
  133. package/dashboard/dist/assets/BoDhb8_y.js.gz +0 -0
  134. package/dashboard/dist/assets/Bqk_l0k6.js +0 -1
  135. package/dashboard/dist/assets/Bqk_l0k6.js.br +0 -0
  136. package/dashboard/dist/assets/Bqk_l0k6.js.gz +0 -0
  137. package/dashboard/dist/assets/C-MOJWHs.js +0 -1
  138. package/dashboard/dist/assets/C-MOJWHs.js.br +0 -0
  139. package/dashboard/dist/assets/C-MOJWHs.js.gz +0 -0
  140. package/dashboard/dist/assets/CV0sWMbv.js.br +0 -0
  141. package/dashboard/dist/assets/CV0sWMbv.js.gz +0 -0
  142. package/dashboard/dist/assets/CaAkScfa.js +0 -1
  143. package/dashboard/dist/assets/CaAkScfa.js.br +0 -0
  144. package/dashboard/dist/assets/CaAkScfa.js.gz +0 -0
  145. package/dashboard/dist/assets/Ck5KlsPN.js +0 -1
  146. package/dashboard/dist/assets/Ck5KlsPN.js.br +0 -0
  147. package/dashboard/dist/assets/Ck5KlsPN.js.gz +0 -0
  148. package/dashboard/dist/assets/D2G51wQm.js +0 -1
  149. package/dashboard/dist/assets/D2G51wQm.js.br +0 -0
  150. package/dashboard/dist/assets/D2G51wQm.js.gz +0 -0
  151. package/dashboard/dist/assets/DAr4MfFk.js.br +0 -0
  152. package/dashboard/dist/assets/DAr4MfFk.js.gz +0 -0
  153. package/dashboard/dist/assets/DXVs61e1.js.br +0 -0
  154. package/dashboard/dist/assets/DXVs61e1.js.gz +0 -0
  155. package/dashboard/dist/assets/DibzNd0I.js.br +0 -0
  156. package/dashboard/dist/assets/DibzNd0I.js.gz +0 -0
  157. package/dashboard/dist/assets/Dm0CfDGr.js.br +0 -0
  158. package/dashboard/dist/assets/Dm0CfDGr.js.gz +0 -0
  159. package/dashboard/dist/assets/_zpQCpjm.js.br +0 -0
  160. package/dashboard/dist/assets/_zpQCpjm.js.gz +0 -0
  161. package/dashboard/dist/assets/uNGpYMSH.js +0 -1
  162. package/dashboard/dist/assets/uNGpYMSH.js.br +0 -0
  163. package/dashboard/dist/assets/uNGpYMSH.js.gz +0 -0
  164. package/dashboard/dist/assets/wa4jJQK9.js.br +0 -0
  165. 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,22 @@ 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 dispatchableTaskRecord = asRecord(record.dispatchableTask ?? record.dispatchable_task);
468
+ const dispatchableTaskId = asString(dispatchableTaskRecord?.id) ??
469
+ asString(record.dispatchableTaskId) ??
470
+ asString(record.dispatchable_task_id);
471
+ const dispatchableTaskTitle = asString(dispatchableTaskRecord?.title) ??
472
+ asString(record.dispatchableTaskTitle) ??
473
+ asString(record.dispatchable_task_title);
474
+ const dispatchableTaskScopeRaw = asString(dispatchableTaskRecord?.scope) ??
475
+ asString(record.dispatchableTaskScope) ??
476
+ asString(record.dispatchable_task_scope);
477
+ const dispatchableTaskScope = dispatchableTaskScopeRaw === "task" ||
478
+ dispatchableTaskScopeRaw === "milestone" ||
479
+ dispatchableTaskScopeRaw === "workstream"
480
+ ? dispatchableTaskScopeRaw
481
+ : null;
482
+ const normalizedSliceScope = normalizeMissionControlStatus(asString(record.sliceScope) ?? asString(record.slice_scope));
480
483
  const sliceScope = normalizedSliceScope === "task" ||
481
484
  normalizedSliceScope === "milestone" ||
482
485
  normalizedSliceScope === "workstream"
@@ -514,6 +517,24 @@ function normalizeQueueItems(input) {
514
517
  ? Math.max(0, Math.floor(sliceTaskCountRaw))
515
518
  : sliceTaskIds.length,
516
519
  sliceMilestoneId: asString(record.sliceMilestoneId) ?? asString(record.slice_milestone_id),
520
+ canStartNow: typeof record.canStartNow === "boolean"
521
+ ? record.canStartNow
522
+ : typeof record.can_start_now === "boolean"
523
+ ? record.can_start_now
524
+ : queueState === "queued" || queueState === "idle",
525
+ startReasonCode: asString(record.startReasonCode) ?? asString(record.start_reason_code),
526
+ startReasonLabel: asString(record.startReasonLabel) ?? asString(record.start_reason_label),
527
+ dispatchableTask: dispatchableTaskId && dispatchableTaskTitle && dispatchableTaskScope
528
+ ? {
529
+ id: dispatchableTaskId,
530
+ title: dispatchableTaskTitle,
531
+ scope: dispatchableTaskScope,
532
+ milestoneId: asString(dispatchableTaskRecord?.milestoneId) ??
533
+ asString(dispatchableTaskRecord?.milestone_id) ??
534
+ asString(record.dispatchableTaskMilestoneId) ??
535
+ asString(record.dispatchable_task_milestone_id),
536
+ }
537
+ : null,
517
538
  isPinned: Boolean(record.isPinned ?? record.is_pinned),
518
539
  pinnedRank: asNumber(record.pinnedRank ?? record.pinned_rank),
519
540
  compositeScore: asNumber(record.compositeScore ?? record.composite_score) ?? undefined,
@@ -561,6 +582,34 @@ function normalizeQueueItems(input) {
561
582
  return left.workstreamTitle.localeCompare(right.workstreamTitle);
562
583
  });
563
584
  }
585
+ function summarizeQueueItems(items) {
586
+ const stateCounts = {
587
+ queued: 0,
588
+ running: 0,
589
+ blocked: 0,
590
+ idle: 0,
591
+ completed: 0,
592
+ };
593
+ for (const item of items) {
594
+ stateCounts[item.queueState] += 1;
595
+ }
596
+ return {
597
+ visibleTotal: items.filter((item) => item.queueState !== "running" && item.queueState !== "completed").length,
598
+ stateCounts,
599
+ };
600
+ }
601
+ function dedupeQueueItemsByLineage(items) {
602
+ const seen = new Set();
603
+ const deduped = [];
604
+ for (const item of items) {
605
+ const key = `${item.initiativeId}:${item.workstreamId}`;
606
+ if (seen.has(key))
607
+ continue;
608
+ seen.add(key);
609
+ deduped.push(item);
610
+ }
611
+ return deduped;
612
+ }
564
613
  function isHighSeverityQueueItem(item) {
565
614
  if (item.scoringTier === "urgent")
566
615
  return true;
@@ -613,134 +662,6 @@ function applyQueueNoiseControls(items, options) {
613
662
  }
614
663
  return deduped;
615
664
  }
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
665
  async function loadInitiativeGraphIndex(deps, initiativeId) {
745
666
  const graphRaw = deps.applyLocalInitiativeOverrideToGraph(await deps.buildMissionControlGraph(initiativeId));
746
667
  const graph = asRecord(graphRaw);
@@ -1024,6 +945,35 @@ export function registerMissionControlReadRoutes(router, deps) {
1024
945
  limit: pageSize,
1025
946
  total: canonicalTotal,
1026
947
  });
948
+ let canonicalSummaryItems = canonicalItems;
949
+ const summaryPageSize = Math.max(pageSize, Math.min(canonicalTotal, 200));
950
+ if (canonicalTotal > canonicalItems.length) {
951
+ const summaryItems = [];
952
+ for (let summaryOffset = 0; summaryOffset < canonicalTotal; summaryOffset += summaryPageSize) {
953
+ const summaryParams = new URLSearchParams(params);
954
+ summaryParams.set("offset", String(summaryOffset));
955
+ summaryParams.set("limit", String(summaryPageSize));
956
+ const summaryPage = await requestCanonicalWithLegacyFallback(deps, {
957
+ timeoutMs: CANONICAL_NEXT_UP_TIMEOUT_MS,
958
+ label: "canonical next-up summary",
959
+ modernPath: `/api/client/mission-control/next-up?${summaryParams.toString()}`,
960
+ legacyPath: `/api/mission-control/next-up?${summaryParams.toString()}`,
961
+ });
962
+ const summaryRecord = asRecord(summaryPage);
963
+ if (!summaryRecord || !Array.isArray(summaryRecord.items)) {
964
+ throw new Error("invalid canonical next-up summary payload");
965
+ }
966
+ const normalizedSummaryItems = applyQueueNoiseControls(normalizeQueueItems(summaryRecord.items).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs });
967
+ summaryItems.push(...normalizedSummaryItems);
968
+ if (normalizedSummaryItems.length < summaryPageSize) {
969
+ break;
970
+ }
971
+ }
972
+ canonicalSummaryItems =
973
+ summaryItems.length > 0
974
+ ? dedupeQueueItemsByLineage(summaryItems)
975
+ : canonicalItems;
976
+ }
1027
977
  const shouldRepaginateCanonically = canonicalItems.length > pageSize ||
1028
978
  canonicalPagination.offset !== offset ||
1029
979
  canonicalPagination.limit !== pageSize;
@@ -1036,11 +986,13 @@ export function registerMissionControlReadRoutes(router, deps) {
1036
986
  })
1037
987
  : null;
1038
988
  const degraded = dedupeStrings(asStringArray(canonicalRecord.degraded));
989
+ const canonicalSummary = summarizeQueueItems(canonicalSummaryItems);
1039
990
  const responsePayload = {
1040
991
  ok: true,
1041
992
  generatedAt: asString(canonicalRecord.generatedAt) ?? new Date().toISOString(),
1042
993
  total: paged ? paged.filtered.length : canonicalPagination.total,
1043
994
  items: paged ? paged.paged : canonicalItems,
995
+ summary: canonicalSummary,
1044
996
  pagination: paged ? paged.pagination : canonicalPagination,
1045
997
  source: "canonical",
1046
998
  degraded,
@@ -1109,79 +1061,6 @@ export function registerMissionControlReadRoutes(router, deps) {
1109
1061
  return;
1110
1062
  }
1111
1063
  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
1064
  // Continue to local fallback.
1186
1065
  try {
1187
1066
  const queue = await deps.buildNextUpQueue({
@@ -1204,6 +1083,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1204
1083
  generatedAt: new Date().toISOString(),
1205
1084
  total: paged.filtered.length,
1206
1085
  items: paged.paged,
1086
+ summary: summarizeQueueItems(items),
1207
1087
  pagination: paged.pagination,
1208
1088
  source: "local_fallback",
1209
1089
  degraded,
@@ -1237,6 +1117,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1237
1117
  generatedAt: new Date().toISOString(),
1238
1118
  total: paged.filtered.length,
1239
1119
  items: paged.paged,
1120
+ summary: summarizeQueueItems(items),
1240
1121
  pagination: paged.pagination,
1241
1122
  source: "local",
1242
1123
  degraded: dedupeStrings(degraded),
@@ -1608,7 +1489,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1608
1489
  const taskBuckets = new Map();
1609
1490
  for (const taskId of selectedTaskIds) {
1610
1491
  const task = graphIndex?.tasksById.get(taskId) ?? null;
1611
- if (!includeCompleted && isDoneStatus(task?.status ?? null))
1492
+ if (!includeCompleted && isDoneStatus(task?.status ?? ""))
1612
1493
  continue;
1613
1494
  const milestoneId = task?.milestoneId ??
1614
1495
  item.sliceMilestoneId ??
@@ -1687,7 +1568,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1687
1568
  ]);
1688
1569
  for (const taskId of selectedTaskIds) {
1689
1570
  const task = graphIndex?.tasksById.get(taskId) ?? null;
1690
- if (!includeCompleted && isDoneStatus(task?.status ?? null))
1571
+ if (!includeCompleted && isDoneStatus(task?.status ?? ""))
1691
1572
  continue;
1692
1573
  const taskTitle = task?.title ??
1693
1574
  (taskId === item.nextTaskId ? item.nextTaskTitle : null) ??
@@ -1708,7 +1589,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1708
1589
  : null,
1709
1590
  taskId,
1710
1591
  taskTitle,
1711
- queueState: isDoneStatus(task?.status ?? null) ? "completed" : item.queueState,
1592
+ queueState: isDoneStatus(task?.status ?? "") ? "completed" : item.queueState,
1712
1593
  sourceWorkstreamIds: [item.workstreamId],
1713
1594
  runnerAgentId: (item.runnerAgents ?? [])[0]?.id ?? item.runnerAgentId ?? null,
1714
1595
  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
  };