feat: add mdtodo web-probe commands
This commit is contained in:
@@ -1019,6 +1019,17 @@ function buildProjectManagementReport(samples, control, network, pagePerformance
|
||||
const launchEnabledSamples = projectSamples.filter((sample) => sample.projectManagement?.launchButtonEnabled === true);
|
||||
const launchVisibleSamples = projectSamples.filter((sample) => sample.projectManagement?.launchButtonVisible === true);
|
||||
const mdtodoSamples = projectSamples.filter((sample) => sample.projectManagement?.pageKind === "project-management-mdtodo");
|
||||
const selectedFileLabelBadSamples = projectSamples.filter((sample) => sample.projectManagement?.selectedFileLabel && sample.projectManagement?.selectedFileLabelLooksDirect === false);
|
||||
const suspiciousFileLabelSamples = projectSamples.filter((sample) => Number(sample.projectManagement?.fileOptionSuspiciousLabelCount ?? 0) > 0);
|
||||
const bodyVisibleSamples = selectedTaskSamples.filter((sample) => sample.projectManagement?.taskBodyVisible === true && Number(sample.projectManagement?.taskBody?.textBytes ?? 0) > 0);
|
||||
const reportLinkSamples = projectSamples.filter((sample) => Number(sample.projectManagement?.reportLinkCount ?? 0) > 0);
|
||||
const reportPreviewSamples = projectSamples.filter((sample) => sample.projectManagement?.reportPreviewVisible === true && Number(sample.projectManagement?.reportPreview?.textBytes ?? 0) > 0);
|
||||
const reportFullscreenSamples = projectSamples.filter((sample) => sample.projectManagement?.reportFullscreenVisible === true);
|
||||
const previewCommands = commandRows.filter((item) => item.type === "openMdtodoReportPreview" || item.type === "toggleMdtodoReportFullscreen");
|
||||
const launchNonEmpty = launchSuccess.filter((item) => item.chatObserved === true && (Number(item.workbenchMessageCount ?? 0) > 0 || Number(item.workbenchTraceRowCount ?? 0) > 0));
|
||||
const launchEmpty = launchSuccess.filter((item) => item.chatObserved !== true || (Number(item.workbenchMessageCount ?? 0) === 0 && Number(item.workbenchTraceRowCount ?? 0) === 0));
|
||||
const minMdtodoTaskCount = minNumber(mdtodoSamples.map((sample) => sample.projectManagement?.taskCount));
|
||||
const maxMdtodoTaskCount = maxNumber(mdtodoSamples.map((sample) => sample.projectManagement?.taskCount));
|
||||
return {
|
||||
enabled,
|
||||
config: config || null,
|
||||
@@ -1041,8 +1052,18 @@ function buildProjectManagementReport(samples, control, network, pagePerformance
|
||||
taskRefMissingMax: maxNumber(projectSamples.map((sample) => sample.projectManagement?.taskRefMissingCount)),
|
||||
latestSelectedTaskRefHash: latestProject?.selectedTaskRef?.hash ?? null,
|
||||
latestSelectedTaskRefPreview: latestProject?.selectedTaskRef?.preview ?? null,
|
||||
latestSelectedFileLabelPreview: latestProject?.selectedFileLabel?.textPreview ?? null,
|
||||
latestSelectedFileLabelLooksDirect: latestProject?.selectedFileLabelLooksDirect ?? null,
|
||||
selectedFileLabelBadSampleCount: selectedFileLabelBadSamples.length,
|
||||
fileOptionSuspiciousLabelSampleCount: suspiciousFileLabelSamples.length,
|
||||
maxFileOptionSuspiciousLabelCount: maxNumber(projectSamples.map((sample) => sample.projectManagement?.fileOptionSuspiciousLabelCount)),
|
||||
latestSelectedTaskStatus: latestProject?.selectedTaskStatus ?? null,
|
||||
latestTaskStatusCounts,
|
||||
selectedTaskBodyVisibleSamples: bodyVisibleSamples.length,
|
||||
reportLinkVisibleSamples: reportLinkSamples.length,
|
||||
maxReportLinkCount: maxNumber(projectSamples.map((sample) => sample.projectManagement?.reportLinkCount)),
|
||||
reportPreviewVisibleSamples: reportPreviewSamples.length,
|
||||
reportFullscreenVisibleSamples: reportFullscreenSamples.length,
|
||||
launchButtonVisibleSamples: launchVisibleSamples.length,
|
||||
launchButtonEnabledSamples: launchEnabledSamples.length,
|
||||
launchButtonDisabledSamples: Math.max(0, launchVisibleSamples.length - launchEnabledSamples.length),
|
||||
@@ -1054,7 +1075,12 @@ function buildProjectManagementReport(samples, control, network, pagePerformance
|
||||
launchCommandCount: launchCommands.length,
|
||||
launchSuccessCount: launchSuccess.length,
|
||||
launchFailureCount: launchFailed.length,
|
||||
launchNonEmptyCount: launchNonEmpty.length,
|
||||
launchEmptyCount: launchEmpty.length,
|
||||
launchWithOtelTraceHeaderCount: launchSuccess.filter((item) => item.otelTraceId).length,
|
||||
reportPreviewCommandCount: previewCommands.length,
|
||||
mdtodoTaskCountMin: minMdtodoTaskCount,
|
||||
mdtodoTaskCountMax: maxMdtodoTaskCount,
|
||||
projectApiEventCount: projectApiEvents.length,
|
||||
projectApiResponseCount: projectApiResponses.length,
|
||||
projectApiFailureCount: projectApiFailures.length,
|
||||
@@ -1075,7 +1101,16 @@ function buildProjectManagementReport(samples, control, network, pagePerformance
|
||||
taskCount: sample.projectManagement?.taskCount ?? null,
|
||||
taskRefMissingCount: sample.projectManagement?.taskRefMissingCount ?? null,
|
||||
selectedTaskRefHash: sample.projectManagement?.selectedTaskRef?.hash ?? null,
|
||||
selectedFileLabelPreview: sample.projectManagement?.selectedFileLabel?.textPreview ?? null,
|
||||
selectedFileLabelLooksDirect: sample.projectManagement?.selectedFileLabelLooksDirect ?? null,
|
||||
fileOptionSuspiciousLabelCount: sample.projectManagement?.fileOptionSuspiciousLabelCount ?? 0,
|
||||
selectedTaskStatus: sample.projectManagement?.selectedTaskStatus ?? null,
|
||||
taskBodyVisible: sample.projectManagement?.taskBodyVisible === true,
|
||||
taskBodyBytes: sample.projectManagement?.taskBody?.textBytes ?? 0,
|
||||
reportLinkCount: sample.projectManagement?.reportLinkCount ?? 0,
|
||||
reportPreviewVisible: sample.projectManagement?.reportPreviewVisible === true,
|
||||
reportPreviewBytes: sample.projectManagement?.reportPreview?.textBytes ?? 0,
|
||||
reportFullscreenVisible: sample.projectManagement?.reportFullscreenVisible === true,
|
||||
launchButtonVisible: sample.projectManagement?.launchButtonVisible === true,
|
||||
launchButtonEnabled: sample.projectManagement?.launchButtonEnabled === true,
|
||||
blockerCount: sample.projectManagement?.blockerCount ?? 0,
|
||||
@@ -1106,6 +1141,11 @@ function compactProjectManagementForOutput(report) {
|
||||
sessionId: item?.sessionId ?? null,
|
||||
workbenchUrl: item?.workbenchUrl ?? null,
|
||||
otelTraceId: item?.otelTraceId ?? null,
|
||||
chatObserved: item?.chatObserved ?? null,
|
||||
chatStatus: item?.chatStatus ?? null,
|
||||
chatTraceId: item?.chatTraceId ?? null,
|
||||
workbenchMessageCount: item?.workbenchMessageCount ?? null,
|
||||
workbenchTraceRowCount: item?.workbenchTraceRowCount ?? null,
|
||||
contractVersion: item?.contractVersion ?? null,
|
||||
selectedTaskRefHash: item?.selectedTaskRefHash ?? null,
|
||||
errorMessageHash: item?.errorMessageHash ?? null,
|
||||
@@ -1161,7 +1201,7 @@ function compactProjectManagementForOutput(report) {
|
||||
|
||||
function projectManagementCommandRows(control, config) {
|
||||
const allowed = new Set(config?.commandAllowlist || []);
|
||||
const mdtodoCommandTypes = new Set(["gotoProjectMdtodo", "openMdtodoSourceConfig", "configureMdtodoHwpodSource", "probeMdtodoSource", "reindexMdtodoSource", "expandMdtodoTask", "editMdtodoTaskTitle", "editMdtodoTaskBody", "toggleMdtodoTaskStatus", "addMdtodoRootTask", "addMdtodoSubTask", "continueMdtodoTask", "deleteMdtodoTask", "launchWorkbenchFromMdtodo"]);
|
||||
const mdtodoCommandTypes = new Set(["gotoProjectMdtodo", "openMdtodoSourceConfig", "configureMdtodoHwpodSource", "probeMdtodoSource", "reindexMdtodoSource", "expandMdtodoTask", "openMdtodoReportPreview", "toggleMdtodoReportFullscreen", "editMdtodoTaskInline", "editMdtodoTaskTitle", "editMdtodoTaskBody", "toggleMdtodoTaskStatus", "addMdtodoRootTask", "addMdtodoSubTask", "continueMdtodoTask", "deleteMdtodoTask", "launchWorkbenchFromMdtodo"]);
|
||||
return (control || [])
|
||||
.filter((item) => allowed.has(item?.type) || mdtodoCommandTypes.has(item?.type) || String(item?.type || "").startsWith("selectMdtodo") || item?.type === "selectProjectSource" || item?.type === "launchWorkbenchFromTask")
|
||||
.filter((item) => item.phase === "completed" || item.phase === "failed")
|
||||
@@ -1178,6 +1218,14 @@ function projectManagementCommandRows(control, config) {
|
||||
sessionId: detail.sessionId ?? error.details?.sessionId ?? null,
|
||||
workbenchUrl: detail.workbenchUrl ?? error.details?.workbenchUrl ?? null,
|
||||
otelTraceId: detail.otelTraceId ?? error.details?.otelTraceId ?? null,
|
||||
chatObserved: detail.chatObserved ?? error.details?.chatObserved ?? null,
|
||||
chatStatus: detail.chatStatus ?? error.details?.chatStatus ?? null,
|
||||
chatSessionId: detail.chatSessionId ?? error.details?.chatSessionId ?? null,
|
||||
chatTraceId: detail.chatTraceId ?? error.details?.chatTraceId ?? null,
|
||||
chatOtelTraceId: detail.chatOtelTraceId ?? error.details?.chatOtelTraceId ?? null,
|
||||
workbenchMessageCount: detail.workbenchSnapshot?.messageCount ?? error.details?.workbenchSnapshot?.messageCount ?? null,
|
||||
workbenchTraceRowCount: detail.workbenchSnapshot?.traceRowCount ?? error.details?.workbenchSnapshot?.traceRowCount ?? null,
|
||||
workbenchComposerReady: detail.workbenchSnapshot?.composerReady ?? error.details?.workbenchSnapshot?.composerReady ?? null,
|
||||
contractVersion: detail.contractVersion ?? error.details?.contractVersion ?? null,
|
||||
selectedTaskRefHash: detail.selectedTask?.hash ?? detail.projectBeforeClick?.selectedTaskRef?.hash ?? null,
|
||||
errorName: error.name ?? null,
|
||||
@@ -1238,6 +1286,28 @@ function buildProjectManagementFindings(report) {
|
||||
if (Number(summary.mdtodoSampleCount ?? 0) > 0 && Number(summary.latestTaskCount ?? 0) > 0 && Number(summary.launchButtonEnabledSamples ?? 0) === 0) {
|
||||
findings.push({ id: "workbench-launch-button-unavailable", severity: "red", summary: "mdtodo tasks were sampled but the Workbench launch button was never enabled", count: summary.mdtodoSampleCount, latest: report.latest, valuesRedacted: true });
|
||||
}
|
||||
if (Number(summary.selectedFileLabelBadSampleCount ?? 0) > 0 || summary.latestSelectedFileLabelLooksDirect === false) {
|
||||
findings.push({ id: "mdtodo-file-label-not-filename", severity: "red", summary: "MDTODO file dropdown selected label is not a direct markdown filename", count: summary.selectedFileLabelBadSampleCount, latestSelectedFileLabelPreview: summary.latestSelectedFileLabelPreview, samples: report.samples.filter((item) => item.selectedFileLabelLooksDirect === false).slice(0, 12), valuesRedacted: true });
|
||||
}
|
||||
if (Number(summary.maxFileOptionSuspiciousLabelCount ?? 0) > 0) {
|
||||
findings.push({ id: "mdtodo-nondirect-files-visible", severity: "red", summary: "MDTODO file dropdown includes non-direct or report-like markdown labels; docs/MDTODO discovery must be direct files only", count: summary.maxFileOptionSuspiciousLabelCount, samples: report.samples.filter((item) => Number(item.fileOptionSuspiciousLabelCount ?? 0) > 0).slice(0, 12), valuesRedacted: true });
|
||||
}
|
||||
if (Number(summary.selectedTaskSampleCount ?? 0) > 0 && Number(summary.selectedTaskBodyVisibleSamples ?? 0) === 0) {
|
||||
findings.push({ id: "mdtodo-task-body-not-visible", severity: "red", summary: "selected MDTODO task was sampled but no rendered task body was visible", count: summary.selectedTaskSampleCount, samples: report.samples.filter((item) => item.selectedTaskRefHash).slice(-12), valuesRedacted: true });
|
||||
}
|
||||
if (Number(summary.maxReportLinkCount ?? 0) > 0 && Number(summary.reportPreviewVisibleSamples ?? 0) === 0) {
|
||||
const severity = Number(summary.reportPreviewCommandCount ?? 0) > 0 ? "red" : "amber";
|
||||
findings.push({ id: "mdtodo-report-preview-missing", severity, summary: "MDTODO report links were visible but no markdown report preview was sampled", count: summary.maxReportLinkCount, previewCommandCount: summary.reportPreviewCommandCount, samples: report.samples.filter((item) => Number(item.reportLinkCount ?? 0) > 0).slice(-12), valuesRedacted: true });
|
||||
}
|
||||
if (Number(summary.reportPreviewCommandCount ?? 0) > 0 && Number(summary.reportFullscreenVisibleSamples ?? 0) === 0 && report.commands.some((item) => item.type === "toggleMdtodoReportFullscreen" && item.phase === "completed")) {
|
||||
findings.push({ id: "mdtodo-report-fullscreen-missing", severity: "red", summary: "toggleMdtodoReportFullscreen command completed but fullscreen report dialog was never sampled", count: summary.reportPreviewCommandCount, commands: report.commands.filter((item) => item.type === "toggleMdtodoReportFullscreen").slice(-8), valuesRedacted: true });
|
||||
}
|
||||
if (Number(summary.launchEmptyCount ?? 0) > 0) {
|
||||
findings.push({ id: "mdtodo-workbench-launch-empty", severity: "red", summary: "MDTODO Workbench launch created a session without observing agent chat or visible message/trace content", count: summary.launchEmptyCount, commands: report.launchCommands.filter((item) => item.chatObserved !== true || (Number(item.workbenchMessageCount ?? 0) === 0 && Number(item.workbenchTraceRowCount ?? 0) === 0)).slice(0, 12), valuesRedacted: true });
|
||||
}
|
||||
if (Number(summary.mdtodoTaskCountMin ?? 0) > 0 && Number(summary.mdtodoTaskCountMax ?? 0) > 0 && (Number(summary.mdtodoTaskCountMax) - Number(summary.mdtodoTaskCountMin) >= 10 || Number(summary.mdtodoTaskCountMax) / Math.max(1, Number(summary.mdtodoTaskCountMin)) >= 2)) {
|
||||
findings.push({ id: "mdtodo-task-count-diverged", severity: "amber", summary: "MDTODO task count varied sharply during observation; compare control commands and observer samples for projection divergence", minTaskCount: summary.mdtodoTaskCountMin, maxTaskCount: summary.mdtodoTaskCountMax, samples: report.samples.slice(-20), valuesRedacted: true });
|
||||
}
|
||||
if (Number(summary.projectApiFailureCount ?? 0) > 0 || Number(summary.projectApiRequestFailedCount ?? 0) > 0) {
|
||||
findings.push({ id: "project-management-api-failed", severity: "amber", summary: "natural project-management or Workbench launch API requests failed during observation", count: Number(summary.projectApiFailureCount ?? 0) + Number(summary.projectApiRequestFailedCount ?? 0), groups: report.projectApiByPath.slice(0, 12), valuesRedacted: true });
|
||||
}
|
||||
@@ -1264,6 +1334,11 @@ function maxNumber(values) {
|
||||
return numeric.length > 0 ? Math.max(...numeric) : 0;
|
||||
}
|
||||
|
||||
function minNumber(values) {
|
||||
const numeric = (values || []).map((value) => Number(value)).filter(Number.isFinite);
|
||||
return numeric.length > 0 ? Math.min(...numeric) : 0;
|
||||
}
|
||||
|
||||
function buildSessionInvariantFindings(control, manifest = {}) {
|
||||
const findings = [];
|
||||
for (const row of control || []) {
|
||||
|
||||
Reference in New Issue
Block a user