@useorgx/openclaw-plugin 0.7.17 → 0.7.20
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/{Crj3jKHE.js → B014hrCe.js} +1 -1
- package/dashboard/dist/assets/B014hrCe.js.br +0 -0
- package/dashboard/dist/assets/B014hrCe.js.gz +0 -0
- package/dashboard/dist/assets/{DBRLnKWw.js → BGY6oI8h.js} +1 -1
- package/dashboard/dist/assets/BGY6oI8h.js.br +0 -0
- package/dashboard/dist/assets/BGY6oI8h.js.gz +0 -0
- package/dashboard/dist/assets/BJI1Iy5v.css +1 -0
- 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 +1 -0
- 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 +212 -0
- package/dashboard/dist/assets/BV2Tf8S2.js.br +0 -0
- package/dashboard/dist/assets/BV2Tf8S2.js.gz +0 -0
- package/dashboard/dist/assets/{CoDun8X6.js → BYb6DARX.js} +1 -1
- package/dashboard/dist/assets/BYb6DARX.js.br +0 -0
- package/dashboard/dist/assets/BYb6DARX.js.gz +0 -0
- package/dashboard/dist/assets/{DLNTxNX-.js → BoDhb8_y.js} +1 -1
- 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 +1 -0
- package/dashboard/dist/assets/Bqk_l0k6.js.br +0 -0
- package/dashboard/dist/assets/Bqk_l0k6.js.gz +0 -0
- package/dashboard/dist/assets/{BDlKSbsp.js → CV0sWMbv.js} +1 -1
- package/dashboard/dist/assets/CV0sWMbv.js.br +0 -0
- package/dashboard/dist/assets/CV0sWMbv.js.gz +0 -0
- package/dashboard/dist/assets/CaAkScfa.js +1 -0
- package/dashboard/dist/assets/CaAkScfa.js.br +0 -0
- package/dashboard/dist/assets/CaAkScfa.js.gz +0 -0
- package/dashboard/dist/assets/{CyUpNSKv.js → Ck5KlsPN.js} +1 -1
- package/dashboard/dist/assets/Ck5KlsPN.js.br +0 -0
- package/dashboard/dist/assets/Ck5KlsPN.js.gz +0 -0
- package/dashboard/dist/assets/{CMir7ekf.js → D2G51wQm.js} +1 -1
- package/dashboard/dist/assets/D2G51wQm.js.br +0 -0
- package/dashboard/dist/assets/D2G51wQm.js.gz +0 -0
- package/dashboard/dist/assets/{D8mvKY2h.js → DAr4MfFk.js} +1 -1
- package/dashboard/dist/assets/DAr4MfFk.js.br +0 -0
- package/dashboard/dist/assets/DAr4MfFk.js.gz +0 -0
- package/dashboard/dist/assets/{DvFumX8R.js → DXVs61e1.js} +1 -1
- package/dashboard/dist/assets/DXVs61e1.js.br +0 -0
- package/dashboard/dist/assets/DXVs61e1.js.gz +0 -0
- package/dashboard/dist/assets/{CWXk6UZl.js → DibzNd0I.js} +1 -1
- package/dashboard/dist/assets/DibzNd0I.js.br +0 -0
- package/dashboard/dist/assets/DibzNd0I.js.gz +0 -0
- package/dashboard/dist/assets/{DdYkuATV.js → Dm0CfDGr.js} +1 -1
- package/dashboard/dist/assets/Dm0CfDGr.js.br +0 -0
- package/dashboard/dist/assets/Dm0CfDGr.js.gz +0 -0
- package/dashboard/dist/assets/_zpQCpjm.js +1 -0
- package/dashboard/dist/assets/_zpQCpjm.js.br +0 -0
- package/dashboard/dist/assets/_zpQCpjm.js.gz +0 -0
- package/dashboard/dist/assets/{B8NuBCcY.js → uNGpYMSH.js} +1 -1
- package/dashboard/dist/assets/uNGpYMSH.js.br +0 -0
- package/dashboard/dist/assets/uNGpYMSH.js.gz +0 -0
- package/dashboard/dist/assets/{B7kFLPiD.js → wa4jJQK9.js} +1 -1
- package/dashboard/dist/assets/wa4jJQK9.js.br +0 -0
- package/dashboard/dist/assets/wa4jJQK9.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/http/helpers/auto-continue-engine.d.ts +39 -0
- package/dist/http/helpers/auto-continue-engine.js +96 -0
- package/dist/http/index.js +2 -1
- package/dist/http/routes/mission-control-read.d.ts +14 -0
- package/dist/http/routes/mission-control-read.js +69 -5
- package/dist/outbox.js +9 -2
- package/package.json +2 -1
- package/dashboard/dist/assets/05zHA1Am.js +0 -1
- package/dashboard/dist/assets/05zHA1Am.js.br +0 -0
- package/dashboard/dist/assets/05zHA1Am.js.gz +0 -0
- package/dashboard/dist/assets/0uYJrBLl.js +0 -1
- package/dashboard/dist/assets/0uYJrBLl.js.br +0 -0
- package/dashboard/dist/assets/0uYJrBLl.js.gz +0 -0
- package/dashboard/dist/assets/8nr6IqT4.js +0 -1
- package/dashboard/dist/assets/8nr6IqT4.js.br +0 -0
- package/dashboard/dist/assets/8nr6IqT4.js.gz +0 -0
- package/dashboard/dist/assets/B7kFLPiD.js.br +0 -0
- package/dashboard/dist/assets/B7kFLPiD.js.gz +0 -0
- package/dashboard/dist/assets/B8NuBCcY.js.br +0 -0
- package/dashboard/dist/assets/B8NuBCcY.js.gz +0 -0
- package/dashboard/dist/assets/BDlKSbsp.js.br +0 -0
- package/dashboard/dist/assets/BDlKSbsp.js.gz +0 -0
- package/dashboard/dist/assets/C8AYbjlq.js +0 -212
- package/dashboard/dist/assets/C8AYbjlq.js.br +0 -0
- package/dashboard/dist/assets/C8AYbjlq.js.gz +0 -0
- package/dashboard/dist/assets/CMir7ekf.js.br +0 -0
- package/dashboard/dist/assets/CMir7ekf.js.gz +0 -0
- package/dashboard/dist/assets/CWXk6UZl.js.br +0 -0
- package/dashboard/dist/assets/CWXk6UZl.js.gz +0 -0
- package/dashboard/dist/assets/CoDun8X6.js.br +0 -0
- package/dashboard/dist/assets/CoDun8X6.js.gz +0 -0
- package/dashboard/dist/assets/Crj3jKHE.js.br +0 -0
- package/dashboard/dist/assets/Crj3jKHE.js.gz +0 -0
- package/dashboard/dist/assets/CyUpNSKv.js.br +0 -0
- package/dashboard/dist/assets/CyUpNSKv.js.gz +0 -0
- package/dashboard/dist/assets/D8mvKY2h.js.br +0 -0
- package/dashboard/dist/assets/D8mvKY2h.js.gz +0 -0
- package/dashboard/dist/assets/DBRLnKWw.js.br +0 -0
- package/dashboard/dist/assets/DBRLnKWw.js.gz +0 -0
- package/dashboard/dist/assets/DBct8HLW.js +0 -1
- package/dashboard/dist/assets/DBct8HLW.js.br +0 -0
- package/dashboard/dist/assets/DBct8HLW.js.gz +0 -0
- package/dashboard/dist/assets/DLNTxNX-.js.br +0 -0
- package/dashboard/dist/assets/DLNTxNX-.js.gz +0 -0
- package/dashboard/dist/assets/DdYkuATV.js.br +0 -0
- package/dashboard/dist/assets/DdYkuATV.js.gz +0 -0
- package/dashboard/dist/assets/DvFumX8R.js.br +0 -0
- package/dashboard/dist/assets/DvFumX8R.js.gz +0 -0
- package/dashboard/dist/assets/RZkbqlJk.css +0 -1
- package/dashboard/dist/assets/RZkbqlJk.css.br +0 -0
- package/dashboard/dist/assets/RZkbqlJk.css.gz +0 -0
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<meta name="googlebot" content="noindex, nofollow, noarchive, nosnippet, noimageindex" />
|
|
11
11
|
<meta name="copyright" content="OrgX. All rights reserved." />
|
|
12
12
|
<title>OrgX Live Dashboard</title>
|
|
13
|
-
<script type="module" crossorigin src="/orgx/live/assets/
|
|
13
|
+
<script type="module" crossorigin src="/orgx/live/assets/BV2Tf8S2.js"></script>
|
|
14
14
|
<link rel="modulepreload" crossorigin href="/orgx/live/assets/Dj2k1r16.js">
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/orgx/live/assets/DMKyYAtD.js">
|
|
16
16
|
<link rel="modulepreload" crossorigin href="/orgx/live/assets/eeHXe_OQ.js">
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<link rel="modulepreload" crossorigin href="/orgx/live/assets/BjK42gtU.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="/orgx/live/assets/BV0BcV1u.js">
|
|
20
20
|
<link rel="stylesheet" crossorigin href="/orgx/live/assets/qm8xLgv-.css">
|
|
21
|
-
<link rel="stylesheet" crossorigin href="/orgx/live/assets/
|
|
21
|
+
<link rel="stylesheet" crossorigin href="/orgx/live/assets/BJI1Iy5v.css">
|
|
22
22
|
</head>
|
|
23
23
|
<body class="bg-[#080808] text-white antialiased">
|
|
24
24
|
<div id="root"></div>
|
|
Binary file
|
|
Binary file
|
|
@@ -485,6 +485,45 @@ export declare function createAutoContinueEngine(deps: CreateAutoContinueEngineD
|
|
|
485
485
|
activeRunId: string | null;
|
|
486
486
|
activeTaskTokenEstimate: number | null;
|
|
487
487
|
}>;
|
|
488
|
+
restoreAutoContinueRun: (initiativeId: string) => Promise<{
|
|
489
|
+
initiativeId: string;
|
|
490
|
+
agentId: string;
|
|
491
|
+
agentName: string | null;
|
|
492
|
+
includeVerification: boolean;
|
|
493
|
+
allowedWorkstreamIds: string[] | null;
|
|
494
|
+
stopAfterSlice: boolean;
|
|
495
|
+
ignoreSpawnGuardRateLimit: boolean;
|
|
496
|
+
maxParallelSlices: number;
|
|
497
|
+
parallelMode: "iwmt";
|
|
498
|
+
scope: SliceScope;
|
|
499
|
+
tokenBudget: number | null;
|
|
500
|
+
tokensUsed: number;
|
|
501
|
+
status: "stopped" | "running" | "stopping";
|
|
502
|
+
stopReason: ("error" | "blocked" | "completed" | "stopped" | "budget_exhausted") | null;
|
|
503
|
+
stopRequested: boolean;
|
|
504
|
+
startedAt: string;
|
|
505
|
+
stoppedAt: string | null;
|
|
506
|
+
updatedAt: string;
|
|
507
|
+
lastError: string | null;
|
|
508
|
+
lastTaskId: string | null;
|
|
509
|
+
lastRunId: string | null;
|
|
510
|
+
activeSliceRunIds: string[];
|
|
511
|
+
activeTaskIds: string[];
|
|
512
|
+
laneByWorkstreamId: Record<string, {
|
|
513
|
+
workstreamId: string;
|
|
514
|
+
state: "idle" | "blocked" | "completed" | "running" | "rate_limited" | "waiting_dependency";
|
|
515
|
+
activeRunId: string | null;
|
|
516
|
+
activeTaskIds: string[];
|
|
517
|
+
blockedReason: string | null;
|
|
518
|
+
waitingOnWorkstreamIds: string[];
|
|
519
|
+
retryAt: string | null;
|
|
520
|
+
updatedAt: string;
|
|
521
|
+
}>;
|
|
522
|
+
blockedWorkstreamIds: string[];
|
|
523
|
+
activeTaskId: string | null;
|
|
524
|
+
activeRunId: string | null;
|
|
525
|
+
activeTaskTokenEstimate: number | null;
|
|
526
|
+
} | null>;
|
|
488
527
|
skipCurrentWorkstream: (initiativeId: string, workstreamId: string, reason?: string) => Promise<{
|
|
489
528
|
ok: boolean;
|
|
490
529
|
skippedWorkstreamId: string;
|
|
@@ -733,6 +733,101 @@ export function createAutoContinueEngine(deps) {
|
|
|
733
733
|
};
|
|
734
734
|
const __filename = deps.filename;
|
|
735
735
|
const autoContinueRuns = new Map();
|
|
736
|
+
/**
|
|
737
|
+
* Rehydrate an AutoContinueRun from persisted initiative metadata.
|
|
738
|
+
* Called when the in-memory Map is empty (e.g. after server restart) to
|
|
739
|
+
* restore the last-known autopilot state so the dashboard toggle stays
|
|
740
|
+
* accurate.
|
|
741
|
+
*/
|
|
742
|
+
async function restoreAutoContinueRun(initiativeId) {
|
|
743
|
+
// Already in memory — nothing to restore.
|
|
744
|
+
if (autoContinueRuns.has(initiativeId)) {
|
|
745
|
+
return autoContinueRuns.get(initiativeId) ?? null;
|
|
746
|
+
}
|
|
747
|
+
try {
|
|
748
|
+
const entity = await fetchInitiativeEntity(initiativeId);
|
|
749
|
+
if (!entity)
|
|
750
|
+
return null;
|
|
751
|
+
const meta = entity && typeof entity === "object"
|
|
752
|
+
? entity.metadata ?? {}
|
|
753
|
+
: {};
|
|
754
|
+
const enabled = meta.auto_continue_enabled;
|
|
755
|
+
const status = meta.auto_continue_status;
|
|
756
|
+
if (!enabled || !status)
|
|
757
|
+
return null;
|
|
758
|
+
// Reconstruct lane objects from persisted array.
|
|
759
|
+
const rawLanes = Array.isArray(meta.auto_continue_lane_states)
|
|
760
|
+
? meta.auto_continue_lane_states
|
|
761
|
+
: [];
|
|
762
|
+
const laneByWorkstreamId = {};
|
|
763
|
+
for (const raw of rawLanes) {
|
|
764
|
+
const wsId = String(raw.workstream_id ?? "").trim();
|
|
765
|
+
if (!wsId)
|
|
766
|
+
continue;
|
|
767
|
+
laneByWorkstreamId[wsId] = {
|
|
768
|
+
workstreamId: wsId,
|
|
769
|
+
state: raw.state ?? LaneState.IDLE,
|
|
770
|
+
activeRunId: raw.active_run_id ?? null,
|
|
771
|
+
activeTaskIds: Array.isArray(raw.active_task_ids) ? raw.active_task_ids : [],
|
|
772
|
+
blockedReason: raw.blocked_reason ?? null,
|
|
773
|
+
waitingOnWorkstreamIds: Array.isArray(raw.waiting_on_workstream_ids)
|
|
774
|
+
? raw.waiting_on_workstream_ids
|
|
775
|
+
: [],
|
|
776
|
+
retryAt: raw.retry_at ?? null,
|
|
777
|
+
updatedAt: raw.updated_at ?? new Date().toISOString(),
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
const now = new Date().toISOString();
|
|
781
|
+
const run = {
|
|
782
|
+
initiativeId,
|
|
783
|
+
agentId: "",
|
|
784
|
+
agentName: null,
|
|
785
|
+
includeVerification: Boolean(meta.auto_continue_include_verification),
|
|
786
|
+
allowedWorkstreamIds: Array.isArray(meta.auto_continue_workstream_filter)
|
|
787
|
+
? meta.auto_continue_workstream_filter
|
|
788
|
+
: null,
|
|
789
|
+
stopAfterSlice: false,
|
|
790
|
+
ignoreSpawnGuardRateLimit: Boolean(meta.auto_continue_ignore_spawn_guard_rate_limit),
|
|
791
|
+
maxParallelSlices: normalizeMaxParallelSlices(meta.auto_continue_max_parallel, AUTO_CONTINUE_MAX_PARALLEL_DEFAULT),
|
|
792
|
+
parallelMode: normalizeParallelMode(meta.auto_continue_parallel_mode),
|
|
793
|
+
scope: "task",
|
|
794
|
+
tokenBudget: normalizeTokenBudget(meta.auto_continue_token_budget, defaultAutoContinueTokenBudget()),
|
|
795
|
+
tokensUsed: typeof meta.auto_continue_tokens_used === "number" ? meta.auto_continue_tokens_used : 0,
|
|
796
|
+
status: status,
|
|
797
|
+
stopReason: meta.auto_continue_stop_reason ?? null,
|
|
798
|
+
stopRequested: false,
|
|
799
|
+
startedAt: meta.auto_continue_started_at ?? now,
|
|
800
|
+
stoppedAt: meta.auto_continue_stopped_at ?? null,
|
|
801
|
+
updatedAt: meta.auto_continue_updated_at ?? now,
|
|
802
|
+
lastError: meta.auto_continue_last_error ?? null,
|
|
803
|
+
lastTaskId: meta.auto_continue_last_task_id ?? null,
|
|
804
|
+
lastRunId: meta.auto_continue_last_run_id ?? null,
|
|
805
|
+
activeSliceRunIds: Array.isArray(meta.auto_continue_active_run_ids)
|
|
806
|
+
? meta.auto_continue_active_run_ids
|
|
807
|
+
: [],
|
|
808
|
+
activeTaskIds: Array.isArray(meta.auto_continue_active_task_ids)
|
|
809
|
+
? meta.auto_continue_active_task_ids
|
|
810
|
+
: [],
|
|
811
|
+
laneByWorkstreamId,
|
|
812
|
+
blockedWorkstreamIds: Array.isArray(meta.auto_continue_blocked_workstream_ids)
|
|
813
|
+
? meta.auto_continue_blocked_workstream_ids
|
|
814
|
+
: [],
|
|
815
|
+
activeTaskId: meta.auto_continue_active_task_id ?? null,
|
|
816
|
+
activeRunId: meta.auto_continue_active_run_id ?? null,
|
|
817
|
+
activeTaskTokenEstimate: typeof meta.auto_continue_active_task_token_estimate === "number"
|
|
818
|
+
? meta.auto_continue_active_task_token_estimate
|
|
819
|
+
: null,
|
|
820
|
+
};
|
|
821
|
+
ensureRunInternals(run);
|
|
822
|
+
syncLegacyRunPointers(run);
|
|
823
|
+
// Insert into in-memory map so subsequent lookups are fast.
|
|
824
|
+
autoContinueRuns.set(initiativeId, run);
|
|
825
|
+
return run;
|
|
826
|
+
}
|
|
827
|
+
catch {
|
|
828
|
+
return null;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
736
831
|
const localInitiativeStatusOverrides = new Map();
|
|
737
832
|
const localTaskStatusOverrides = new Map();
|
|
738
833
|
const localMilestoneStatusOverrides = new Map();
|
|
@@ -4470,6 +4565,7 @@ export function createAutoContinueEngine(deps) {
|
|
|
4470
4565
|
getAutoContinueLaneForWorkstream,
|
|
4471
4566
|
scheduleAutoFixForWorkstream,
|
|
4472
4567
|
startAutoContinueRun,
|
|
4568
|
+
restoreAutoContinueRun,
|
|
4473
4569
|
skipCurrentWorkstream,
|
|
4474
4570
|
getCanonicalAutopilotState,
|
|
4475
4571
|
// Session store (for resume support)
|
package/dist/http/index.js
CHANGED
|
@@ -1846,7 +1846,7 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
1846
1846
|
};
|
|
1847
1847
|
const codexBinResolver = createCodexBinResolver();
|
|
1848
1848
|
const resolveCodexBinInfo = () => codexBinResolver.resolveCodexBinInfo();
|
|
1849
|
-
const { autoContinueRuns, autoContinueSliceRuns, localInitiativeStatusOverrides, writeRuntimeEvent, autoContinueTickMs: AUTO_CONTINUE_TICK_MS, defaultAutoContinueTokenBudget, defaultAutoContinueMaxParallelSlices, setLocalInitiativeStatusOverride, clearLocalInitiativeStatusOverride, applyLocalInitiativeOverrides, applyLocalInitiativeOverrideToGraph, updateInitiativeAutoContinueState, stopAutoContinueRun, tickAutoContinueRun, tickAllAutoContinue, isInitiativeActiveStatus, runningAutoContinueForWorkstream, getAutoContinueLaneForWorkstream, scheduleAutoFixForWorkstream, startAutoContinueRun, skipCurrentWorkstream, getCanonicalAutopilotState, } = createAutoContinueEngine({
|
|
1849
|
+
const { autoContinueRuns, autoContinueSliceRuns, localInitiativeStatusOverrides, writeRuntimeEvent, autoContinueTickMs: AUTO_CONTINUE_TICK_MS, defaultAutoContinueTokenBudget, defaultAutoContinueMaxParallelSlices, setLocalInitiativeStatusOverride, clearLocalInitiativeStatusOverride, applyLocalInitiativeOverrides, applyLocalInitiativeOverrideToGraph, updateInitiativeAutoContinueState, stopAutoContinueRun, tickAutoContinueRun, tickAllAutoContinue, isInitiativeActiveStatus, runningAutoContinueForWorkstream, getAutoContinueLaneForWorkstream, scheduleAutoFixForWorkstream, startAutoContinueRun, restoreAutoContinueRun, skipCurrentWorkstream, getCanonicalAutopilotState, } = createAutoContinueEngine({
|
|
1850
1850
|
client,
|
|
1851
1851
|
filename: __filename,
|
|
1852
1852
|
safeErrorMessage,
|
|
@@ -3042,6 +3042,7 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
3042
3042
|
});
|
|
3043
3043
|
registerMissionControlReadRoutes(apiRouter, {
|
|
3044
3044
|
autoContinueRuns,
|
|
3045
|
+
restoreAutoContinueRun,
|
|
3045
3046
|
defaultAutoContinueTokenBudget,
|
|
3046
3047
|
defaultAutoContinueMaxParallelSlices,
|
|
3047
3048
|
autoContinueTickMs: AUTO_CONTINUE_TICK_MS,
|
|
@@ -38,6 +38,7 @@ type NextUpQueueItem = {
|
|
|
38
38
|
sliceTaskIds?: string[];
|
|
39
39
|
sliceTaskCount?: number | null;
|
|
40
40
|
sliceMilestoneId?: string | null;
|
|
41
|
+
milestoneBreakdown?: MilestoneBreakdownEntry[];
|
|
41
42
|
isPinned?: boolean;
|
|
42
43
|
pinnedRank?: number | null;
|
|
43
44
|
compositeScore?: number;
|
|
@@ -56,8 +57,21 @@ type NextUpQueue = {
|
|
|
56
57
|
items: NextUpQueueItem[];
|
|
57
58
|
degraded: string[];
|
|
58
59
|
};
|
|
60
|
+
type MilestoneBreakdownTask = {
|
|
61
|
+
id: string;
|
|
62
|
+
title: string;
|
|
63
|
+
status: string;
|
|
64
|
+
};
|
|
65
|
+
type MilestoneBreakdownEntry = {
|
|
66
|
+
id: string;
|
|
67
|
+
title: string;
|
|
68
|
+
tasks: MilestoneBreakdownTask[];
|
|
69
|
+
totalTasks: number;
|
|
70
|
+
doneTasks: number;
|
|
71
|
+
};
|
|
59
72
|
type RegisterMissionControlReadRoutesDeps<TRes> = {
|
|
60
73
|
autoContinueRuns: Map<string, AutoContinueRunRecord>;
|
|
74
|
+
restoreAutoContinueRun?: (initiativeId: string) => Promise<AutoContinueRunRecord | null>;
|
|
61
75
|
defaultAutoContinueTokenBudget: () => number | null;
|
|
62
76
|
defaultAutoContinueMaxParallelSlices?: () => number;
|
|
63
77
|
autoContinueTickMs: number;
|
|
@@ -619,6 +619,11 @@ function mapCanonicalSlicesToQueueItems(input) {
|
|
|
619
619
|
const record = asRecord(entry);
|
|
620
620
|
if (!record)
|
|
621
621
|
continue;
|
|
622
|
+
const sliceKind = (asString(record.sliceKind) ?? asString(record.slice_kind) ?? "")
|
|
623
|
+
.trim()
|
|
624
|
+
.toLowerCase();
|
|
625
|
+
if (sliceKind && sliceKind !== "work_slice")
|
|
626
|
+
continue;
|
|
622
627
|
const initiativeId = asString(record.initiativeId) ?? asString(record.initiative_id);
|
|
623
628
|
const workstreamId = asString(record.workstreamId) ?? asString(record.workstream_id);
|
|
624
629
|
if (!initiativeId || !workstreamId)
|
|
@@ -742,6 +747,7 @@ async function loadInitiativeGraphIndex(deps, initiativeId) {
|
|
|
742
747
|
const nodes = Array.isArray(graph?.nodes) ? graph.nodes : [];
|
|
743
748
|
const tasksById = new Map();
|
|
744
749
|
const milestoneTitleById = new Map();
|
|
750
|
+
const milestoneWorkstream = new Map();
|
|
745
751
|
for (const nodeEntry of nodes) {
|
|
746
752
|
const node = asRecord(nodeEntry);
|
|
747
753
|
if (!node)
|
|
@@ -752,6 +758,9 @@ async function loadInitiativeGraphIndex(deps, initiativeId) {
|
|
|
752
758
|
continue;
|
|
753
759
|
if (type === "milestone") {
|
|
754
760
|
milestoneTitleById.set(id, asString(node.title) ?? id);
|
|
761
|
+
const wsId = asString(node.workstreamId) ?? asString(node.parentId);
|
|
762
|
+
if (wsId)
|
|
763
|
+
milestoneWorkstream.set(id, wsId);
|
|
755
764
|
continue;
|
|
756
765
|
}
|
|
757
766
|
if (type !== "task")
|
|
@@ -767,11 +776,63 @@ async function loadInitiativeGraphIndex(deps, initiativeId) {
|
|
|
767
776
|
updatedAt: asString(node.updatedAt),
|
|
768
777
|
});
|
|
769
778
|
}
|
|
779
|
+
// Build milestonesByWorkstream from milestones + their child tasks
|
|
780
|
+
const milestonesByWorkstream = new Map();
|
|
781
|
+
for (const [msId, wsId] of milestoneWorkstream) {
|
|
782
|
+
const taskIds = [];
|
|
783
|
+
for (const task of tasksById.values()) {
|
|
784
|
+
if (task.milestoneId === msId)
|
|
785
|
+
taskIds.push(task.id);
|
|
786
|
+
}
|
|
787
|
+
const entry = { id: msId, title: milestoneTitleById.get(msId) ?? msId, taskIds };
|
|
788
|
+
const existing = milestonesByWorkstream.get(wsId) ?? [];
|
|
789
|
+
existing.push(entry);
|
|
790
|
+
milestonesByWorkstream.set(wsId, existing);
|
|
791
|
+
}
|
|
770
792
|
return {
|
|
771
793
|
tasksById,
|
|
772
794
|
milestoneTitleById,
|
|
795
|
+
milestonesByWorkstream,
|
|
773
796
|
};
|
|
774
797
|
}
|
|
798
|
+
async function enrichWithMilestoneBreakdown(items, deps) {
|
|
799
|
+
if (items.length === 0)
|
|
800
|
+
return items;
|
|
801
|
+
const graphByInitiative = new Map();
|
|
802
|
+
const uniqueInitiatives = dedupeStrings(items.map((i) => i.initiativeId));
|
|
803
|
+
for (const id of uniqueInitiatives) {
|
|
804
|
+
try {
|
|
805
|
+
graphByInitiative.set(id, await loadInitiativeGraphIndex(deps, id));
|
|
806
|
+
}
|
|
807
|
+
catch {
|
|
808
|
+
// graph unavailable — skip enrichment for this initiative
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
if (graphByInitiative.size === 0)
|
|
812
|
+
return items;
|
|
813
|
+
for (const item of items) {
|
|
814
|
+
const graph = graphByInitiative.get(item.initiativeId);
|
|
815
|
+
if (!graph)
|
|
816
|
+
continue;
|
|
817
|
+
const milestones = graph.milestonesByWorkstream.get(item.workstreamId) ?? [];
|
|
818
|
+
if (milestones.length === 0)
|
|
819
|
+
continue;
|
|
820
|
+
item.milestoneBreakdown = milestones.map((ms) => {
|
|
821
|
+
const tasks = ms.taskIds.map((tid) => {
|
|
822
|
+
const task = graph.tasksById.get(tid);
|
|
823
|
+
return { id: tid, title: task?.title ?? "Untitled", status: task?.status ?? "pending" };
|
|
824
|
+
});
|
|
825
|
+
return {
|
|
826
|
+
id: ms.id,
|
|
827
|
+
title: ms.title,
|
|
828
|
+
tasks,
|
|
829
|
+
totalTasks: tasks.length,
|
|
830
|
+
doneTasks: tasks.filter((t) => t.status === "done" || t.status === "completed").length,
|
|
831
|
+
};
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
return items;
|
|
835
|
+
}
|
|
775
836
|
export function registerMissionControlReadRoutes(router, deps) {
|
|
776
837
|
// Handler registrations are process-local. Reset route caches so each newly
|
|
777
838
|
// constructed handler starts from a clean canonical cache/bypass state.
|
|
@@ -803,7 +864,10 @@ export function registerMissionControlReadRoutes(router, deps) {
|
|
|
803
864
|
sendRouteError(res, 400, "mission-control.read.auto-continue.status.validation", "initiativeId is required");
|
|
804
865
|
return;
|
|
805
866
|
}
|
|
806
|
-
|
|
867
|
+
let run = deps.autoContinueRuns.get(id) ?? null;
|
|
868
|
+
if (!run && deps.restoreAutoContinueRun) {
|
|
869
|
+
run = await deps.restoreAutoContinueRun(id) ?? null;
|
|
870
|
+
}
|
|
807
871
|
deps.sendJson(res, 200, {
|
|
808
872
|
ok: true,
|
|
809
873
|
initiativeId: id,
|
|
@@ -953,7 +1017,7 @@ export function registerMissionControlReadRoutes(router, deps) {
|
|
|
953
1017
|
if (isCanonicalAllScopeMismatch(canonicalRecord, useAllScope)) {
|
|
954
1018
|
throw new Error("canonical next-up all-workspaces scope mismatch");
|
|
955
1019
|
}
|
|
956
|
-
const canonicalItems = applyQueueNoiseControls(normalizeQueueItems(canonicalRecord.items).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs });
|
|
1020
|
+
const canonicalItems = await enrichWithMilestoneBreakdown(applyQueueNoiseControls(normalizeQueueItems(canonicalRecord.items).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs }), deps);
|
|
957
1021
|
const canonicalTotal = Math.max(canonicalItems.length, Math.floor(asNumber(canonicalRecord.total) ?? canonicalItems.length)) ?? canonicalItems.length;
|
|
958
1022
|
const canonicalPagination = parsePaginationEnvelope(canonicalRecord.pagination, {
|
|
959
1023
|
offset,
|
|
@@ -1081,7 +1145,7 @@ export function registerMissionControlReadRoutes(router, deps) {
|
|
|
1081
1145
|
if (isCanonicalAllScopeMismatch(canonicalSlicesRecord, useAllScope)) {
|
|
1082
1146
|
throw new Error("canonical slices all-workspaces scope mismatch");
|
|
1083
1147
|
}
|
|
1084
|
-
const bridgedItems = applyQueueNoiseControls(mapCanonicalSlicesToQueueItems(canonicalSlicesRecord.items).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs });
|
|
1148
|
+
const bridgedItems = await enrichWithMilestoneBreakdown(applyQueueNoiseControls(mapCanonicalSlicesToQueueItems(canonicalSlicesRecord.items).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs }), deps);
|
|
1085
1149
|
if (bridgedItems.length > 0) {
|
|
1086
1150
|
const paged = applySliceSearchAndPagination({
|
|
1087
1151
|
items: bridgedItems,
|
|
@@ -1124,7 +1188,7 @@ export function registerMissionControlReadRoutes(router, deps) {
|
|
|
1124
1188
|
initiativeId,
|
|
1125
1189
|
projectId,
|
|
1126
1190
|
});
|
|
1127
|
-
const items = applyQueueNoiseControls(normalizeQueueItems(queue.items ?? []).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs });
|
|
1191
|
+
const items = await enrichWithMilestoneBreakdown(applyQueueNoiseControls(normalizeQueueItems(queue.items ?? []).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs }), deps);
|
|
1128
1192
|
const paged = applySliceSearchAndPagination({
|
|
1129
1193
|
items,
|
|
1130
1194
|
searchTerm: "",
|
|
@@ -1157,7 +1221,7 @@ export function registerMissionControlReadRoutes(router, deps) {
|
|
|
1157
1221
|
initiativeId,
|
|
1158
1222
|
projectId,
|
|
1159
1223
|
});
|
|
1160
|
-
const items = applyQueueNoiseControls(normalizeQueueItems(queue.items ?? []).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs });
|
|
1224
|
+
const items = await enrichWithMilestoneBreakdown(applyQueueNoiseControls(normalizeQueueItems(queue.items ?? []).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs }), deps);
|
|
1161
1225
|
const paged = applySliceSearchAndPagination({
|
|
1162
1226
|
items,
|
|
1163
1227
|
searchTerm: "",
|
package/dist/outbox.js
CHANGED
|
@@ -114,10 +114,17 @@ async function appendOutboxDeadLetterRecord(sessionId, record) {
|
|
|
114
114
|
await hardenPath(targetPath, 0o600);
|
|
115
115
|
}
|
|
116
116
|
export async function appendOutboxDeadLetter(sessionId, event, reason, error) {
|
|
117
|
+
let normalizedSessionId;
|
|
118
|
+
try {
|
|
119
|
+
normalizedSessionId = normalizeSessionId(sessionId);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
117
124
|
const droppedAt = new Date().toISOString();
|
|
118
|
-
await appendOutboxDeadLetterRecord(
|
|
125
|
+
await appendOutboxDeadLetterRecord(normalizedSessionId, {
|
|
119
126
|
droppedAt,
|
|
120
|
-
queueId:
|
|
127
|
+
queueId: normalizedSessionId,
|
|
121
128
|
reason,
|
|
122
129
|
error: error ?? null,
|
|
123
130
|
event,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useorgx/openclaw-plugin",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.20",
|
|
4
4
|
"description": "OrgX plugin for OpenClaw — agent orchestration, quality gates, model routing, and live dashboard",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"verify:conduit-mcp": "node ./scripts/verify-conduit-mcp.mjs",
|
|
55
55
|
"verify:repo-hygiene": "node ./scripts/verify-repo-hygiene.mjs",
|
|
56
56
|
"dev:main": "node ./scripts/dev-main-sync.mjs",
|
|
57
|
+
"dev:live": "node ./scripts/live-dev-serve.mjs",
|
|
57
58
|
"e2e:auto-continue": "node ./scripts/e2e-auto-continue.mjs",
|
|
58
59
|
"e2e:agent-suite": "npm run build:core && node ./scripts/e2e-agent-suite-kickoff-3x.mjs",
|
|
59
60
|
"demo:record": "node ./scripts/record-demo.mjs",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as a,j as e}from"./Dj2k1r16.js";import{e as l,y as p,E as h,$ as u}from"./C8AYbjlq.js";import{DecisionQueue as b}from"./CMir7ekf.js";import"./DMKyYAtD.js";import"./eeHXe_OQ.js";import"./cX2e-TLi.js";import"./BjK42gtU.js";import"./BV0BcV1u.js";import"./DBRLnKWw.js";import"./D8mvKY2h.js";function D({open:n,onClose:o,decisions:t,onApproveDecision:i,onRejectDecision:m,onApproveAll:d,onBulkDecisionAction:x}){const r=a.useMemo(()=>t.length>0?Math.max(0,...t.map(c=>c.waitingMinutes)):0,[t]),s=a.useMemo(()=>t.length>=20||r>=15?l.red:t.length>0?l.amber:l.textMuted,[t.length,r]);return e.jsx(p,{open:n,onClose:o,maxWidth:"max-w-3xl",children:e.jsxs("div",{className:"flex h-full w-full flex-col",children:[e.jsx("div",{className:"border-b border-subtle px-5 pt-5 pb-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("h3",{className:"inline-flex items-center gap-2 text-heading font-semibold text-white",children:[e.jsx(h,{type:"decision",size:14}),e.jsx("span",{className:"truncate",children:"Decisions"}),e.jsx("span",{className:"rounded-full border px-2 py-0.5 text-caption font-semibold",style:{borderColor:`${s}30`,backgroundColor:`${s}14`,color:s},children:t.length})]}),e.jsx("p",{className:"mt-1 text-body leading-relaxed text-secondary",children:"Bulk review and resolve pending decisions."}),t.length>0&&e.jsxs("p",{className:"mt-2 text-caption text-secondary",children:["Oldest: ",e.jsxs("span",{className:"font-semibold text-white",children:[u(r)," ago"]})]})]}),e.jsx("button",{type:"button",onClick:o,className:"rounded-md border border-strong bg-white/[0.03] px-2.5 py-1.5 text-caption text-primary transition-colors hover:bg-white/[0.08]","aria-label":"Close decisions modal",children:"Close"})]})}),e.jsx("div",{className:"min-h-0 flex-1 overflow-hidden p-4",children:e.jsx(b,{decisions:t,onApproveDecision:i,onRejectDecision:m,onApproveAll:d,onBulkDecisionAction:x})})]})})}export{D as BulkDecisionsModal};
|
|
Binary file
|
|
Binary file
|