@useorgx/openclaw-plugin 0.7.15 → 0.7.17
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/{CFZ4Swr5.js → 05zHA1Am.js} +1 -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 +1 -0
- package/dashboard/dist/assets/0uYJrBLl.js.br +0 -0
- package/dashboard/dist/assets/0uYJrBLl.js.gz +0 -0
- package/dashboard/dist/assets/8nr6IqT4.js +1 -0
- package/dashboard/dist/assets/8nr6IqT4.js.br +0 -0
- package/dashboard/dist/assets/8nr6IqT4.js.gz +0 -0
- package/dashboard/dist/assets/{3VwNyxUf.js → B7kFLPiD.js} +1 -1
- package/dashboard/dist/assets/B7kFLPiD.js.br +0 -0
- package/dashboard/dist/assets/B7kFLPiD.js.gz +0 -0
- package/dashboard/dist/assets/{3TtV4moZ.js → B8NuBCcY.js} +1 -1
- package/dashboard/dist/assets/B8NuBCcY.js.br +0 -0
- package/dashboard/dist/assets/B8NuBCcY.js.gz +0 -0
- package/dashboard/dist/assets/{CnPC783_.js → BDlKSbsp.js} +1 -1
- package/dashboard/dist/assets/BDlKSbsp.js.br +0 -0
- package/dashboard/dist/assets/BDlKSbsp.js.gz +0 -0
- package/dashboard/dist/assets/C8AYbjlq.js +212 -0
- package/dashboard/dist/assets/C8AYbjlq.js.br +0 -0
- package/dashboard/dist/assets/C8AYbjlq.js.gz +0 -0
- package/dashboard/dist/assets/CMir7ekf.js +1 -0
- package/dashboard/dist/assets/CMir7ekf.js.br +0 -0
- package/dashboard/dist/assets/CMir7ekf.js.gz +0 -0
- package/dashboard/dist/assets/{CKrH5fYO.js → CWXk6UZl.js} +1 -1
- package/dashboard/dist/assets/CWXk6UZl.js.br +0 -0
- package/dashboard/dist/assets/CWXk6UZl.js.gz +0 -0
- package/dashboard/dist/assets/{Ctw95IkC.js → CoDun8X6.js} +1 -1
- package/dashboard/dist/assets/CoDun8X6.js.br +0 -0
- package/dashboard/dist/assets/CoDun8X6.js.gz +0 -0
- package/dashboard/dist/assets/{7DhYqBrM.js → Crj3jKHE.js} +1 -1
- package/dashboard/dist/assets/Crj3jKHE.js.br +0 -0
- package/dashboard/dist/assets/Crj3jKHE.js.gz +0 -0
- package/dashboard/dist/assets/{T2NFtzAv.js → CyUpNSKv.js} +1 -1
- package/dashboard/dist/assets/CyUpNSKv.js.br +0 -0
- package/dashboard/dist/assets/CyUpNSKv.js.gz +0 -0
- package/dashboard/dist/assets/{C9fvfXmS.js → D8mvKY2h.js} +1 -1
- package/dashboard/dist/assets/D8mvKY2h.js.br +0 -0
- package/dashboard/dist/assets/D8mvKY2h.js.gz +0 -0
- package/dashboard/dist/assets/{C91KLKit.js → DBRLnKWw.js} +1 -1
- package/dashboard/dist/assets/DBRLnKWw.js.br +0 -0
- package/dashboard/dist/assets/DBRLnKWw.js.gz +0 -0
- package/dashboard/dist/assets/DBct8HLW.js +1 -0
- package/dashboard/dist/assets/DBct8HLW.js.br +0 -0
- package/dashboard/dist/assets/DBct8HLW.js.gz +0 -0
- package/dashboard/dist/assets/{gZr_xKlA.js → DLNTxNX-.js} +1 -1
- package/dashboard/dist/assets/DLNTxNX-.js.br +0 -0
- package/dashboard/dist/assets/DLNTxNX-.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/{CJjEAGFN.js → DdYkuATV.js} +1 -1
- package/dashboard/dist/assets/DdYkuATV.js.br +0 -0
- package/dashboard/dist/assets/DdYkuATV.js.gz +0 -0
- package/dashboard/dist/assets/{CGj8kRhg.js → DvFumX8R.js} +1 -1
- package/dashboard/dist/assets/DvFumX8R.js.br +0 -0
- package/dashboard/dist/assets/DvFumX8R.js.gz +0 -0
- package/dashboard/dist/assets/RZkbqlJk.css +1 -0
- package/dashboard/dist/assets/RZkbqlJk.css.br +0 -0
- package/dashboard/dist/assets/RZkbqlJk.css.gz +0 -0
- package/dashboard/dist/index.html +3 -3
- 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 +15 -0
- package/dist/http/helpers/auto-continue-engine.js +165 -0
- package/dist/http/helpers/mission-control.d.ts +3 -0
- package/dist/http/helpers/mission-control.js +38 -7
- package/dist/http/helpers/value-utils.d.ts +1 -1
- package/dist/http/helpers/value-utils.js +5 -2
- package/dist/http/index.js +3 -1
- package/dist/http/routes/chat.d.ts +1 -1
- package/dist/http/routes/chat.js +2 -2
- 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 +11 -3
- package/dist/http/routes/mission-control-actions.d.ts +6 -0
- package/dist/http/routes/mission-control-actions.js +33 -0
- package/package.json +1 -1
- package/dashboard/dist/assets/0RUEVzJa.js +0 -1
- package/dashboard/dist/assets/0RUEVzJa.js.br +0 -0
- package/dashboard/dist/assets/0RUEVzJa.js.gz +0 -0
- package/dashboard/dist/assets/3TtV4moZ.js.br +0 -0
- package/dashboard/dist/assets/3TtV4moZ.js.gz +0 -0
- package/dashboard/dist/assets/3VwNyxUf.js.br +0 -0
- package/dashboard/dist/assets/3VwNyxUf.js.gz +0 -0
- package/dashboard/dist/assets/7DhYqBrM.js.br +0 -0
- package/dashboard/dist/assets/7DhYqBrM.js.gz +0 -0
- package/dashboard/dist/assets/BVvffj0x.js +0 -1
- package/dashboard/dist/assets/BVvffj0x.js.br +0 -0
- package/dashboard/dist/assets/BVvffj0x.js.gz +0 -0
- package/dashboard/dist/assets/BiOgVMED.js +0 -1
- package/dashboard/dist/assets/BiOgVMED.js.br +0 -0
- package/dashboard/dist/assets/BiOgVMED.js.gz +0 -0
- package/dashboard/dist/assets/C91KLKit.js.br +0 -0
- package/dashboard/dist/assets/C91KLKit.js.gz +0 -0
- package/dashboard/dist/assets/C9fvfXmS.js.br +0 -0
- package/dashboard/dist/assets/C9fvfXmS.js.gz +0 -0
- package/dashboard/dist/assets/CFZ4Swr5.js.br +0 -0
- package/dashboard/dist/assets/CFZ4Swr5.js.gz +0 -0
- package/dashboard/dist/assets/CGj8kRhg.js.br +0 -0
- package/dashboard/dist/assets/CGj8kRhg.js.gz +0 -0
- package/dashboard/dist/assets/CJjEAGFN.js.br +0 -0
- package/dashboard/dist/assets/CJjEAGFN.js.gz +0 -0
- package/dashboard/dist/assets/CKrH5fYO.js.br +0 -0
- package/dashboard/dist/assets/CKrH5fYO.js.gz +0 -0
- package/dashboard/dist/assets/CMTTPXch.js +0 -1
- package/dashboard/dist/assets/CMTTPXch.js.br +0 -0
- package/dashboard/dist/assets/CMTTPXch.js.gz +0 -0
- package/dashboard/dist/assets/CnPC783_.js.br +0 -0
- package/dashboard/dist/assets/CnPC783_.js.gz +0 -0
- package/dashboard/dist/assets/Ctw95IkC.js.br +0 -0
- package/dashboard/dist/assets/Ctw95IkC.js.gz +0 -0
- package/dashboard/dist/assets/DHz-aQPw.js +0 -1
- package/dashboard/dist/assets/DHz-aQPw.js.br +0 -0
- package/dashboard/dist/assets/DHz-aQPw.js.gz +0 -0
- package/dashboard/dist/assets/DNX2foSJ.css +0 -1
- package/dashboard/dist/assets/DNX2foSJ.css.br +0 -0
- package/dashboard/dist/assets/DNX2foSJ.css.gz +0 -0
- package/dashboard/dist/assets/DxUw4FMR.js +0 -212
- package/dashboard/dist/assets/DxUw4FMR.js.br +0 -0
- package/dashboard/dist/assets/DxUw4FMR.js.gz +0 -0
- package/dashboard/dist/assets/T2NFtzAv.js.br +0 -0
- package/dashboard/dist/assets/T2NFtzAv.js.gz +0 -0
- package/dashboard/dist/assets/gZr_xKlA.js.br +0 -0
- package/dashboard/dist/assets/gZr_xKlA.js.gz +0 -0
|
@@ -48,7 +48,7 @@ export function toIsoString(value) {
|
|
|
48
48
|
return null;
|
|
49
49
|
return new Date(parsed).toISOString();
|
|
50
50
|
}
|
|
51
|
-
export function parsePositiveInt(raw, fallback) {
|
|
51
|
+
export function parsePositiveInt(raw, fallback, max = Number.POSITIVE_INFINITY) {
|
|
52
52
|
if (!raw)
|
|
53
53
|
return fallback;
|
|
54
54
|
const normalized = raw.trim();
|
|
@@ -59,7 +59,10 @@ export function parsePositiveInt(raw, fallback) {
|
|
|
59
59
|
return fallback;
|
|
60
60
|
// Offset-like parameters may intentionally allow zero when fallback is zero.
|
|
61
61
|
const minimum = fallback <= 0 ? 0 : 1;
|
|
62
|
-
|
|
62
|
+
const clamped = Math.max(minimum, Math.floor(parsed));
|
|
63
|
+
if (!Number.isFinite(max))
|
|
64
|
+
return clamped;
|
|
65
|
+
return Math.min(clamped, Math.max(minimum, Math.floor(max)));
|
|
63
66
|
}
|
|
64
67
|
export function parseBooleanQuery(raw) {
|
|
65
68
|
if (!raw)
|
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, } = 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, skipCurrentWorkstream, getCanonicalAutopilotState, } = createAutoContinueEngine({
|
|
1850
1850
|
client,
|
|
1851
1851
|
filename: __filename,
|
|
1852
1852
|
safeErrorMessage,
|
|
@@ -3417,6 +3417,7 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
3417
3417
|
dispatchFallbackWorkstreamTurn,
|
|
3418
3418
|
tickAutoContinueRun,
|
|
3419
3419
|
stopAutoContinueRun,
|
|
3420
|
+
skipCurrentWorkstream,
|
|
3420
3421
|
updateInitiativeAutoContinueState,
|
|
3421
3422
|
tickAllAutoContinue,
|
|
3422
3423
|
scheduleAutoFixForWorkstream,
|
|
@@ -3592,6 +3593,7 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
3592
3593
|
},
|
|
3593
3594
|
runAction: (runId, action, input) => client.runAction(runId, action, input),
|
|
3594
3595
|
listChatThreads: ({ commandCenterId, initiativeId, limit, offset }) => listChatThreads({ commandCenterId, initiativeId, limit, offset }),
|
|
3596
|
+
getCanonicalAutopilotState,
|
|
3595
3597
|
sendJson,
|
|
3596
3598
|
});
|
|
3597
3599
|
registerRuntimeHookRoutes(apiRouter, {
|
|
@@ -3,7 +3,7 @@ type JsonRecord = Record<string, unknown>;
|
|
|
3
3
|
type RegisterChatRoutesDeps<TReq, TRes> = {
|
|
4
4
|
parseJsonRequest: (req: TReq) => Promise<JsonRecord>;
|
|
5
5
|
pickString: (input: Record<string, unknown>, keys: string[]) => string | null;
|
|
6
|
-
parsePositiveInt: (raw: string | null, fallback: number) => number;
|
|
6
|
+
parsePositiveInt: (raw: string | null, fallback: number, max?: number) => number;
|
|
7
7
|
emitActivitySafe?: (input: {
|
|
8
8
|
initiativeId: string | null;
|
|
9
9
|
sourceClient?: string;
|
package/dist/http/routes/chat.js
CHANGED
|
@@ -161,8 +161,8 @@ export function registerChatRoutes(router, deps) {
|
|
|
161
161
|
const initiativeId = query.get("initiative_id") ?? query.get("initiative");
|
|
162
162
|
const searchQuery = query.get("query") ?? query.get("q");
|
|
163
163
|
const status = query.get("status");
|
|
164
|
-
const limit = deps.parsePositiveInt(query.get("limit"), 60);
|
|
165
|
-
const offset = deps.parsePositiveInt(query.get("offset"), 0);
|
|
164
|
+
const limit = deps.parsePositiveInt(query.get("limit"), 60, 200);
|
|
165
|
+
const offset = deps.parsePositiveInt(query.get("offset"), 0, 10000);
|
|
166
166
|
sendThreadList(deps, res, {
|
|
167
167
|
commandCenterId: commandCenterId?.trim() ?? null,
|
|
168
168
|
initiativeId: initiativeId?.trim() ?? null,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolveWorkspaceScope, workspaceScopeFromHeaders, } from "../helpers/workspace-scope.js";
|
|
2
|
+
import { deriveInitiativeLifecycleStatus } from "../helpers/mission-control.js";
|
|
2
3
|
const WORKSTREAM_REASSIGNMENT_FIELDS = [
|
|
3
4
|
"domain",
|
|
4
5
|
"role",
|
|
@@ -38,6 +39,59 @@ function toObjectArray(input) {
|
|
|
38
39
|
return [];
|
|
39
40
|
return input.filter((item) => Boolean(item) && typeof item === "object");
|
|
40
41
|
}
|
|
42
|
+
async function reconcileInitiativeStatusesFromWorkstreams(deps, rows, input) {
|
|
43
|
+
if (rows.length === 0)
|
|
44
|
+
return rows;
|
|
45
|
+
const initiativeIds = new Set(rows
|
|
46
|
+
.map((row) => deps.pickString(row, ["id"]))
|
|
47
|
+
.filter((value) => Boolean(value)));
|
|
48
|
+
if (initiativeIds.size === 0)
|
|
49
|
+
return rows;
|
|
50
|
+
const scopedInitiativeId = input.initiativeId?.trim() ?? "";
|
|
51
|
+
const scopedWorkspaceId = input.workspaceId?.trim() ?? "";
|
|
52
|
+
if (!scopedInitiativeId && !scopedWorkspaceId) {
|
|
53
|
+
// Avoid unscoped global workstream scans.
|
|
54
|
+
return rows;
|
|
55
|
+
}
|
|
56
|
+
const filters = { limit: 2000 };
|
|
57
|
+
if (scopedInitiativeId) {
|
|
58
|
+
filters.initiative_id = scopedInitiativeId;
|
|
59
|
+
}
|
|
60
|
+
if (scopedWorkspaceId) {
|
|
61
|
+
filters.workspace_id = scopedWorkspaceId;
|
|
62
|
+
filters.command_center_id = scopedWorkspaceId;
|
|
63
|
+
}
|
|
64
|
+
const response = await deps.client.listEntities("workstream", filters);
|
|
65
|
+
const workstreamRows = toObjectArray(response && typeof response === "object"
|
|
66
|
+
? response.data
|
|
67
|
+
: []);
|
|
68
|
+
const childStatusesByInitiative = new Map();
|
|
69
|
+
for (const workstreamRow of workstreamRows) {
|
|
70
|
+
const initiativeId = deps.pickString(workstreamRow, ["initiative_id", "initiativeId"]);
|
|
71
|
+
if (!initiativeId || !initiativeIds.has(initiativeId))
|
|
72
|
+
continue;
|
|
73
|
+
const status = deps.pickString(workstreamRow, ["status"]) ?? "todo";
|
|
74
|
+
const statuses = childStatusesByInitiative.get(initiativeId) ?? [];
|
|
75
|
+
statuses.push(status);
|
|
76
|
+
childStatusesByInitiative.set(initiativeId, statuses);
|
|
77
|
+
}
|
|
78
|
+
return rows.map((row) => {
|
|
79
|
+
const initiativeId = deps.pickString(row, ["id"]);
|
|
80
|
+
const status = deps.pickString(row, ["status"]);
|
|
81
|
+
if (!initiativeId || !status)
|
|
82
|
+
return row;
|
|
83
|
+
const childStatuses = childStatusesByInitiative.get(initiativeId) ?? [];
|
|
84
|
+
if (childStatuses.length === 0)
|
|
85
|
+
return row;
|
|
86
|
+
const normalized = deriveInitiativeLifecycleStatus(status, childStatuses);
|
|
87
|
+
if (normalized === status)
|
|
88
|
+
return row;
|
|
89
|
+
return {
|
|
90
|
+
...row,
|
|
91
|
+
status: normalized,
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
}
|
|
41
95
|
export function registerEntitiesRoutes(router, deps) {
|
|
42
96
|
router.add("POST", "entities", async ({ req, res }) => {
|
|
43
97
|
try {
|
|
@@ -305,13 +359,17 @@ export function registerEntitiesRoutes(router, deps) {
|
|
|
305
359
|
return rowScope.trim() === workspaceScopeId;
|
|
306
360
|
})
|
|
307
361
|
: searchedRows;
|
|
362
|
+
const reconciledRows = await reconcileInitiativeStatusesFromWorkstreams(deps, rows, {
|
|
363
|
+
initiativeId: id,
|
|
364
|
+
workspaceId: workspaceScopeId,
|
|
365
|
+
}).catch(() => rows);
|
|
308
366
|
deps.sendJson(res, 200, {
|
|
309
367
|
...payload,
|
|
310
|
-
data: deps.applyLocalInitiativeOverrides(
|
|
368
|
+
data: deps.applyLocalInitiativeOverrides(reconciledRows),
|
|
311
369
|
pagination: payload.pagination && typeof payload.pagination === "object"
|
|
312
370
|
? {
|
|
313
371
|
...payload.pagination,
|
|
314
|
-
total:
|
|
372
|
+
total: reconciledRows.length,
|
|
315
373
|
}
|
|
316
374
|
: payload.pagination,
|
|
317
375
|
});
|
|
@@ -1,3 +1,51 @@
|
|
|
1
|
+
function resolveEntityActionStatus(entityType, entityAction) {
|
|
2
|
+
const normalizedType = entityType.trim().toLowerCase();
|
|
3
|
+
const normalizedAction = entityAction.trim().toLowerCase();
|
|
4
|
+
const defaultStatusMap = {
|
|
5
|
+
start: "in_progress",
|
|
6
|
+
complete: "done",
|
|
7
|
+
block: "blocked",
|
|
8
|
+
unblock: "in_progress",
|
|
9
|
+
pause: "paused",
|
|
10
|
+
resume: "active",
|
|
11
|
+
};
|
|
12
|
+
const statusMapByEntityType = {
|
|
13
|
+
initiative: {
|
|
14
|
+
start: "active",
|
|
15
|
+
complete: "completed",
|
|
16
|
+
block: "blocked",
|
|
17
|
+
unblock: "active",
|
|
18
|
+
pause: "paused",
|
|
19
|
+
resume: "active",
|
|
20
|
+
},
|
|
21
|
+
workstream: {
|
|
22
|
+
start: "active",
|
|
23
|
+
complete: "completed",
|
|
24
|
+
block: "blocked",
|
|
25
|
+
unblock: "active",
|
|
26
|
+
pause: "paused",
|
|
27
|
+
resume: "active",
|
|
28
|
+
},
|
|
29
|
+
milestone: {
|
|
30
|
+
start: "in_progress",
|
|
31
|
+
complete: "completed",
|
|
32
|
+
block: "at_risk",
|
|
33
|
+
unblock: "in_progress",
|
|
34
|
+
pause: "planned",
|
|
35
|
+
resume: "in_progress",
|
|
36
|
+
},
|
|
37
|
+
task: {
|
|
38
|
+
start: "in_progress",
|
|
39
|
+
complete: "done",
|
|
40
|
+
block: "blocked",
|
|
41
|
+
unblock: "in_progress",
|
|
42
|
+
pause: "todo",
|
|
43
|
+
resume: "in_progress",
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
const map = statusMapByEntityType[normalizedType] ?? defaultStatusMap;
|
|
47
|
+
return map[normalizedAction] ?? null;
|
|
48
|
+
}
|
|
1
49
|
export function registerEntityDynamicRoutes(router, deps) {
|
|
2
50
|
router.add("*", "entities/*", async ({ req, res, path }) => {
|
|
3
51
|
const method = (req.method ?? "GET").toUpperCase();
|
|
@@ -137,15 +185,7 @@ export function registerEntityDynamicRoutes(router, deps) {
|
|
|
137
185
|
}
|
|
138
186
|
return;
|
|
139
187
|
}
|
|
140
|
-
const
|
|
141
|
-
start: "in_progress",
|
|
142
|
-
complete: "done",
|
|
143
|
-
block: "blocked",
|
|
144
|
-
unblock: "in_progress",
|
|
145
|
-
pause: "paused",
|
|
146
|
-
resume: "active",
|
|
147
|
-
};
|
|
148
|
-
const newStatus = statusMap[entityAction];
|
|
188
|
+
const newStatus = resolveEntityActionStatus(entityType, entityAction);
|
|
149
189
|
if (!newStatus) {
|
|
150
190
|
deps.sendJson(res, 400, {
|
|
151
191
|
error: `Unknown entity action: ${entityAction}`,
|
|
@@ -14,7 +14,7 @@ type SnapshotPersistState = {
|
|
|
14
14
|
lastPersistAt: number;
|
|
15
15
|
};
|
|
16
16
|
type LiveSnapshotRoutesDeps<TReq, TRes> = {
|
|
17
|
-
parsePositiveInt: (raw: string | null, fallback: number) => number;
|
|
17
|
+
parsePositiveInt: (raw: string | null, fallback: number, max?: number) => number;
|
|
18
18
|
readSnapshotResponseCache: (key: string) => Record<string, unknown> | null;
|
|
19
19
|
writeSnapshotResponseCache: (key: string, payload: Record<string, unknown>) => void;
|
|
20
20
|
safeErrorMessage: (err: unknown) => string;
|
|
@@ -131,6 +131,15 @@ type LiveSnapshotRoutesDeps<TReq, TRes> = {
|
|
|
131
131
|
total: number;
|
|
132
132
|
updatedAt: string;
|
|
133
133
|
};
|
|
134
|
+
getCanonicalAutopilotState?: (initiativeId: string) => {
|
|
135
|
+
state: "idle" | "running" | "blocked" | "stopping";
|
|
136
|
+
reason: string | null;
|
|
137
|
+
activeRunId: string | null;
|
|
138
|
+
activeWorkstreamId: string | null;
|
|
139
|
+
activeWorkstreamTitle: string | null;
|
|
140
|
+
queueHeadTitle: string | null;
|
|
141
|
+
lastTransitionAt: string;
|
|
142
|
+
} | null;
|
|
134
143
|
sendJson: (res: TRes, status: number, payload: unknown) => void;
|
|
135
144
|
};
|
|
136
145
|
export declare function registerLiveSnapshotRoutes<TReq, TRes>(router: Router<Record<string, never>, TReq, TRes>, deps: LiveSnapshotRoutesDeps<TReq, TRes>): void;
|
|
@@ -231,9 +231,9 @@ export function registerLiveSnapshotRoutes(router, deps) {
|
|
|
231
231
|
};
|
|
232
232
|
const headerScopeFromRequest = (req) => workspaceScopeFromHeaders(req?.headers);
|
|
233
233
|
function parseSnapshotQuery(query, headerScope) {
|
|
234
|
-
const sessionsLimit = deps.parsePositiveInt(query.get("sessionsLimit") ?? query.get("sessions_limit"), 320);
|
|
235
|
-
const activityLimit = deps.parsePositiveInt(query.get("activityLimit") ?? query.get("activity_limit"), 600);
|
|
236
|
-
const decisionsLimit = deps.parsePositiveInt(query.get("decisionsLimit") ?? query.get("decisions_limit"), 120);
|
|
234
|
+
const sessionsLimit = deps.parsePositiveInt(query.get("sessionsLimit") ?? query.get("sessions_limit"), 320, 1000);
|
|
235
|
+
const activityLimit = deps.parsePositiveInt(query.get("activityLimit") ?? query.get("activity_limit"), 600, 2000);
|
|
236
|
+
const decisionsLimit = deps.parsePositiveInt(query.get("decisionsLimit") ?? query.get("decisions_limit"), 120, 500);
|
|
237
237
|
const initiative = query.get("initiative");
|
|
238
238
|
const scope = resolveWorkspaceScope(query, headerScope, {
|
|
239
239
|
allowProjectScope: false,
|
|
@@ -523,6 +523,14 @@ export function registerLiveSnapshotRoutes(router, deps) {
|
|
|
523
523
|
projectId,
|
|
524
524
|
degraded: degraded.length > 0 ? degraded : undefined,
|
|
525
525
|
};
|
|
526
|
+
if (typeof deps.getCanonicalAutopilotState === "function" && initiative) {
|
|
527
|
+
try {
|
|
528
|
+
payload.autopilot = deps.getCanonicalAutopilotState(initiative) ?? null;
|
|
529
|
+
}
|
|
530
|
+
catch {
|
|
531
|
+
// best effort
|
|
532
|
+
}
|
|
533
|
+
}
|
|
526
534
|
if (typeof deps.listChatThreads === "function") {
|
|
527
535
|
try {
|
|
528
536
|
const listed = deps.listChatThreads({
|
|
@@ -66,6 +66,12 @@ type RegisterMissionControlActionsRoutesDeps<TReq, TRes> = {
|
|
|
66
66
|
}>;
|
|
67
67
|
tickAutoContinueRun: (run: any) => Promise<void>;
|
|
68
68
|
stopAutoContinueRun: (input: any) => Promise<void>;
|
|
69
|
+
skipCurrentWorkstream: (initiativeId: string, workstreamId: string, reason?: string) => Promise<{
|
|
70
|
+
ok: boolean;
|
|
71
|
+
skippedWorkstreamId: string;
|
|
72
|
+
nextWorkstreamId?: string;
|
|
73
|
+
nextWorkstreamTitle?: string;
|
|
74
|
+
}>;
|
|
69
75
|
updateInitiativeAutoContinueState: (input: any) => Promise<void>;
|
|
70
76
|
tickAllAutoContinue: () => Promise<void>;
|
|
71
77
|
scheduleAutoFixForWorkstream: (input: {
|
|
@@ -1636,6 +1636,39 @@ export function registerMissionControlActionsRoutes(router, deps) {
|
|
|
1636
1636
|
sendRouteException(res, "mission-control.auto-continue.stop.handler", err);
|
|
1637
1637
|
}
|
|
1638
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");
|
|
1639
1672
|
router.add("POST", "mission-control/auto-continue/tick", async ({ req, query, res }) => {
|
|
1640
1673
|
try {
|
|
1641
1674
|
const payload = await deps.parseJsonRequest(req);
|
package/package.json
CHANGED