@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.
- package/dashboard/dist/assets/B6VftyY6.js +1 -0
- package/dashboard/dist/assets/B6VftyY6.js.br +0 -0
- package/dashboard/dist/assets/B6VftyY6.js.gz +0 -0
- package/dashboard/dist/assets/{Dm0CfDGr.js → BANQdlC4.js} +1 -1
- package/dashboard/dist/assets/BANQdlC4.js.br +0 -0
- package/dashboard/dist/assets/BANQdlC4.js.gz +0 -0
- package/dashboard/dist/assets/{_zpQCpjm.js → BPL4CL3c.js} +1 -1
- package/dashboard/dist/assets/BPL4CL3c.js.br +0 -0
- package/dashboard/dist/assets/BPL4CL3c.js.gz +0 -0
- package/dashboard/dist/assets/{DXVs61e1.js → BZCkOZ20.js} +1 -1
- package/dashboard/dist/assets/BZCkOZ20.js.br +0 -0
- package/dashboard/dist/assets/BZCkOZ20.js.gz +0 -0
- package/dashboard/dist/assets/{BYb6DARX.js → B_LdOJUa.js} +1 -1
- package/dashboard/dist/assets/B_LdOJUa.js.br +0 -0
- package/dashboard/dist/assets/B_LdOJUa.js.gz +0 -0
- package/dashboard/dist/assets/Bfp-wdwb.css +1 -0
- package/dashboard/dist/assets/Bfp-wdwb.css.br +0 -0
- package/dashboard/dist/assets/Bfp-wdwb.css.gz +0 -0
- package/dashboard/dist/assets/{DibzNd0I.js → BvFcH_Iy.js} +1 -1
- package/dashboard/dist/assets/BvFcH_Iy.js.br +0 -0
- package/dashboard/dist/assets/BvFcH_Iy.js.gz +0 -0
- package/dashboard/dist/assets/By0MIBj_.js +1 -0
- package/dashboard/dist/assets/By0MIBj_.js.br +0 -0
- package/dashboard/dist/assets/By0MIBj_.js.gz +0 -0
- package/dashboard/dist/assets/C0i7ABUU.js +212 -0
- package/dashboard/dist/assets/C0i7ABUU.js.br +0 -0
- package/dashboard/dist/assets/C0i7ABUU.js.gz +0 -0
- package/dashboard/dist/assets/CFB0MM7j.js +1 -0
- package/dashboard/dist/assets/CFB0MM7j.js.br +0 -0
- package/dashboard/dist/assets/CFB0MM7j.js.gz +0 -0
- package/dashboard/dist/assets/CQSRb1yu.js +1 -0
- package/dashboard/dist/assets/CQSRb1yu.js.br +0 -0
- package/dashboard/dist/assets/CQSRb1yu.js.gz +0 -0
- package/dashboard/dist/assets/{wa4jJQK9.js → CUoQoSm-.js} +1 -1
- package/dashboard/dist/assets/CUoQoSm-.js.br +0 -0
- package/dashboard/dist/assets/CUoQoSm-.js.gz +0 -0
- package/dashboard/dist/assets/Ckd1R1iE.js +1 -0
- package/dashboard/dist/assets/Ckd1R1iE.js.br +0 -0
- package/dashboard/dist/assets/Ckd1R1iE.js.gz +0 -0
- package/dashboard/dist/assets/{BGY6oI8h.js → CqRNb2EL.js} +1 -1
- package/dashboard/dist/assets/CqRNb2EL.js.br +0 -0
- package/dashboard/dist/assets/CqRNb2EL.js.gz +0 -0
- package/dashboard/dist/assets/{DAr4MfFk.js → DClUc9rw.js} +1 -1
- package/dashboard/dist/assets/DClUc9rw.js.br +0 -0
- package/dashboard/dist/assets/DClUc9rw.js.gz +0 -0
- package/dashboard/dist/assets/DF2PMTwT.js +1 -0
- package/dashboard/dist/assets/DF2PMTwT.js.br +0 -0
- package/dashboard/dist/assets/DF2PMTwT.js.gz +0 -0
- package/dashboard/dist/assets/{B014hrCe.js → DJYl7gyA.js} +2 -2
- package/dashboard/dist/assets/DJYl7gyA.js.br +0 -0
- package/dashboard/dist/assets/DJYl7gyA.js.gz +0 -0
- package/dashboard/dist/assets/{BoDhb8_y.js → DZtNMX0t.js} +2 -2
- package/dashboard/dist/assets/DZtNMX0t.js.br +0 -0
- package/dashboard/dist/assets/DZtNMX0t.js.gz +0 -0
- package/dashboard/dist/assets/DlEa8PI0.js +1 -0
- package/dashboard/dist/assets/DlEa8PI0.js.br +0 -0
- package/dashboard/dist/assets/DlEa8PI0.js.gz +0 -0
- package/dashboard/dist/assets/M4QxcXjh.js +1 -0
- package/dashboard/dist/assets/M4QxcXjh.js.br +0 -0
- package/dashboard/dist/assets/M4QxcXjh.js.gz +0 -0
- package/dashboard/dist/assets/{CV0sWMbv.js → MrW1ixGx.js} +1 -1
- package/dashboard/dist/assets/MrW1ixGx.js.br +0 -0
- package/dashboard/dist/assets/MrW1ixGx.js.gz +0 -0
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist/index.html.br +0 -0
- package/dashboard/dist/index.html.gz +0 -0
- package/dist/activity-store.js +68 -8
- package/dist/agent-run-store.js +162 -24
- package/dist/cli/orgx.d.ts +3 -0
- package/dist/config/resolution.d.ts +7 -0
- package/dist/config/resolution.js +13 -5
- package/dist/contracts/onboarding-state.d.ts +2 -0
- package/dist/contracts/onboarding-state.js +23 -0
- package/dist/contracts/shared-types.d.ts +45 -0
- package/dist/http/helpers/auto-continue-engine.d.ts +23 -0
- package/dist/http/helpers/auto-continue-engine.js +468 -85
- package/dist/http/helpers/autopilot-runtime.js +5 -1
- package/dist/http/helpers/autopilot-slice-utils.js +25 -1
- package/dist/http/helpers/decision-mapper.d.ts +1 -0
- package/dist/http/helpers/decision-mapper.js +19 -2
- package/dist/http/helpers/dispatch-lifecycle.js +3 -0
- package/dist/http/helpers/mission-control.d.ts +1 -0
- package/dist/http/helpers/mission-control.js +5 -2
- package/dist/http/helpers/slice-run-projections.d.ts +27 -0
- package/dist/http/helpers/slice-run-projections.js +198 -10
- package/dist/http/helpers/triage-mapper.js +499 -6
- package/dist/http/helpers/value-utils.d.ts +1 -0
- package/dist/http/helpers/value-utils.js +17 -0
- package/dist/http/index.d.ts +1 -0
- package/dist/http/index.js +179 -46
- package/dist/http/router.js +64 -9
- package/dist/http/routes/live-legacy.d.ts +19 -2
- package/dist/http/routes/live-legacy.js +110 -27
- package/dist/http/routes/live-snapshot.d.ts +16 -2
- package/dist/http/routes/live-snapshot.js +169 -25
- package/dist/http/routes/live-triage.js +6 -1
- package/dist/http/routes/mission-control-actions.d.ts +9 -0
- package/dist/http/routes/mission-control-actions.js +185 -7
- package/dist/http/routes/mission-control-read.d.ts +13 -0
- package/dist/http/routes/mission-control-read.js +100 -219
- package/dist/http/routes/onboarding.d.ts +1 -0
- package/dist/http/routes/onboarding.js +17 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +199 -123
- package/dist/outbox.d.ts +0 -2
- package/dist/outbox.js +259 -148
- package/dist/reporting/rollups.js +18 -11
- package/dist/runtime-instance-store.js +212 -58
- package/dist/stores/materialized-snapshot-store.d.ts +18 -0
- package/dist/stores/materialized-snapshot-store.js +91 -0
- package/dist/stores/sqlite-state.d.ts +6 -0
- package/dist/stores/sqlite-state.js +330 -0
- package/package.json +5 -1
- package/dashboard/dist/assets/B014hrCe.js.br +0 -0
- package/dashboard/dist/assets/B014hrCe.js.gz +0 -0
- package/dashboard/dist/assets/BCudUvwg.js +0 -1
- package/dashboard/dist/assets/BCudUvwg.js.br +0 -0
- package/dashboard/dist/assets/BCudUvwg.js.gz +0 -0
- package/dashboard/dist/assets/BGY6oI8h.js.br +0 -0
- package/dashboard/dist/assets/BGY6oI8h.js.gz +0 -0
- package/dashboard/dist/assets/BJI1Iy5v.css +0 -1
- package/dashboard/dist/assets/BJI1Iy5v.css.br +0 -0
- package/dashboard/dist/assets/BJI1Iy5v.css.gz +0 -0
- package/dashboard/dist/assets/BUvcp_7V.js +0 -1
- package/dashboard/dist/assets/BUvcp_7V.js.br +0 -0
- package/dashboard/dist/assets/BUvcp_7V.js.gz +0 -0
- package/dashboard/dist/assets/BV2Tf8S2.js +0 -212
- package/dashboard/dist/assets/BV2Tf8S2.js.br +0 -0
- package/dashboard/dist/assets/BV2Tf8S2.js.gz +0 -0
- package/dashboard/dist/assets/BYb6DARX.js.br +0 -0
- package/dashboard/dist/assets/BYb6DARX.js.gz +0 -0
- package/dashboard/dist/assets/BoDhb8_y.js.br +0 -0
- package/dashboard/dist/assets/BoDhb8_y.js.gz +0 -0
- package/dashboard/dist/assets/Bqk_l0k6.js +0 -1
- package/dashboard/dist/assets/Bqk_l0k6.js.br +0 -0
- package/dashboard/dist/assets/Bqk_l0k6.js.gz +0 -0
- package/dashboard/dist/assets/C-MOJWHs.js +0 -1
- package/dashboard/dist/assets/C-MOJWHs.js.br +0 -0
- package/dashboard/dist/assets/C-MOJWHs.js.gz +0 -0
- package/dashboard/dist/assets/CV0sWMbv.js.br +0 -0
- package/dashboard/dist/assets/CV0sWMbv.js.gz +0 -0
- package/dashboard/dist/assets/CaAkScfa.js +0 -1
- package/dashboard/dist/assets/CaAkScfa.js.br +0 -0
- package/dashboard/dist/assets/CaAkScfa.js.gz +0 -0
- package/dashboard/dist/assets/Ck5KlsPN.js +0 -1
- package/dashboard/dist/assets/Ck5KlsPN.js.br +0 -0
- package/dashboard/dist/assets/Ck5KlsPN.js.gz +0 -0
- package/dashboard/dist/assets/D2G51wQm.js +0 -1
- package/dashboard/dist/assets/D2G51wQm.js.br +0 -0
- package/dashboard/dist/assets/D2G51wQm.js.gz +0 -0
- package/dashboard/dist/assets/DAr4MfFk.js.br +0 -0
- package/dashboard/dist/assets/DAr4MfFk.js.gz +0 -0
- package/dashboard/dist/assets/DXVs61e1.js.br +0 -0
- package/dashboard/dist/assets/DXVs61e1.js.gz +0 -0
- package/dashboard/dist/assets/DibzNd0I.js.br +0 -0
- package/dashboard/dist/assets/DibzNd0I.js.gz +0 -0
- package/dashboard/dist/assets/Dm0CfDGr.js.br +0 -0
- package/dashboard/dist/assets/Dm0CfDGr.js.gz +0 -0
- package/dashboard/dist/assets/_zpQCpjm.js.br +0 -0
- package/dashboard/dist/assets/_zpQCpjm.js.gz +0 -0
- package/dashboard/dist/assets/uNGpYMSH.js +0 -1
- package/dashboard/dist/assets/uNGpYMSH.js.br +0 -0
- package/dashboard/dist/assets/uNGpYMSH.js.gz +0 -0
- package/dashboard/dist/assets/wa4jJQK9.js.br +0 -0
- 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 =
|
|
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
|
|
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 ??
|
|
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 ??
|
|
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 ??
|
|
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();
|