feat: add mdtodo web-probe commands (#898)

Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
Lyon
2026-06-25 22:56:10 +08:00
committed by GitHub
parent 2da1c97e0d
commit 87b90e45b6
6 changed files with 555 additions and 38 deletions
+107 -3
View File
@@ -68,7 +68,38 @@ interface NodeWebProbeScriptOptions {
}
type NodeWebProbeObserveAction = "start" | "status" | "command" | "stop" | "collect" | "analyze";
type NodeWebProbeObserveCommandType = "login" | "preflight" | "goto" | "newSession" | "sendPrompt" | "steer" | "cancel" | "selectProvider" | "clickSession" | "selectProjectSource" | "selectMdtodoFile" | "selectMdtodoTask" | "launchWorkbenchFromTask" | "screenshot" | "mark" | "stop";
type NodeWebProbeObserveCommandType =
| "login"
| "preflight"
| "goto"
| "gotoProjectMdtodo"
| "newSession"
| "sendPrompt"
| "steer"
| "cancel"
| "selectProvider"
| "clickSession"
| "selectProjectSource"
| "selectMdtodoSource"
| "selectMdtodoFile"
| "selectMdtodoTask"
| "expandMdtodoTask"
| "openMdtodoSourceConfig"
| "configureMdtodoHwpodSource"
| "probeMdtodoSource"
| "reindexMdtodoSource"
| "editMdtodoTaskTitle"
| "editMdtodoTaskBody"
| "toggleMdtodoTaskStatus"
| "addMdtodoRootTask"
| "addMdtodoSubTask"
| "continueMdtodoTask"
| "deleteMdtodoTask"
| "launchWorkbenchFromTask"
| "launchWorkbenchFromMdtodo"
| "screenshot"
| "mark"
| "stop";
interface NodeWebProbeObserveOptions {
action: "observe";
@@ -111,6 +142,13 @@ interface NodeWebProbeObserveOptions {
commandSourceId: string | null;
commandFileRef: string | null;
commandTaskRef: string | null;
commandTaskId: string | null;
commandTitle: string | null;
commandBody: string | null;
commandStatus: string | null;
commandHwpodId: string | null;
commandNodeId: string | null;
commandRoot: string | null;
}
interface NodeWebProbeSentinelOptions {
@@ -7537,6 +7575,14 @@ function parseNodeWebProbeObserveOptions(
"--source-id",
"--file-ref",
"--task-ref",
"--task",
"--task-id",
"--title",
"--body",
"--status",
"--hwpod-id",
"--node-id",
"--root",
]), new Set(["--force", "--full", "--text-stdin"]));
const commandTypeRaw = optionValue(args, "--type") ?? null;
const commandType = commandTypeRaw === null ? null : parseNodeWebProbeObserveCommandType(commandTypeRaw);
@@ -7583,7 +7629,25 @@ function parseNodeWebProbeObserveOptions(
const commandSourceId = optionValue(args, "--source-id") ?? null;
const commandFileRef = optionValue(args, "--file-ref") ?? null;
const commandTaskRef = optionValue(args, "--task-ref") ?? null;
for (const [label, value] of [["--source-id", commandSourceId], ["--file-ref", commandFileRef], ["--task-ref", commandTaskRef]] as const) {
const commandTaskId = optionValue(args, "--task-id") ?? optionValue(args, "--task") ?? null;
const commandTitle = optionValue(args, "--title") ?? null;
const commandBody = optionValue(args, "--body") ?? null;
const commandStatus = optionValue(args, "--status") ?? null;
const commandHwpodId = optionValue(args, "--hwpod-id") ?? null;
const commandNodeId = optionValue(args, "--node-id") ?? null;
const commandRoot = optionValue(args, "--root") ?? null;
for (const [label, value] of [
["--source-id", commandSourceId],
["--file-ref", commandFileRef],
["--task-ref", commandTaskRef],
["--task/--task-id", commandTaskId],
["--title", commandTitle],
["--body", commandBody],
["--status", commandStatus],
["--hwpod-id", commandHwpodId],
["--node-id", commandNodeId],
["--root", commandRoot],
] as const) {
if (value !== null && (value.includes("\0") || value.length > 500)) throw new Error(`unsafe web-probe observe ${label}: expected 1-500 non-NUL chars`);
}
return {
@@ -7627,6 +7691,13 @@ function parseNodeWebProbeObserveOptions(
commandSourceId,
commandFileRef,
commandTaskRef,
commandTaskId,
commandTitle,
commandBody,
commandStatus,
commandHwpodId,
commandNodeId,
commandRoot,
};
}
@@ -7641,15 +7712,30 @@ function parseNodeWebProbeObserveCommandType(value: string): NodeWebProbeObserve
|| value === "cancel"
|| value === "selectProvider"
|| value === "clickSession"
|| value === "gotoProjectMdtodo"
|| value === "selectProjectSource"
|| value === "selectMdtodoSource"
|| value === "selectMdtodoFile"
|| value === "selectMdtodoTask"
|| value === "expandMdtodoTask"
|| value === "openMdtodoSourceConfig"
|| value === "configureMdtodoHwpodSource"
|| value === "probeMdtodoSource"
|| value === "reindexMdtodoSource"
|| value === "editMdtodoTaskTitle"
|| value === "editMdtodoTaskBody"
|| value === "toggleMdtodoTaskStatus"
|| value === "addMdtodoRootTask"
|| value === "addMdtodoSubTask"
|| value === "continueMdtodoTask"
|| value === "deleteMdtodoTask"
|| value === "launchWorkbenchFromTask"
|| value === "launchWorkbenchFromMdtodo"
|| value === "screenshot"
|| value === "mark"
|| value === "stop"
) return value;
throw new Error(`web-probe observe command --type must be login, preflight, goto, newSession, sendPrompt, steer, cancel, selectProvider, clickSession, selectProjectSource, selectMdtodoFile, selectMdtodoTask, launchWorkbenchFromTask, screenshot, mark, or stop; got ${value}`);
throw new Error(`web-probe observe command --type must be login, preflight, goto, gotoProjectMdtodo, newSession, sendPrompt, steer, cancel, selectProvider, clickSession, selectProjectSource, selectMdtodoSource, selectMdtodoFile, selectMdtodoTask, expandMdtodoTask, openMdtodoSourceConfig, configureMdtodoHwpodSource, probeMdtodoSource, reindexMdtodoSource, editMdtodoTaskTitle, editMdtodoTaskBody, toggleMdtodoTaskStatus, addMdtodoRootTask, addMdtodoSubTask, continueMdtodoTask, deleteMdtodoTask, launchWorkbenchFromTask, launchWorkbenchFromMdtodo, screenshot, mark, or stop; got ${value}`);
}
function parseWebProbeBrowserProxyMode(value: string | undefined): WebProbeBrowserProxyMode {
@@ -8327,6 +8413,13 @@ function runNodeWebProbeObserveCommand(options: NodeWebProbeObserveOptions, spec
sourceId: options.commandSourceId,
fileRef: options.commandFileRef,
taskRef: options.commandTaskRef,
taskId: options.commandTaskId,
title: options.commandTitle,
body: options.commandBody,
status: options.commandStatus,
hwpodId: options.commandHwpodId,
nodeId: options.commandNodeId,
root: options.commandRoot,
};
const preStopStatus = options.force && stopCommand
? readNodeWebProbeObserveRemoteStatus(options, spec, 1, Math.min(options.commandTimeoutSeconds, 30))
@@ -10749,6 +10842,8 @@ function nodeWebObserveWaitCommandShell(commandId: string, waitMs: number): stri
function commandSummaryForOutput(payload: Record<string, unknown>): Record<string, unknown> {
const text = typeof payload.text === "string" ? payload.text : null;
const title = typeof payload.title === "string" ? payload.title : null;
const body = typeof payload.body === "string" ? payload.body : null;
const opaque = (value: unknown) => typeof value === "string" && value.length > 0
? {
hash: `sha256:${createHash("sha256").update(value).digest("hex")}`,
@@ -10766,6 +10861,15 @@ function commandSummaryForOutput(payload: Record<string, unknown>): Record<strin
sourceId: opaque(payload.sourceId),
fileRef: opaque(payload.fileRef),
taskRef: opaque(payload.taskRef),
taskId: payload.taskId ?? null,
titleHash: title === null ? null : `sha256:${createHash("sha256").update(title).digest("hex")}`,
titleBytes: title === null ? null : Buffer.byteLength(title),
bodyHash: body === null ? null : `sha256:${createHash("sha256").update(body).digest("hex")}`,
bodyBytes: body === null ? null : Buffer.byteLength(body),
status: payload.status ?? null,
hwpodId: opaque(payload.hwpodId),
nodeId: opaque(payload.nodeId),
root: opaque(payload.root),
textHash: text === null ? null : `sha256:${createHash("sha256").update(text).digest("hex")}`,
textBytes: text === null ? null : Buffer.byteLength(text),
valuesRedacted: true,