@useorgx/openclaw-plugin 0.7.11 → 0.7.16
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/README.md +94 -122
- package/dashboard/dist/assets/8pbG6uLK.js +1 -0
- package/dashboard/dist/assets/8pbG6uLK.js.br +0 -0
- package/dashboard/dist/assets/8pbG6uLK.js.gz +0 -0
- package/dashboard/dist/assets/B1LENRC8.js +212 -0
- package/dashboard/dist/assets/B1LENRC8.js.br +0 -0
- package/dashboard/dist/assets/B1LENRC8.js.gz +0 -0
- package/dashboard/dist/assets/{tcEHYcbW.js → BCudUvwg.js} +1 -1
- package/dashboard/dist/assets/BCudUvwg.js.br +0 -0
- package/dashboard/dist/assets/BCudUvwg.js.gz +0 -0
- package/dashboard/dist/assets/{Du1wfrXa.js → BM75sh1f.js} +2 -2
- package/dashboard/dist/assets/BM75sh1f.js.br +0 -0
- package/dashboard/dist/assets/BM75sh1f.js.gz +0 -0
- package/dashboard/dist/assets/BV0BcV1u.js +53 -0
- package/dashboard/dist/assets/BV0BcV1u.js.br +0 -0
- package/dashboard/dist/assets/BV0BcV1u.js.gz +0 -0
- package/dashboard/dist/assets/BYVYH9CH.js +1 -0
- package/dashboard/dist/assets/BYVYH9CH.js.br +0 -0
- package/dashboard/dist/assets/BYVYH9CH.js.gz +0 -0
- package/dashboard/dist/assets/BjK42gtU.js +1 -0
- package/dashboard/dist/assets/BjK42gtU.js.br +0 -0
- package/dashboard/dist/assets/BjK42gtU.js.gz +0 -0
- package/dashboard/dist/assets/BkMrrjAv.js +1 -0
- package/dashboard/dist/assets/BkMrrjAv.js.br +0 -0
- package/dashboard/dist/assets/BkMrrjAv.js.gz +0 -0
- package/dashboard/dist/assets/BpF7v1Dk.js +1 -0
- package/dashboard/dist/assets/BpF7v1Dk.js.br +0 -0
- package/dashboard/dist/assets/BpF7v1Dk.js.gz +0 -0
- package/dashboard/dist/assets/{AqVoI3SF.js → Bv_86bUY.js} +1 -1
- package/dashboard/dist/assets/Bv_86bUY.js.br +0 -0
- package/dashboard/dist/assets/Bv_86bUY.js.gz +0 -0
- package/dashboard/dist/assets/C-MOJWHs.js +1 -0
- package/dashboard/dist/assets/C-MOJWHs.js.br +0 -0
- package/dashboard/dist/assets/C-MOJWHs.js.gz +0 -0
- package/dashboard/dist/assets/C3PrI8L7.js +1 -0
- package/dashboard/dist/assets/C3PrI8L7.js.br +0 -0
- package/dashboard/dist/assets/C3PrI8L7.js.gz +0 -0
- package/dashboard/dist/assets/{CD-q5mdP.js → C6AqbA9J.js} +1 -1
- package/dashboard/dist/assets/C6AqbA9J.js.br +0 -0
- package/dashboard/dist/assets/C6AqbA9J.js.gz +0 -0
- package/dashboard/dist/assets/CSlBSRyv.js +1 -0
- package/dashboard/dist/assets/CSlBSRyv.js.br +0 -0
- package/dashboard/dist/assets/CSlBSRyv.js.gz +0 -0
- package/dashboard/dist/assets/{beHYBbh6.js → CUXb_4F3.js} +2 -2
- package/dashboard/dist/assets/CUXb_4F3.js.br +0 -0
- package/dashboard/dist/assets/CUXb_4F3.js.gz +0 -0
- package/dashboard/dist/assets/Cn8sRTkO.js +1 -0
- package/dashboard/dist/assets/Cn8sRTkO.js.br +0 -0
- package/dashboard/dist/assets/Cn8sRTkO.js.gz +0 -0
- package/dashboard/dist/assets/D5IgXoTj.js +1 -0
- package/dashboard/dist/assets/D5IgXoTj.js.br +0 -0
- package/dashboard/dist/assets/D5IgXoTj.js.gz +0 -0
- package/dashboard/dist/assets/DMKyYAtD.js +1 -0
- package/dashboard/dist/assets/DMKyYAtD.js.br +0 -0
- package/dashboard/dist/assets/DMKyYAtD.js.gz +0 -0
- package/dashboard/dist/assets/{DCP-C7fn.js → DXzpQUC0.js} +1 -1
- package/dashboard/dist/assets/DXzpQUC0.js.br +0 -0
- package/dashboard/dist/assets/DXzpQUC0.js.gz +0 -0
- package/dashboard/dist/assets/Dj2k1r16.js +8 -0
- package/dashboard/dist/assets/Dj2k1r16.js.br +0 -0
- package/dashboard/dist/assets/Dj2k1r16.js.gz +0 -0
- package/dashboard/dist/assets/JDPvhd68.js +1 -0
- package/dashboard/dist/assets/JDPvhd68.js.br +0 -0
- package/dashboard/dist/assets/JDPvhd68.js.gz +0 -0
- package/dashboard/dist/assets/R6N_VVqm.js +1 -0
- package/dashboard/dist/assets/R6N_VVqm.js.br +0 -0
- package/dashboard/dist/assets/R6N_VVqm.js.gz +0 -0
- package/dashboard/dist/assets/cEP7N1dn.js +1 -0
- package/dashboard/dist/assets/cEP7N1dn.js.br +0 -0
- package/dashboard/dist/assets/cEP7N1dn.js.gz +0 -0
- package/dashboard/dist/assets/cX2e-TLi.js +1 -0
- package/dashboard/dist/assets/cX2e-TLi.js.br +0 -0
- package/dashboard/dist/assets/cX2e-TLi.js.gz +0 -0
- package/dashboard/dist/assets/eeHXe_OQ.js +9 -0
- package/dashboard/dist/assets/eeHXe_OQ.js.br +0 -0
- package/dashboard/dist/assets/eeHXe_OQ.js.gz +0 -0
- package/dashboard/dist/assets/iLnvdWmW.css +1 -0
- package/dashboard/dist/assets/iLnvdWmW.css.br +0 -0
- package/dashboard/dist/assets/iLnvdWmW.css.gz +0 -0
- package/dashboard/dist/assets/konqMbVI.js +1 -0
- package/dashboard/dist/assets/konqMbVI.js.br +0 -0
- package/dashboard/dist/assets/konqMbVI.js.gz +0 -0
- package/dashboard/dist/assets/wc6cgXzV.js +1 -0
- package/dashboard/dist/assets/wc6cgXzV.js.br +0 -0
- package/dashboard/dist/assets/wc6cgXzV.js.gz +0 -0
- package/dashboard/dist/brand/control-tower.png +0 -0
- package/dashboard/dist/brand/design-codex.png +0 -0
- package/dashboard/dist/brand/engineering-autopilot.png +0 -0
- package/dashboard/dist/brand/launch-captain.png +0 -0
- package/dashboard/dist/brand/orgx-logo.png +0 -0
- package/dashboard/dist/brand/pipeline-intelligence.png +0 -0
- package/dashboard/dist/brand/product-orchestrator.png +0 -0
- package/dashboard/dist/brand/xandy-orchestrator.png +0 -0
- package/dashboard/dist/index.html +8 -6
- package/dashboard/dist/index.html.br +0 -0
- package/dashboard/dist/index.html.gz +0 -0
- package/dist/hash-utils.d.ts +1 -0
- package/dist/hash-utils.js +4 -0
- package/dist/http/helpers/auto-continue-engine.d.ts +15 -0
- package/dist/http/helpers/auto-continue-engine.js +289 -67
- package/dist/http/helpers/autopilot-slice-utils.js +112 -66
- package/dist/http/helpers/hash-utils.d.ts +1 -1
- package/dist/http/helpers/hash-utils.js +1 -1
- package/dist/http/helpers/mission-control.d.ts +3 -0
- package/dist/http/helpers/mission-control.js +43 -9
- package/dist/http/helpers/queue-constants.d.ts +37 -0
- package/dist/http/helpers/queue-constants.js +34 -0
- package/dist/http/helpers/slice-experience-v2.js +2 -5
- package/dist/http/helpers/slice-run-projections.js +2 -5
- package/dist/http/helpers/value-utils.d.ts +1 -1
- package/dist/http/helpers/value-utils.js +5 -2
- package/dist/http/helpers/workspace-scope.js +4 -3
- package/dist/http/index.js +104 -61
- package/dist/http/routes/chat.d.ts +1 -1
- package/dist/http/routes/chat.js +3 -23
- package/dist/http/routes/entities.js +60 -2
- package/dist/http/routes/entity-dynamic.js +49 -9
- package/dist/http/routes/live-snapshot.d.ts +10 -1
- package/dist/http/routes/live-snapshot.js +15 -26
- package/dist/http/routes/mission-control-actions.d.ts +6 -0
- package/dist/http/routes/mission-control-actions.js +35 -18
- package/dist/http/routes/mission-control-read.js +4 -107
- package/dist/lib/type-coercion.d.ts +10 -0
- package/dist/lib/type-coercion.js +82 -0
- package/dist/mcp-http-handler.js +14 -2
- package/dist/openclaw.plugin.json +1 -1
- package/dist/services/experiment-randomization.js +9 -2
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -2
- package/dashboard/dist/assets/AqVoI3SF.js.br +0 -0
- package/dashboard/dist/assets/AqVoI3SF.js.gz +0 -0
- package/dashboard/dist/assets/BC4WvnHJ.js +0 -1
- package/dashboard/dist/assets/BC4WvnHJ.js.br +0 -0
- package/dashboard/dist/assets/BC4WvnHJ.js.gz +0 -0
- package/dashboard/dist/assets/BG5mwTkg.js +0 -1
- package/dashboard/dist/assets/BG5mwTkg.js.br +0 -0
- package/dashboard/dist/assets/BG5mwTkg.js.gz +0 -0
- package/dashboard/dist/assets/BJgZIVUQ.js +0 -53
- package/dashboard/dist/assets/BJgZIVUQ.js.br +0 -0
- package/dashboard/dist/assets/BJgZIVUQ.js.gz +0 -0
- package/dashboard/dist/assets/BNh-XYPV.js +0 -1
- package/dashboard/dist/assets/BNh-XYPV.js.br +0 -0
- package/dashboard/dist/assets/BNh-XYPV.js.gz +0 -0
- package/dashboard/dist/assets/BTAEErUY.js +0 -1
- package/dashboard/dist/assets/BTAEErUY.js.br +0 -0
- package/dashboard/dist/assets/BTAEErUY.js.gz +0 -0
- package/dashboard/dist/assets/BepW_590.js +0 -1
- package/dashboard/dist/assets/BepW_590.js.br +0 -0
- package/dashboard/dist/assets/BepW_590.js.gz +0 -0
- package/dashboard/dist/assets/BerAfzjq.js +0 -1
- package/dashboard/dist/assets/BerAfzjq.js.br +0 -0
- package/dashboard/dist/assets/BerAfzjq.js.gz +0 -0
- package/dashboard/dist/assets/Bp3N-QL5.js +0 -212
- package/dashboard/dist/assets/Bp3N-QL5.js.br +0 -0
- package/dashboard/dist/assets/Bp3N-QL5.js.gz +0 -0
- package/dashboard/dist/assets/C-KIc3Wc.js +0 -1
- package/dashboard/dist/assets/C-KIc3Wc.js.br +0 -0
- package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
- package/dashboard/dist/assets/C3dZRz9P.css +0 -1
- package/dashboard/dist/assets/C3dZRz9P.css.br +0 -0
- package/dashboard/dist/assets/C3dZRz9P.css.gz +0 -0
- package/dashboard/dist/assets/CD-q5mdP.js.br +0 -0
- package/dashboard/dist/assets/CD-q5mdP.js.gz +0 -0
- package/dashboard/dist/assets/CL_wXqR7.js +0 -1
- package/dashboard/dist/assets/CL_wXqR7.js.br +0 -0
- package/dashboard/dist/assets/CL_wXqR7.js.gz +0 -0
- package/dashboard/dist/assets/CdvjC9G9.js +0 -1
- package/dashboard/dist/assets/CdvjC9G9.js.br +0 -0
- package/dashboard/dist/assets/CdvjC9G9.js.gz +0 -0
- package/dashboard/dist/assets/Ck2agw-s.js +0 -1
- package/dashboard/dist/assets/Ck2agw-s.js.br +0 -0
- package/dashboard/dist/assets/Ck2agw-s.js.gz +0 -0
- package/dashboard/dist/assets/CxQ08qFN.js +0 -9
- package/dashboard/dist/assets/CxQ08qFN.js.br +0 -0
- package/dashboard/dist/assets/CxQ08qFN.js.gz +0 -0
- package/dashboard/dist/assets/D2CH1H6k.js +0 -1
- package/dashboard/dist/assets/D2CH1H6k.js.br +0 -0
- package/dashboard/dist/assets/D2CH1H6k.js.gz +0 -0
- package/dashboard/dist/assets/D9esz7jd.js +0 -1
- package/dashboard/dist/assets/D9esz7jd.js.br +0 -0
- package/dashboard/dist/assets/D9esz7jd.js.gz +0 -0
- package/dashboard/dist/assets/DCP-C7fn.js.br +0 -0
- package/dashboard/dist/assets/DCP-C7fn.js.gz +0 -0
- package/dashboard/dist/assets/DJASCd69.js +0 -1
- package/dashboard/dist/assets/DJASCd69.js.br +0 -0
- package/dashboard/dist/assets/DJASCd69.js.gz +0 -0
- package/dashboard/dist/assets/Dm9AybAp.js +0 -1
- package/dashboard/dist/assets/Dm9AybAp.js.br +0 -0
- package/dashboard/dist/assets/Dm9AybAp.js.gz +0 -0
- package/dashboard/dist/assets/Du1wfrXa.js.br +0 -0
- package/dashboard/dist/assets/Du1wfrXa.js.gz +0 -0
- package/dashboard/dist/assets/beHYBbh6.js.br +0 -0
- package/dashboard/dist/assets/beHYBbh6.js.gz +0 -0
- package/dashboard/dist/assets/cNrhgGc1.js +0 -8
- package/dashboard/dist/assets/cNrhgGc1.js.br +0 -0
- package/dashboard/dist/assets/cNrhgGc1.js.gz +0 -0
- package/dashboard/dist/assets/tcEHYcbW.js.br +0 -0
- package/dashboard/dist/assets/tcEHYcbW.js.gz +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { resolveWorkspaceScope as resolveCanonicalWorkspaceScope } from "../helpers/workspace-scope.js";
|
|
3
|
+
import { asRecord, asString, asStringArray } from "../../lib/type-coercion.js";
|
|
3
4
|
import { buildDispatchGatewayEnvelope } from "./dispatch-gateway-envelope.js";
|
|
4
5
|
const PLAY_QUEUE_LOOKUP_TIMEOUT_MS = (() => {
|
|
5
6
|
const raw = process.env.ORGX_PLAY_QUEUE_LOOKUP_TIMEOUT_MS;
|
|
@@ -194,24 +195,7 @@ function shouldResetTaskStatus(status, states) {
|
|
|
194
195
|
}
|
|
195
196
|
return false;
|
|
196
197
|
}
|
|
197
|
-
|
|
198
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
199
|
-
return null;
|
|
200
|
-
return value;
|
|
201
|
-
}
|
|
202
|
-
function asString(value) {
|
|
203
|
-
if (typeof value !== "string")
|
|
204
|
-
return null;
|
|
205
|
-
const trimmed = value.trim();
|
|
206
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
207
|
-
}
|
|
208
|
-
function asStringArray(value) {
|
|
209
|
-
if (!Array.isArray(value))
|
|
210
|
-
return [];
|
|
211
|
-
return value
|
|
212
|
-
.map((entry) => asString(entry))
|
|
213
|
-
.filter((entry) => Boolean(entry));
|
|
214
|
-
}
|
|
198
|
+
// asRecord, asString, asStringArray imported from ../../lib/type-coercion.js
|
|
215
199
|
function parseCycleGraphNodes(graph) {
|
|
216
200
|
const root = asRecord(graph);
|
|
217
201
|
const rawNodes = Array.isArray(root?.nodes) ? root.nodes : [];
|
|
@@ -1652,6 +1636,39 @@ export function registerMissionControlActionsRoutes(router, deps) {
|
|
|
1652
1636
|
sendRouteException(res, "mission-control.auto-continue.stop.handler", err);
|
|
1653
1637
|
}
|
|
1654
1638
|
}, "Mission-control auto-continue stop");
|
|
1639
|
+
router.add("POST", "mission-control/auto-continue/skip", async ({ req, query, res }) => {
|
|
1640
|
+
try {
|
|
1641
|
+
const payload = await deps.parseJsonRequest(req);
|
|
1642
|
+
const initiativeId = (deps.pickString(payload, ["initiativeId", "initiative_id"]) ??
|
|
1643
|
+
query.get("initiativeId") ??
|
|
1644
|
+
query.get("initiative_id") ??
|
|
1645
|
+
"")
|
|
1646
|
+
.trim();
|
|
1647
|
+
if (!initiativeId) {
|
|
1648
|
+
sendRouteError(res, 400, "mission-control.auto-continue.skip.validation", "initiativeId is required");
|
|
1649
|
+
return;
|
|
1650
|
+
}
|
|
1651
|
+
const workstreamId = (deps.pickString(payload, ["workstreamId", "workstream_id"]) ??
|
|
1652
|
+
query.get("workstreamId") ??
|
|
1653
|
+
query.get("workstream_id") ??
|
|
1654
|
+
"")
|
|
1655
|
+
.trim();
|
|
1656
|
+
if (!workstreamId) {
|
|
1657
|
+
sendRouteError(res, 400, "mission-control.auto-continue.skip.validation", "workstreamId is required");
|
|
1658
|
+
return;
|
|
1659
|
+
}
|
|
1660
|
+
const reason = (deps.pickString(payload, ["reason"]) ??
|
|
1661
|
+
query.get("reason") ??
|
|
1662
|
+
"")
|
|
1663
|
+
.trim() || undefined;
|
|
1664
|
+
const result = await deps.skipCurrentWorkstream(initiativeId, workstreamId, reason);
|
|
1665
|
+
deps.clearNextUpQueueCache(initiativeId);
|
|
1666
|
+
deps.sendJson(res, result.ok ? 200 : 404, result);
|
|
1667
|
+
}
|
|
1668
|
+
catch (err) {
|
|
1669
|
+
sendRouteException(res, "mission-control.auto-continue.skip.handler", err);
|
|
1670
|
+
}
|
|
1671
|
+
}, "Mission-control auto-continue skip");
|
|
1655
1672
|
router.add("POST", "mission-control/auto-continue/tick", async ({ req, query, res }) => {
|
|
1656
1673
|
try {
|
|
1657
1674
|
const payload = await deps.parseJsonRequest(req);
|
|
@@ -1,34 +1,7 @@
|
|
|
1
1
|
import { listBuiltInSentinels } from "../helpers/sentinel-catalog.js";
|
|
2
2
|
import { resolveWorkspaceScope, workspaceScopeFromHeaders, } from "../helpers/workspace-scope.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
return null;
|
|
6
|
-
return value;
|
|
7
|
-
}
|
|
8
|
-
function asString(value) {
|
|
9
|
-
if (typeof value !== "string")
|
|
10
|
-
return null;
|
|
11
|
-
const trimmed = value.trim();
|
|
12
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
13
|
-
}
|
|
14
|
-
function asArray(value) {
|
|
15
|
-
if (Array.isArray(value))
|
|
16
|
-
return value;
|
|
17
|
-
if (typeof value !== "string")
|
|
18
|
-
return [];
|
|
19
|
-
const trimmed = value.trim();
|
|
20
|
-
try {
|
|
21
|
-
const parsed = JSON.parse(trimmed);
|
|
22
|
-
if (Array.isArray(parsed))
|
|
23
|
-
return parsed;
|
|
24
|
-
if (parsed && typeof parsed === "object")
|
|
25
|
-
return [parsed];
|
|
26
|
-
return [];
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
}
|
|
3
|
+
import { asRecord, asString, asNumber, asArray, asStringArray, } from "../../lib/type-coercion.js";
|
|
4
|
+
// asRecord, asString, asArray, asNumber, asStringArray imported from ../../lib/type-coercion.js
|
|
32
5
|
function normalizeRunnerValue(value) {
|
|
33
6
|
const raw = asString(value);
|
|
34
7
|
if (!raw)
|
|
@@ -105,29 +78,7 @@ function mergeRunnerAgents(...groups) {
|
|
|
105
78
|
}
|
|
106
79
|
return output;
|
|
107
80
|
}
|
|
108
|
-
|
|
109
|
-
if (typeof value === "number" && Number.isFinite(value))
|
|
110
|
-
return value;
|
|
111
|
-
if (typeof value === "string" && value.trim().length > 0) {
|
|
112
|
-
const parsed = Number(value);
|
|
113
|
-
if (Number.isFinite(parsed))
|
|
114
|
-
return parsed;
|
|
115
|
-
}
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
function asStringArray(value) {
|
|
119
|
-
const entries = asArray(value);
|
|
120
|
-
if (entries.length === 0)
|
|
121
|
-
return [];
|
|
122
|
-
const values = [];
|
|
123
|
-
for (const entry of entries) {
|
|
124
|
-
const normalized = asString(entry);
|
|
125
|
-
if (!normalized)
|
|
126
|
-
continue;
|
|
127
|
-
values.push(normalized);
|
|
128
|
-
}
|
|
129
|
-
return dedupeStrings(values);
|
|
130
|
-
}
|
|
81
|
+
// asNumber, asStringArray imported from ../../lib/type-coercion.js
|
|
131
82
|
function isCanonicalAllScopeMismatch(canonicalRecord, useAllScope) {
|
|
132
83
|
if (!useAllScope)
|
|
133
84
|
return false;
|
|
@@ -846,64 +797,10 @@ export function registerMissionControlReadRoutes(router, deps) {
|
|
|
846
797
|
sendRouteError(res, 400, "mission-control.read.auto-continue.status.validation", workspaceScope.error);
|
|
847
798
|
return;
|
|
848
799
|
}
|
|
849
|
-
const scopedProjectId = workspaceScope.workspaceId;
|
|
850
800
|
const initiativeId = query.get("initiative_id") ?? query.get("initiativeId") ?? "";
|
|
851
801
|
const id = initiativeId.trim();
|
|
852
|
-
let scopedInitiatives = null;
|
|
853
|
-
if (scopedProjectId) {
|
|
854
|
-
try {
|
|
855
|
-
const ids = await deps.listInitiativeIdsForProject({ projectId: scopedProjectId });
|
|
856
|
-
scopedInitiatives = new Set(ids);
|
|
857
|
-
}
|
|
858
|
-
catch {
|
|
859
|
-
// best effort: if scope lookup is unavailable, fall back to unscoped run resolution.
|
|
860
|
-
scopedInitiatives = null;
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
const statusRank = (value) => {
|
|
864
|
-
const normalized = (value ?? "").trim().toLowerCase();
|
|
865
|
-
if (normalized === "running")
|
|
866
|
-
return 0;
|
|
867
|
-
if (normalized === "stopping")
|
|
868
|
-
return 1;
|
|
869
|
-
if (normalized === "blocked")
|
|
870
|
-
return 2;
|
|
871
|
-
if (normalized === "stopped")
|
|
872
|
-
return 3;
|
|
873
|
-
return 4;
|
|
874
|
-
};
|
|
875
|
-
const updatedEpoch = (value) => {
|
|
876
|
-
const parsed = Date.parse(value ?? "");
|
|
877
|
-
return Number.isFinite(parsed) ? parsed : 0;
|
|
878
|
-
};
|
|
879
802
|
if (!id) {
|
|
880
|
-
|
|
881
|
-
const runInitiativeId = (run.initiativeId ?? "").trim();
|
|
882
|
-
if (!runInitiativeId)
|
|
883
|
-
return false;
|
|
884
|
-
if (scopedInitiatives && !scopedInitiatives.has(runInitiativeId))
|
|
885
|
-
return false;
|
|
886
|
-
return true;
|
|
887
|
-
});
|
|
888
|
-
scopedRuns.sort((left, right) => {
|
|
889
|
-
const statusDelta = statusRank(left.status) - statusRank(right.status);
|
|
890
|
-
if (statusDelta !== 0)
|
|
891
|
-
return statusDelta;
|
|
892
|
-
return updatedEpoch(right.updatedAt) - updatedEpoch(left.updatedAt);
|
|
893
|
-
});
|
|
894
|
-
const run = scopedRuns[0] ?? null;
|
|
895
|
-
deps.sendJson(res, 200, {
|
|
896
|
-
ok: true,
|
|
897
|
-
initiativeId: run?.initiativeId ?? null,
|
|
898
|
-
run,
|
|
899
|
-
defaults: {
|
|
900
|
-
tokenBudget: deps.defaultAutoContinueTokenBudget(),
|
|
901
|
-
maxParallelSlices: typeof deps.defaultAutoContinueMaxParallelSlices === "function"
|
|
902
|
-
? deps.defaultAutoContinueMaxParallelSlices()
|
|
903
|
-
: 1,
|
|
904
|
-
tickMs: deps.autoContinueTickMs,
|
|
905
|
-
},
|
|
906
|
-
});
|
|
803
|
+
sendRouteError(res, 400, "mission-control.read.auto-continue.status.validation", "initiativeId is required");
|
|
907
804
|
return;
|
|
908
805
|
}
|
|
909
806
|
const run = deps.autoContinueRuns.get(id) ?? null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Safely cast unknown to a Record, or null if not a plain object. */
|
|
2
|
+
export declare function asRecord(value: unknown): Record<string, unknown> | null;
|
|
3
|
+
/** Safely cast unknown to a trimmed non-empty string, or null. */
|
|
4
|
+
export declare function asString(value: unknown): string | null;
|
|
5
|
+
/** Safely cast unknown to a finite number, or null. */
|
|
6
|
+
export declare function asNumber(value: unknown): number | null;
|
|
7
|
+
/** Safely cast unknown to an array. Attempts JSON parse for string values. */
|
|
8
|
+
export declare function asArray(value: unknown): unknown[];
|
|
9
|
+
/** Extract a deduplicated string array from unknown. */
|
|
10
|
+
export declare function asStringArray(value: unknown): string[];
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Shared type-coercion helpers for safe parsing of unknown API data.
|
|
3
|
+
// Previously duplicated across 20+ files.
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
/** Safely cast unknown to a Record, or null if not a plain object. */
|
|
6
|
+
export function asRecord(value) {
|
|
7
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
8
|
+
return null;
|
|
9
|
+
const proto = Object.getPrototypeOf(value);
|
|
10
|
+
if (proto !== Object.prototype && proto !== null)
|
|
11
|
+
return null;
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
/** Safely cast unknown to a trimmed non-empty string, or null. */
|
|
15
|
+
export function asString(value) {
|
|
16
|
+
if (typeof value !== "string")
|
|
17
|
+
return null;
|
|
18
|
+
const trimmed = value.trim();
|
|
19
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
20
|
+
}
|
|
21
|
+
/** Safely cast unknown to a finite number, or null. */
|
|
22
|
+
export function asNumber(value) {
|
|
23
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
24
|
+
return value;
|
|
25
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
26
|
+
const parsed = Number(value);
|
|
27
|
+
if (Number.isFinite(parsed))
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
/** Safely cast unknown to an array. Attempts JSON parse for string values. */
|
|
33
|
+
export function asArray(value) {
|
|
34
|
+
if (Array.isArray(value))
|
|
35
|
+
return value;
|
|
36
|
+
if (asRecord(value))
|
|
37
|
+
return [value];
|
|
38
|
+
if (typeof value !== "string")
|
|
39
|
+
return [];
|
|
40
|
+
const trimmed = value.trim();
|
|
41
|
+
try {
|
|
42
|
+
const parsed = JSON.parse(trimmed);
|
|
43
|
+
if (Array.isArray(parsed))
|
|
44
|
+
return parsed;
|
|
45
|
+
if (asRecord(parsed))
|
|
46
|
+
return [parsed];
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Extract a deduplicated string array from unknown. */
|
|
54
|
+
export function asStringArray(value) {
|
|
55
|
+
const entries = asArray(value);
|
|
56
|
+
if (entries.length === 0) {
|
|
57
|
+
const scalar = asString(value);
|
|
58
|
+
if (!scalar)
|
|
59
|
+
return [];
|
|
60
|
+
const fallbackEntries = scalar.includes(",") ? scalar.split(",") : [scalar];
|
|
61
|
+
const seenFallback = new Set();
|
|
62
|
+
const fallbackValues = [];
|
|
63
|
+
for (const entry of fallbackEntries) {
|
|
64
|
+
const normalized = asString(entry);
|
|
65
|
+
if (!normalized || seenFallback.has(normalized))
|
|
66
|
+
continue;
|
|
67
|
+
seenFallback.add(normalized);
|
|
68
|
+
fallbackValues.push(normalized);
|
|
69
|
+
}
|
|
70
|
+
return fallbackValues;
|
|
71
|
+
}
|
|
72
|
+
const seen = new Set();
|
|
73
|
+
const values = [];
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
const normalized = asString(entry);
|
|
76
|
+
if (!normalized || seen.has(normalized))
|
|
77
|
+
continue;
|
|
78
|
+
seen.add(normalized);
|
|
79
|
+
values.push(normalized);
|
|
80
|
+
}
|
|
81
|
+
return values;
|
|
82
|
+
}
|
package/dist/mcp-http-handler.js
CHANGED
|
@@ -136,6 +136,13 @@ async function readRequestBodyBuffer(req) {
|
|
|
136
136
|
return Buffer.from("", "utf8");
|
|
137
137
|
return await new Promise((resolve) => {
|
|
138
138
|
const chunks = [];
|
|
139
|
+
let settled = false;
|
|
140
|
+
const settle = () => {
|
|
141
|
+
if (settled)
|
|
142
|
+
return;
|
|
143
|
+
settled = true;
|
|
144
|
+
resolve(Buffer.concat(chunks));
|
|
145
|
+
};
|
|
139
146
|
const onData = (chunk) => {
|
|
140
147
|
if (typeof chunk === "string") {
|
|
141
148
|
chunks.push(Buffer.from(chunk, "utf8"));
|
|
@@ -147,9 +154,14 @@ async function readRequestBodyBuffer(req) {
|
|
|
147
154
|
chunks.push(Buffer.from(chunk));
|
|
148
155
|
}
|
|
149
156
|
};
|
|
150
|
-
const onEnd = () =>
|
|
151
|
-
const onError = () =>
|
|
157
|
+
const onEnd = () => settle();
|
|
158
|
+
const onError = () => settle();
|
|
152
159
|
req.on?.("data", onData);
|
|
160
|
+
if (typeof req.once === "function") {
|
|
161
|
+
req.once("end", onEnd);
|
|
162
|
+
req.once("error", onError);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
153
165
|
req.on?.("end", onEnd);
|
|
154
166
|
req.on?.("error", onError);
|
|
155
167
|
});
|
|
@@ -23,8 +23,13 @@ function normalizeArms(arms) {
|
|
|
23
23
|
if (!Array.isArray(arms) || arms.length === 0) {
|
|
24
24
|
throw new Error("arms must include at least one entry");
|
|
25
25
|
}
|
|
26
|
+
const seenIds = new Set();
|
|
26
27
|
const sanitized = arms.map((arm, index) => {
|
|
27
28
|
const id = sanitizeIdentifier(arm?.id, `arms[${index}].id`);
|
|
29
|
+
if (seenIds.has(id)) {
|
|
30
|
+
throw new Error(`arms[${index}].id must be unique`);
|
|
31
|
+
}
|
|
32
|
+
seenIds.add(id);
|
|
28
33
|
const weight = Number.isFinite(arm?.weight) ? Number(arm.weight) : Number.NaN;
|
|
29
34
|
if (!Number.isFinite(weight) || weight <= 0) {
|
|
30
35
|
throw new Error(`arms[${index}].weight must be > 0`);
|
|
@@ -58,6 +63,8 @@ function sanitizeIdentifier(value, field) {
|
|
|
58
63
|
return trimmed;
|
|
59
64
|
}
|
|
60
65
|
function bucketFromHash(hash) {
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
// Keep only 53 high-order bits from the 56-bit hex prefix.
|
|
67
|
+
const first56Bits = parseInt(hash.slice(0, 14), 16);
|
|
68
|
+
const first53Bits = Math.floor(first56Bits / 8);
|
|
69
|
+
return first53Bits / (MAX_UINT53 + 1);
|
|
63
70
|
}
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useorgx/openclaw-plugin",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.16",
|
|
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",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"verify:iwmt-cascade": "npm run build:core && node ./scripts/verify-iwmt-cascade-e2e.mjs",
|
|
53
53
|
"verify:live-ui:p0": "node ./scripts/agent-browser-live-ui-p0-audit.mjs",
|
|
54
54
|
"verify:conduit-mcp": "node ./scripts/verify-conduit-mcp.mjs",
|
|
55
|
+
"verify:repo-hygiene": "node ./scripts/verify-repo-hygiene.mjs",
|
|
55
56
|
"dev:main": "node ./scripts/dev-main-sync.mjs",
|
|
56
57
|
"e2e:auto-continue": "node ./scripts/e2e-auto-continue.mjs",
|
|
57
58
|
"e2e:agent-suite": "npm run build:core && node ./scripts/e2e-agent-suite-kickoff-3x.mjs",
|
|
@@ -94,7 +95,7 @@
|
|
|
94
95
|
},
|
|
95
96
|
"repository": {
|
|
96
97
|
"type": "git",
|
|
97
|
-
"url": "https://github.com/useorgx/openclaw-plugin.git"
|
|
98
|
+
"url": "git+https://github.com/useorgx/openclaw-plugin.git"
|
|
98
99
|
},
|
|
99
100
|
"homepage": "https://useorgx.com",
|
|
100
101
|
"bugs": {
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as c,a as g}from"./cNrhgGc1.js";import{b as m,h as n}from"./Bp3N-QL5.js";function p({authToken:s=null,embedMode:a=!1,enabled:i=!0}={}){var t;const u=c.useMemo(()=>["usage-control-plane",{authToken:s,embedMode:a}],[s,a]),e=g({queryKey:u,enabled:i,queryFn:async()=>{const o=await fetch("/orgx/api/usage/control-plane/summary",{headers:m({authToken:s,embedMode:a})}),r=await o.json().catch(()=>null);if(!o.ok){const l=(r&&typeof r=="object"&&"error"in r&&typeof r.error=="string"?r.error:null)??(r&&typeof r=="object"&&"message"in r&&typeof r.message=="string"?r.message:null)??`Failed to load usage summary (${o.status})`;throw new Error(n(l))}if(!r||typeof r!="object"||!("generatedAt"in r))throw new Error(n("Usage summary response is missing required fields."));return r},refetchInterval:6e4});return{summary:e.data??null,isLoading:e.isLoading,isFetching:e.isFetching,error:((t=e.error)==null?void 0:t.message)??null,refetch:e.refetch}}export{p as u};
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as o,j as e}from"./cNrhgGc1.js";import{e as l,y as p,E as h,_ as u}from"./Bp3N-QL5.js";import{DecisionQueue as b}from"./Dm9AybAp.js";import"./C-KIc3Wc.js";import"./BJgZIVUQ.js";import"./CxQ08qFN.js";import"./CD-q5mdP.js";import"./AqVoI3SF.js";function C({open:n,onClose:a,decisions:t,onApproveDecision:i,onRejectDecision:d,onApproveAll:m,onBulkDecisionAction:x}){const r=o.useMemo(()=>t.length>0?Math.max(0,...t.map(c=>c.waitingMinutes)):0,[t]),s=o.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:a,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:a,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:d,onApproveAll:m,onBulkDecisionAction:x})})]})})}export{C as BulkDecisionsModal};
|
|
Binary file
|
|
Binary file
|