u-foo 1.7.5 → 1.8.0
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 +9 -1
- package/README.zh-CN.md +9 -1
- package/bin/ufoo.js +4 -2
- package/package.json +1 -1
- package/src/agent/cliRunner.js +3 -2
- package/src/agent/ucodeBootstrap.js +5 -3
- package/src/agent/ufooAgent.js +184 -5
- package/src/assistant/constants.js +1 -1
- package/src/chat/commandExecutor.js +98 -3
- package/src/chat/commands.js +7 -0
- package/src/chat/completionController.js +40 -0
- package/src/chat/daemonMessageRouter.js +21 -1
- package/src/chat/dashboardKeyController.js +55 -3
- package/src/chat/dashboardView.js +31 -5
- package/src/chat/index.js +152 -36
- package/src/chat/inputListenerController.js +14 -0
- package/src/chat/inputSubmitHandler.js +9 -5
- package/src/chat/transientAgentState.js +64 -0
- package/src/cli/groupCoreCommands.js +21 -12
- package/src/cli.js +23 -1
- package/src/daemon/groupOrchestrator.js +581 -97
- package/src/daemon/index.js +418 -3
- package/src/daemon/ops.js +25 -7
- package/src/daemon/promptLoop.js +16 -0
- package/src/daemon/promptRequest.js +126 -2
- package/src/daemon/reporting.js +18 -0
- package/src/daemon/soloBootstrap.js +435 -0
- package/src/daemon/status.js +5 -1
- package/src/globalMode.js +33 -0
- package/src/group/bootstrap.js +157 -0
- package/src/group/promptProfiles.js +646 -0
- package/src/group/templateValidation.js +99 -0
- package/src/group/validateTemplate.js +36 -5
- package/src/init/index.js +13 -7
- package/src/report/store.js +6 -0
- package/src/shared/eventContract.js +1 -0
- package/templates/groups/{dev-basic.json → build-lane.json} +38 -34
- package/templates/groups/product-discovery.json +79 -0
- package/templates/groups/ui-polish.json +87 -0
- package/templates/groups/verify-ship.json +79 -0
- package/templates/groups/research-quick.json +0 -49
|
@@ -11,6 +11,7 @@ function createCompletionController(options = {}) {
|
|
|
11
11
|
completionPanel,
|
|
12
12
|
promptBox,
|
|
13
13
|
commandRegistry = [],
|
|
14
|
+
getGroupTemplateCandidates = () => [],
|
|
14
15
|
getMentionCandidates = () => [],
|
|
15
16
|
normalizeCommandPrefix = () => {},
|
|
16
17
|
truncateText = (text) => String(text || ""),
|
|
@@ -141,8 +142,33 @@ function createCompletionController(options = {}) {
|
|
|
141
142
|
const parts = trimmed.split(/\s+/);
|
|
142
143
|
const mainCmd = parts[0];
|
|
143
144
|
const isLaunch = mainCmd && mainCmd.toLowerCase() === "/launch";
|
|
145
|
+
const isGroup = mainCmd && mainCmd.toLowerCase() === "/group";
|
|
144
146
|
const wantsSubcommands = (parts.length > 1 || (endsWithSpace && parts.length === 1));
|
|
145
147
|
|
|
148
|
+
if (isGroup) {
|
|
149
|
+
const groupSubcommand = String(parts[1] || "").trim().toLowerCase();
|
|
150
|
+
const wantsGroupRunArgs = groupSubcommand === "run" && (parts.length > 2 || endsWithSpace);
|
|
151
|
+
if (wantsGroupRunArgs) {
|
|
152
|
+
const aliasFilter = String(parts[2] || "").trim().toLowerCase();
|
|
153
|
+
return (Array.isArray(getGroupTemplateCandidates()) ? getGroupTemplateCandidates() : [])
|
|
154
|
+
.map((item) => {
|
|
155
|
+
const alias = String(item && item.alias ? item.alias : item && item.cmd ? item.cmd : "").trim();
|
|
156
|
+
if (!alias) return null;
|
|
157
|
+
const desc = String(item && item.desc ? item.desc : item && item.name ? item.name : "").trim();
|
|
158
|
+
const source = String(item && item.source ? item.source : "").trim();
|
|
159
|
+
const detail = [desc, source].filter(Boolean).join(" · ");
|
|
160
|
+
return {
|
|
161
|
+
cmd: alias,
|
|
162
|
+
desc: detail,
|
|
163
|
+
isArgumentSuggestion: true,
|
|
164
|
+
argumentPrefix: "/group run",
|
|
165
|
+
};
|
|
166
|
+
})
|
|
167
|
+
.filter((item) => item && (!aliasFilter || item.cmd.toLowerCase().startsWith(aliasFilter)))
|
|
168
|
+
.sort((a, b) => a.cmd.localeCompare(b.cmd, "en", { sensitivity: "base" }));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
146
172
|
if ((wantsSubcommands || isLaunch) && mainCmd && mainCmd.startsWith("/")) {
|
|
147
173
|
const subFilter = parts[1] || "";
|
|
148
174
|
const mainCmdObj = commandRegistry.find((item) =>
|
|
@@ -261,6 +287,13 @@ function createCompletionController(options = {}) {
|
|
|
261
287
|
return { text: `${completedCore} `, isComplete };
|
|
262
288
|
}
|
|
263
289
|
|
|
290
|
+
if (selected.isArgumentSuggestion) {
|
|
291
|
+
const prefix = String(selected.argumentPrefix || "").trim();
|
|
292
|
+
const completedCore = prefix ? `${prefix} ${selected.cmd}` : selected.cmd;
|
|
293
|
+
const isComplete = trimmed === completedCore || trimmed.startsWith(`${completedCore} `);
|
|
294
|
+
return { text: `${completedCore} `, isComplete };
|
|
295
|
+
}
|
|
296
|
+
|
|
264
297
|
const completedCore = selected.cmd;
|
|
265
298
|
const hasChildren = selected.subcommands && selected.subcommands.length > 0;
|
|
266
299
|
const isComplete =
|
|
@@ -291,6 +324,9 @@ function createCompletionController(options = {}) {
|
|
|
291
324
|
const parts = input.value.split(/\s+/);
|
|
292
325
|
parts[parts.length - 1] = selected.cmd;
|
|
293
326
|
input.value = `${parts.join(" ")} `;
|
|
327
|
+
} else if (selected.isArgumentSuggestion) {
|
|
328
|
+
const prefix = String(selected.argumentPrefix || "").trim();
|
|
329
|
+
input.value = prefix ? `${prefix} ${selected.cmd} ` : `${selected.cmd} `;
|
|
294
330
|
} else {
|
|
295
331
|
input.value = `${selected.cmd} `;
|
|
296
332
|
}
|
|
@@ -304,6 +340,8 @@ function createCompletionController(options = {}) {
|
|
|
304
340
|
|
|
305
341
|
if (!selected.isSubcommand && selected.subcommands && selected.subcommands.length > 0) {
|
|
306
342
|
show(input.value);
|
|
343
|
+
} else if (selected.isSubcommand && selected.parentCmd === "/group" && selected.cmd === "run") {
|
|
344
|
+
show(input.value);
|
|
307
345
|
} else {
|
|
308
346
|
hide();
|
|
309
347
|
}
|
|
@@ -346,6 +384,8 @@ function createCompletionController(options = {}) {
|
|
|
346
384
|
applyPreview(nextPreview);
|
|
347
385
|
if (!selected.isSubcommand && selected.subcommands && selected.subcommands.length > 0) {
|
|
348
386
|
show(input.value);
|
|
387
|
+
} else if (selected.isSubcommand && selected.parentCmd === "/group" && selected.cmd === "run") {
|
|
388
|
+
show(input.value);
|
|
349
389
|
} else {
|
|
350
390
|
hide();
|
|
351
391
|
}
|
|
@@ -286,7 +286,14 @@ function createDaemonMessageRouter(options = {}) {
|
|
|
286
286
|
payload.disambiguate.candidates.length > 0
|
|
287
287
|
) {
|
|
288
288
|
const pending = getPending();
|
|
289
|
-
|
|
289
|
+
const routedProjectRoot = payload.routed_project && payload.routed_project.project_root
|
|
290
|
+
? payload.routed_project.project_root
|
|
291
|
+
: (pending && pending.project_root ? pending.project_root : "");
|
|
292
|
+
setPending({
|
|
293
|
+
disambiguate: payload.disambiguate,
|
|
294
|
+
original: pending && pending.original,
|
|
295
|
+
project_root: routedProjectRoot || undefined,
|
|
296
|
+
});
|
|
290
297
|
const prompt = payload.disambiguate.prompt || "Choose target:";
|
|
291
298
|
resolveStatusLine(`{gray-fg}?{/gray-fg} ${escapeBlessed(prompt)}`);
|
|
292
299
|
logMessage("disambiguate", `{white-fg}?{/white-fg} ${escapeBlessed(prompt)}`);
|
|
@@ -323,6 +330,19 @@ function createDaemonMessageRouter(options = {}) {
|
|
|
323
330
|
requestStatus();
|
|
324
331
|
return true;
|
|
325
332
|
}
|
|
333
|
+
if (data.event === "controller_report") {
|
|
334
|
+
const report = data.report && typeof data.report === "object" ? data.report : {};
|
|
335
|
+
const publisher = report.agent_id || data.publisher || "ufoo-agent";
|
|
336
|
+
const displayName = resolveAgentDisplayName(publisher);
|
|
337
|
+
const detail = report.summary || report.message || data.message || report.task_id || "report";
|
|
338
|
+
logMessage(
|
|
339
|
+
"system",
|
|
340
|
+
`{gray-fg}↥{/gray-fg} {cyan-fg}${escapeBlessed(displayName)}{/cyan-fg} {gray-fg}→ ufoo-agent{/gray-fg} ${escapeBlessed(detail)}`
|
|
341
|
+
);
|
|
342
|
+
requestStatus();
|
|
343
|
+
renderScreen();
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
326
346
|
const prefix = data.event === "broadcast" ? "{gray-fg}⇢{/gray-fg}" : "{gray-fg}↔{/gray-fg}";
|
|
327
347
|
const publisher = data.publisher && data.publisher !== "unknown"
|
|
328
348
|
? data.publisher
|
|
@@ -23,6 +23,9 @@ function createDashboardKeyController(options = {}) {
|
|
|
23
23
|
clampAgentWindowWithSelection = () => {},
|
|
24
24
|
requestProjectSwitch = () => {},
|
|
25
25
|
requestCloseProject = () => {},
|
|
26
|
+
requestCron = () => {},
|
|
27
|
+
setGlobalScope = () => {},
|
|
28
|
+
getGlobalScope = () => "",
|
|
26
29
|
renderDashboard = () => {},
|
|
27
30
|
renderAgentDashboard = () => {},
|
|
28
31
|
renderScreen = () => {},
|
|
@@ -232,6 +235,8 @@ function createDashboardKeyController(options = {}) {
|
|
|
232
235
|
|
|
233
236
|
if (key.name === "down") {
|
|
234
237
|
state.dashboardView = "cron";
|
|
238
|
+
const cronTasks = Array.isArray(state.cronTasks) ? state.cronTasks : [];
|
|
239
|
+
state.selectedCronIndex = cronTasks.length > 0 ? 0 : -1;
|
|
235
240
|
renderDashboardAndScreen();
|
|
236
241
|
return true;
|
|
237
242
|
}
|
|
@@ -258,6 +263,25 @@ function createDashboardKeyController(options = {}) {
|
|
|
258
263
|
}
|
|
259
264
|
|
|
260
265
|
function handleCronKey(key) {
|
|
266
|
+
const cronTasks = Array.isArray(state.cronTasks) ? state.cronTasks : [];
|
|
267
|
+
const maxIndex = cronTasks.length - 1;
|
|
268
|
+
|
|
269
|
+
if (key.name === "left") {
|
|
270
|
+
if (maxIndex >= 0 && state.selectedCronIndex > 0) {
|
|
271
|
+
state.selectedCronIndex -= 1;
|
|
272
|
+
renderDashboardAndScreen();
|
|
273
|
+
}
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (key.name === "right") {
|
|
278
|
+
if (maxIndex >= 0 && state.selectedCronIndex < maxIndex) {
|
|
279
|
+
state.selectedCronIndex += 1;
|
|
280
|
+
renderDashboardAndScreen();
|
|
281
|
+
}
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
|
|
261
285
|
if (key.name === "up") {
|
|
262
286
|
state.dashboardView = "provider";
|
|
263
287
|
renderDashboardAndScreen();
|
|
@@ -265,6 +289,14 @@ function createDashboardKeyController(options = {}) {
|
|
|
265
289
|
}
|
|
266
290
|
|
|
267
291
|
if (key.name === "x" && key.ctrl) {
|
|
292
|
+
if (maxIndex >= 0 && state.selectedCronIndex >= 0 && state.selectedCronIndex <= maxIndex) {
|
|
293
|
+
const task = cronTasks[state.selectedCronIndex];
|
|
294
|
+
const id = task && task.id ? String(task.id).trim() : "";
|
|
295
|
+
if (id) {
|
|
296
|
+
requestCron({ operation: "stop", id });
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
268
300
|
exitDashboardMode(false);
|
|
269
301
|
return true;
|
|
270
302
|
}
|
|
@@ -353,7 +385,9 @@ function createDashboardKeyController(options = {}) {
|
|
|
353
385
|
const next = current - 1;
|
|
354
386
|
state.selectedProjectIndex = next;
|
|
355
387
|
renderDashboardAndScreen();
|
|
356
|
-
|
|
388
|
+
if (getGlobalScope() === "project") {
|
|
389
|
+
requestProjectSwitch(next);
|
|
390
|
+
}
|
|
357
391
|
}
|
|
358
392
|
return true;
|
|
359
393
|
}
|
|
@@ -364,17 +398,35 @@ function createDashboardKeyController(options = {}) {
|
|
|
364
398
|
const next = current + 1;
|
|
365
399
|
state.selectedProjectIndex = next;
|
|
366
400
|
renderDashboardAndScreen();
|
|
367
|
-
|
|
401
|
+
if (getGlobalScope() === "project") {
|
|
402
|
+
requestProjectSwitch(next);
|
|
403
|
+
}
|
|
368
404
|
}
|
|
369
405
|
return true;
|
|
370
406
|
}
|
|
371
407
|
|
|
372
|
-
if (key.name === "up"
|
|
408
|
+
if (key.name === "up") {
|
|
409
|
+
exitDashboardMode(false);
|
|
410
|
+
return true;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (key.name === "escape") {
|
|
414
|
+
if (getGlobalScope() === "project") {
|
|
415
|
+
setGlobalScope("controller");
|
|
416
|
+
}
|
|
373
417
|
exitDashboardMode(false);
|
|
374
418
|
return true;
|
|
375
419
|
}
|
|
376
420
|
|
|
377
421
|
if (key.name === "enter" || key.name === "return") {
|
|
422
|
+
const current = Number.isFinite(state.selectedProjectIndex) ? state.selectedProjectIndex : 0;
|
|
423
|
+
if (current >= 0 && current < projects.length) {
|
|
424
|
+
const selectedRow = projects[current];
|
|
425
|
+
const selectedProjectRoot = String((selectedRow && selectedRow.project_root) || "");
|
|
426
|
+
if (selectedProjectRoot) {
|
|
427
|
+
setGlobalScope("project", selectedProjectRoot);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
378
430
|
exitDashboardMode(false);
|
|
379
431
|
return true;
|
|
380
432
|
}
|
|
@@ -36,6 +36,7 @@ function buildSummaryLine(options = {}) {
|
|
|
36
36
|
launchMode = "terminal",
|
|
37
37
|
agentProvider = "codex-cli",
|
|
38
38
|
cronTasks = [],
|
|
39
|
+
pendingReports = 0,
|
|
39
40
|
} = options;
|
|
40
41
|
const agents = activeAgents.length > 0
|
|
41
42
|
? activeAgents.slice(0, 3)
|
|
@@ -46,6 +47,7 @@ function buildSummaryLine(options = {}) {
|
|
|
46
47
|
return `{gray-fg}Agents:{/gray-fg} {cyan-fg}${agents}{/cyan-fg}`
|
|
47
48
|
+ ` {gray-fg}Mode:{/gray-fg} {cyan-fg}${launchMode}{/cyan-fg}`
|
|
48
49
|
+ ` {gray-fg}Agent:{/gray-fg} {cyan-fg}${providerLabel(agentProvider)}{/cyan-fg}`
|
|
50
|
+
+ ` {gray-fg}Reports:{/gray-fg} {cyan-fg}${Number.isFinite(pendingReports) ? pendingReports : 0}{/cyan-fg}`
|
|
49
51
|
+ ` {gray-fg}Cron:{/gray-fg} {cyan-fg}${Array.isArray(cronTasks) ? cronTasks.length : 0}{/cyan-fg}`;
|
|
50
52
|
}
|
|
51
53
|
|
|
@@ -57,6 +59,8 @@ function buildProjectRailLine(options = {}) {
|
|
|
57
59
|
maxProjectWindow = 5,
|
|
58
60
|
activeProjectRoot = "",
|
|
59
61
|
projectsFocused = false,
|
|
62
|
+
globalScope = "",
|
|
63
|
+
dashboardHint = "",
|
|
60
64
|
} = options;
|
|
61
65
|
const rows = Array.isArray(projects) ? projects : [];
|
|
62
66
|
let windowStart = projectListWindowStart;
|
|
@@ -92,7 +96,7 @@ function buildProjectRailLine(options = {}) {
|
|
|
92
96
|
const absoluteIndex = start + i;
|
|
93
97
|
const name = String((row && row.project_name) || (row && row.project_root) || "-");
|
|
94
98
|
const rowRoot = String((row && row.project_root) || "");
|
|
95
|
-
const isActiveProject = Boolean(activeRoot && rowRoot === activeRoot);
|
|
99
|
+
const isActiveProject = globalScope !== "controller" && Boolean(activeRoot && rowRoot === activeRoot);
|
|
96
100
|
const isSelected = absoluteIndex === safeSelectedIndex;
|
|
97
101
|
if (projectsFocused && isSelected) {
|
|
98
102
|
return `{inverse}${name}{/inverse}`;
|
|
@@ -105,9 +109,10 @@ function buildProjectRailLine(options = {}) {
|
|
|
105
109
|
|
|
106
110
|
const leftMore = start > 0 ? "{gray-fg}<{/gray-fg} " : "";
|
|
107
111
|
const rightMore = end < rows.length ? " {gray-fg}>{/gray-fg}" : "";
|
|
112
|
+
const hintPart = dashboardHint ? `{|}{gray-fg}${dashboardHint}{/gray-fg}` : "";
|
|
108
113
|
return {
|
|
109
114
|
hasProjects: true,
|
|
110
|
-
line: ` {gray-fg}Projects:{/gray-fg} ${leftMore}${projectParts.join(" ")}${rightMore}`,
|
|
115
|
+
line: ` {gray-fg}Projects:{/gray-fg} ${leftMore}${projectParts.join(" ")}${rightMore}${hintPart}`,
|
|
111
116
|
windowStart,
|
|
112
117
|
};
|
|
113
118
|
}
|
|
@@ -125,7 +130,9 @@ function buildDashboardDetailLine(options = {}) {
|
|
|
125
130
|
selectedModeIndex = 0,
|
|
126
131
|
selectedProviderIndex = 0,
|
|
127
132
|
selectedResumeIndex = 0,
|
|
133
|
+
selectedCronIndex = -1,
|
|
128
134
|
cronTasks = [],
|
|
135
|
+
pendingReports = 0,
|
|
129
136
|
providerOptions = [],
|
|
130
137
|
resumeOptions = [],
|
|
131
138
|
dashHints = {},
|
|
@@ -174,9 +181,15 @@ function buildDashboardDetailLine(options = {}) {
|
|
|
174
181
|
if (dashboardView === "cron") {
|
|
175
182
|
const items = Array.isArray(cronTasks) ? cronTasks : [];
|
|
176
183
|
const summary = items.length > 0
|
|
177
|
-
? items.map((item) =>
|
|
178
|
-
|
|
179
|
-
|
|
184
|
+
? items.map((item, index) => {
|
|
185
|
+
const label = item.label || item.summary || item.id || "";
|
|
186
|
+
if (!label) return "";
|
|
187
|
+
return index === selectedCronIndex
|
|
188
|
+
? `{inverse}${label}{/inverse}`
|
|
189
|
+
: `{cyan-fg}${label}{/cyan-fg}`;
|
|
190
|
+
}).filter(Boolean).join(", ")
|
|
191
|
+
: "{cyan-fg}none{/cyan-fg}";
|
|
192
|
+
content += `{gray-fg}Cron:{/gray-fg} ${summary}`;
|
|
180
193
|
content += ` {gray-fg}│ ${dashHints.cron || ""}{/gray-fg}`;
|
|
181
194
|
return { content, windowStart };
|
|
182
195
|
}
|
|
@@ -220,6 +233,7 @@ function buildDashboardDetailLine(options = {}) {
|
|
|
220
233
|
function computeDashboardContent(options = {}) {
|
|
221
234
|
const {
|
|
222
235
|
globalMode = false,
|
|
236
|
+
globalScope = "controller",
|
|
223
237
|
focusMode = "input",
|
|
224
238
|
dashboardView = "agents",
|
|
225
239
|
activeAgents = [],
|
|
@@ -238,7 +252,9 @@ function computeDashboardContent(options = {}) {
|
|
|
238
252
|
selectedModeIndex = 0,
|
|
239
253
|
selectedProviderIndex = 0,
|
|
240
254
|
selectedResumeIndex = 0,
|
|
255
|
+
selectedCronIndex = -1,
|
|
241
256
|
cronTasks = [],
|
|
257
|
+
pendingReports = 0,
|
|
242
258
|
providerOptions = [],
|
|
243
259
|
resumeOptions = [],
|
|
244
260
|
dashHints = {},
|
|
@@ -247,6 +263,10 @@ function computeDashboardContent(options = {}) {
|
|
|
247
263
|
|
|
248
264
|
if (globalMode) {
|
|
249
265
|
const projectsFocused = focusMode === "dashboard" && dashboardView === "projects";
|
|
266
|
+
let dashboardHint = "";
|
|
267
|
+
if (projectsFocused) {
|
|
268
|
+
dashboardHint = globalScope === "controller" ? "Enter\u2192project" : "Esc\u2192global";
|
|
269
|
+
}
|
|
250
270
|
const rail = buildProjectRailLine({
|
|
251
271
|
projects,
|
|
252
272
|
selectedProjectIndex,
|
|
@@ -254,6 +274,8 @@ function computeDashboardContent(options = {}) {
|
|
|
254
274
|
maxProjectWindow,
|
|
255
275
|
activeProjectRoot,
|
|
256
276
|
projectsFocused,
|
|
277
|
+
globalScope,
|
|
278
|
+
dashboardHint,
|
|
257
279
|
});
|
|
258
280
|
if (!rail.hasProjects) {
|
|
259
281
|
const line2 = ` {gray-fg}${dashHints.projectsEmpty || "Run ufoo chat/daemon in projects to populate registry"}{/gray-fg}`;
|
|
@@ -271,6 +293,7 @@ function computeDashboardContent(options = {}) {
|
|
|
271
293
|
launchMode,
|
|
272
294
|
agentProvider,
|
|
273
295
|
cronTasks,
|
|
296
|
+
pendingReports,
|
|
274
297
|
});
|
|
275
298
|
return {
|
|
276
299
|
content: `${rail.line}\n ${line2}`,
|
|
@@ -290,6 +313,7 @@ function computeDashboardContent(options = {}) {
|
|
|
290
313
|
selectedModeIndex,
|
|
291
314
|
selectedProviderIndex,
|
|
292
315
|
selectedResumeIndex,
|
|
316
|
+
selectedCronIndex,
|
|
293
317
|
cronTasks,
|
|
294
318
|
providerOptions,
|
|
295
319
|
resumeOptions,
|
|
@@ -315,6 +339,7 @@ function computeDashboardContent(options = {}) {
|
|
|
315
339
|
selectedModeIndex,
|
|
316
340
|
selectedProviderIndex,
|
|
317
341
|
selectedResumeIndex,
|
|
342
|
+
selectedCronIndex,
|
|
318
343
|
cronTasks,
|
|
319
344
|
providerOptions,
|
|
320
345
|
resumeOptions,
|
|
@@ -331,6 +356,7 @@ function computeDashboardContent(options = {}) {
|
|
|
331
356
|
launchMode,
|
|
332
357
|
agentProvider,
|
|
333
358
|
cronTasks,
|
|
359
|
+
pendingReports,
|
|
334
360
|
});
|
|
335
361
|
|
|
336
362
|
return { content, windowStart: agentListWindowStart };
|