@ai-agent-forge/plugin-desktop-windows-input 0.88.19 → 0.88.20

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/agent-forge.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageFormatVersion": 1,
3
3
  "id": "agent-forge.plugin.desktop-windows-input",
4
- "pluginVersion": "0.88.19",
4
+ "pluginVersion": "0.88.20",
5
5
  "apiVersion": "1",
6
6
  "minHostVersion": "0.84.4",
7
7
  "capabilityRefs": [
@@ -1 +1 @@
1
- {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAc3E,OAAO,KAAK,EACX,2BAA2B,EAI3B,MAAM,YAAY,CAAC;AAyVpB,wBAAgB,qCAAqC,CACpD,OAAO,EAAE,2BAA2B,GAClC,2BAA2B,CA8N7B","sourcesContent":["/**\n * Bounded desktop input and replay capability factory, migrated from\n * agent-forge `src/profile/runtime-capabilities-desktop-input.ts`\n * (`desktopInputFactory`, D-075 S3 extraction). Differences from the host\n * original:\n * - The factory type is the public `CapabilityPluginSyncFactory` from the\n * plugin SDK instead of the host-internal `BuiltinCapabilityPlugin`.\n * - Projection helpers live in `projection.ts`, input helpers in `shared.ts`.\n * Tool names, budgets and result shapes are unchanged, including the\n * readonly-mode refusal to register input tools and the optional replay\n * registration when the runtime exposes a replay method. Since the 2026-10-13\n * product decision, type/key actions may omit the target: the request is routed\n * to the driver's foreground keyboard-queue injection instead of being rejected\n * (user ruling: \"AI 操作需要的是任何情况下都能操作,和人一样操作电脑\").\n */\nimport type { CapabilityPluginSyncFactory } from \"@agent-forge/plugin-sdk\";\nimport { Type } from \"typebox\";\nimport {\n\tDESKTOP_MAX_POSTCONDITIONS_V1,\n\tDESKTOP_MAX_REPLAY_ACTIONS_V1,\n\tDESKTOP_MAX_STRING_CHARS_V1,\n\tDESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\tdesktopBoundedString,\n\tdesktopFailure,\n\tdesktopRequiredString,\n\tdesktopResultWithinBudget,\n\tprojectDesktopObservation,\n} from \"./projection.ts\";\nimport { signalFrom, toolInvocation } from \"./shared.ts\";\nimport type {\n\tDesktopFullControlAdapterV1,\n\tDesktopOperationRequestV1,\n\tDesktopPostconditionV1,\n\tDesktopReplayRequestV1,\n} from \"./types.ts\";\n\nfunction desktopTarget(input: unknown, allowCoordinates: boolean): DesktopOperationRequestV1[\"action\"][\"target\"] {\n\tif (input === null || typeof input !== \"object\" || Array.isArray(input)) throw new Error(\"desktop-target-invalid\");\n\tconst target = input as Record<string, unknown>;\n\tif (target.kind === \"window\") {\n\t\tdesktopExactKeys(target, [\"kind\", \"windowId\"]);\n\t\treturn { kind: \"window\", windowId: desktopRequiredString(target.windowId, \"windowId\") };\n\t}\n\tif (target.kind === \"control\") {\n\t\tdesktopExactKeys(target, [\"kind\", \"controlId\", \"windowId\"]);\n\t\treturn {\n\t\t\tkind: \"control\",\n\t\t\tcontrolId: desktopRequiredString(target.controlId, \"controlId\"),\n\t\t\t...(target.windowId === undefined ? {} : { windowId: desktopRequiredString(target.windowId, \"windowId\") }),\n\t\t};\n\t}\n\t// Raw screen-pixel coordinates are accepted for click actions only; the\n\t// schema union cannot express that condition, so this validator rejects it.\n\tif (target.kind === \"coordinates\") {\n\t\tif (!allowCoordinates) throw new Error(\"desktop-target-invalid\");\n\t\tdesktopExactKeys(target, [\"kind\", \"x\", \"y\"]);\n\t\tif (\n\t\t\ttypeof target.x !== \"number\" ||\n\t\t\t!Number.isInteger(target.x) ||\n\t\t\ttarget.x < 0 ||\n\t\t\ttypeof target.y !== \"number\" ||\n\t\t\t!Number.isInteger(target.y) ||\n\t\t\ttarget.y < 0\n\t\t)\n\t\t\tthrow new Error(\"desktop-target-invalid\");\n\t\treturn { kind: \"coordinates\", x: target.x, y: target.y };\n\t}\n\tthrow new Error(\"desktop-target-invalid\");\n}\n\nfunction desktopExactKeys(value: Record<string, unknown>, allowed: readonly string[]): void {\n\tif (Object.keys(value).some((key) => !allowed.includes(key))) throw new Error(\"desktop-input-invalid\");\n}\n\n/**\n * Target validation with the foreground-input exception: type and key may omit\n * the target entirely. A target-less type/key is routed by the driver to the\n * real keyboard queue at the current focus (FOREGROUND_INPUT_SCRIPT) — the only\n * path that reaches UIA-invisible surfaces such as the native file dialog's\n * name box. Every other kind still requires an observed identity: a focus,\n * click or scroll without a target has no addressable subject.\n */\nfunction desktopActionTarget(\n\tinput: unknown,\n\tkind: DesktopOperationRequestV1[\"action\"][\"kind\"],\n): DesktopOperationRequestV1[\"action\"][\"target\"] | undefined {\n\tif (input === undefined) {\n\t\tif (kind === \"type\" || kind === \"key\") return undefined;\n\t\tthrow new Error(\"desktop-target-required\");\n\t}\n\treturn desktopTarget(input, kind === \"click\");\n}\n\nfunction desktopPostconditions(input: unknown): readonly DesktopPostconditionV1[] | undefined {\n\tif (input === undefined) return undefined;\n\tif (!Array.isArray(input) || input.length > DESKTOP_MAX_POSTCONDITIONS_V1)\n\t\tthrow new Error(\"desktop-postconditions-invalid\");\n\treturn input.map((entry) => {\n\t\tif (entry === null || typeof entry !== \"object\" || Array.isArray(entry))\n\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\tconst value = entry as Record<string, unknown>;\n\t\tif (value.kind === \"window-exists\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"windowId\"]);\n\t\t\treturn { kind: \"window-exists\", windowId: desktopRequiredString(value.windowId, \"windowId\") } as const;\n\t\t}\n\t\tif (value.kind === \"control-exists\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"controlId\"]);\n\t\t\treturn { kind: \"control-exists\", controlId: desktopRequiredString(value.controlId, \"controlId\") } as const;\n\t\t}\n\t\tif (value.kind === \"focused\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"controlId\"]);\n\t\t\treturn { kind: \"focused\", controlId: desktopRequiredString(value.controlId, \"controlId\") } as const;\n\t\t}\n\t\tif (value.kind === \"property-equals\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"target\", \"property\", \"expected\"]);\n\t\t\tif (value.property !== \"enabled\" && value.property !== \"value\" && value.property !== \"name\")\n\t\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\t\tif (\n\t\t\t\t(value.property === \"enabled\" && typeof value.expected !== \"boolean\") ||\n\t\t\t\t(value.property !== \"enabled\" && typeof value.expected !== \"string\")\n\t\t\t)\n\t\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\t\treturn {\n\t\t\t\tkind: \"property-equals\",\n\t\t\t\ttarget: desktopTarget(value.target, false),\n\t\t\t\tproperty: value.property,\n\t\t\t\texpected:\n\t\t\t\t\ttypeof value.expected === \"string\"\n\t\t\t\t\t\t? desktopBoundedString(value.expected, \"postcondition expected\")\n\t\t\t\t\t\t: value.expected,\n\t\t\t} as DesktopPostconditionV1;\n\t\t}\n\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t});\n}\n\nfunction desktopExecuteRequest(input: Record<string, unknown>, operationId: string): DesktopOperationRequestV1 {\n\tdesktopExactKeys(input, [\"sessionId\", \"action\", \"postconditions\"]);\n\tconst actionInput = input.action;\n\tif (actionInput === null || typeof actionInput !== \"object\" || Array.isArray(actionInput))\n\t\tthrow new Error(\"desktop-action-invalid\");\n\tconst action = actionInput as Record<string, unknown>;\n\tdesktopExactKeys(action, [\"kind\", \"target\", \"text\", \"key\"]);\n\tif (\n\t\taction.kind !== \"focus\" &&\n\t\taction.kind !== \"click\" &&\n\t\taction.kind !== \"type\" &&\n\t\taction.kind !== \"key\" &&\n\t\taction.kind !== \"scroll\"\n\t)\n\t\tthrow new Error(\"desktop-action-invalid\");\n\tconst target = desktopActionTarget(action.target, action.kind);\n\tconst text =\n\t\taction.kind === \"type\" || action.kind === \"scroll\" ? desktopBoundedString(action.text, \"text\") : undefined;\n\tif (text !== undefined && text.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst key = action.kind === \"key\" ? desktopBoundedString(action.key, \"key\") : undefined;\n\tif (key !== undefined && key.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst postconditions = desktopPostconditions(input.postconditions);\n\t// Postcondition scoping for foreground actions: a target-less type/key has no\n\t// action target, so a target-level postcondition cannot describe its effect.\n\t// `property-equals` is the only kind that carries a target; pair it with a\n\t// target-less action and the check would silently assert state the action\n\t// never addressed. Global session-state checks (window-exists,\n\t// control-exists, focused) and the no-postcondition case stay allowed.\n\tif (target === undefined && postconditions?.some((condition) => condition.kind === \"property-equals\"))\n\t\tthrow new Error(\"desktop-postcondition-target-without-action-target\");\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tsessionId: desktopRequiredString(input.sessionId, \"sessionId\"),\n\t\taction: {\n\t\t\tversion: 1,\n\t\t\tkind: action.kind,\n\t\t\t...(target === undefined ? {} : { target }),\n\t\t\t...(text === undefined ? {} : { text }),\n\t\t\t...(key === undefined ? {} : { key }),\n\t\t},\n\t\t...(postconditions === undefined ? {} : { postconditions }),\n\t\t// Input plugin operations always request a fresh observation; callers may\n\t\t// not turn this off because target identity otherwise goes stale.\n\t\treobserveAfterAction: true,\n\t};\n}\n\nfunction desktopVerification(\n\tvalue: unknown,\n): { readonly status: \"passed\" | \"failed\" | \"unknown\"; readonly checks: readonly string[] } | undefined {\n\tif (value === undefined) return undefined;\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst verification = value as Record<string, unknown>;\n\tif (\n\t\t(verification.status !== \"passed\" && verification.status !== \"failed\" && verification.status !== \"unknown\") ||\n\t\t!Array.isArray(verification.checks) ||\n\t\tverification.checks.length > DESKTOP_MAX_POSTCONDITIONS_V1\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\treturn {\n\t\tstatus: verification.status,\n\t\tchecks: verification.checks.map((check) => desktopBoundedString(check, \"verification check\")),\n\t};\n}\n\nfunction desktopExecuteResult(value: unknown, request: DesktopOperationRequestV1) {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst result = value as Record<string, unknown>;\n\tif (\n\t\tresult.version !== 1 ||\n\t\tresult.operationId !== request.operationId ||\n\t\t(result.status !== \"succeeded\" &&\n\t\t\tresult.status !== \"failed\" &&\n\t\t\tresult.status !== \"cancelled\" &&\n\t\t\tresult.status !== \"needs_user\" &&\n\t\t\tresult.status !== \"unsupported\")\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tconst observation = result.observation === undefined ? undefined : projectDesktopObservation(result.observation);\n\tif (\n\t\tresult.status === \"succeeded\" &&\n\t\t(observation === undefined || observation.observation.sessionId !== request.sessionId)\n\t) {\n\t\treturn desktopFailure(\n\t\t\trequest.operationId,\n\t\t\t\"verification_unavailable\",\n\t\t\t\"Desktop action did not produce a fresh observation\",\n\t\t);\n\t}\n\tconst base = {\n\t\tversion: 1 as const,\n\t\toperationId: request.operationId,\n\t\tstatus: result.status,\n\t\tsummary: result.status === \"succeeded\" ? \"Desktop action completed\" : \"Desktop action could not be completed\",\n\t\t...(observation === undefined ? {} : observation),\n\t\t...(desktopVerification(result.verification) === undefined\n\t\t\t? {}\n\t\t\t: { verification: desktopVerification(result.verification) }),\n\t};\n\tif (result.status === \"succeeded\") return desktopResultWithinBudget(base);\n\tconst error = result.error;\n\tif (error === null || typeof error !== \"object\" || Array.isArray(error)) throw new Error(\"desktop-result-invalid\");\n\tconst errorValue = error as Record<string, unknown>;\n\tconst causeCode =\n\t\tresult.status === \"needs_user\" && typeof errorValue.causeCode === \"string\"\n\t\t\t? desktopBoundedString(errorValue.causeCode, \"error causeCode\")\n\t\t\t: undefined;\n\treturn desktopResultWithinBudget({\n\t\t...base,\n\t\terror: {\n\t\t\tversion: 1 as const,\n\t\t\tcode: result.status === \"needs_user\" ? \"needs_user\" : \"desktop_action_failed\",\n\t\t\tmessage: result.status === \"needs_user\" ? \"Desktop action requires user action\" : \"Desktop action failed\",\n\t\t\t...(causeCode === undefined ? {} : { causeCode }),\n\t\t},\n\t});\n}\n\nfunction desktopReplayActionInput(raw: unknown): DesktopOperationRequestV1[\"action\"] {\n\tif (raw === null || typeof raw !== \"object\" || Array.isArray(raw)) throw new Error(\"desktop-action-invalid\");\n\tconst action = raw as Record<string, unknown>;\n\tdesktopExactKeys(action, [\"kind\", \"target\", \"text\", \"key\"]);\n\tif (\n\t\taction.kind !== \"focus\" &&\n\t\taction.kind !== \"click\" &&\n\t\taction.kind !== \"type\" &&\n\t\taction.kind !== \"key\" &&\n\t\taction.kind !== \"scroll\"\n\t)\n\t\tthrow new Error(\"desktop-action-invalid\");\n\t// Replay stays anchored to observed identities; coordinates are execute-only.\n\t// Recorded foreground type/key entries (no target) replay through the same\n\t// driver foreground-injection path as desktop_execute.\n\tconst target = desktopActionTarget(action.target, action.kind);\n\tconst text =\n\t\taction.kind === \"type\" || action.kind === \"scroll\" ? desktopBoundedString(action.text, \"text\") : undefined;\n\tif (text !== undefined && text.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst key = action.kind === \"key\" ? desktopBoundedString(action.key, \"key\") : undefined;\n\tif (key !== undefined && key.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\treturn {\n\t\tversion: 1,\n\t\tkind: action.kind,\n\t\t...(target === undefined ? {} : { target }),\n\t\t...(text === undefined ? {} : { text }),\n\t\t...(key === undefined ? {} : { key }),\n\t};\n}\n\nfunction desktopReplayRequest(input: Record<string, unknown>, operationId: string): DesktopReplayRequestV1 {\n\tdesktopExactKeys(input, [\"sessionId\", \"actions\", \"stopOnFailure\"]);\n\tif (\n\t\t!Array.isArray(input.actions) ||\n\t\tinput.actions.length === 0 ||\n\t\tinput.actions.length > DESKTOP_MAX_REPLAY_ACTIONS_V1\n\t)\n\t\tthrow new Error(\"desktop-replay-actions-invalid\");\n\tconst sessionId = desktopRequiredString(input.sessionId, \"sessionId\");\n\tconst operations = input.actions.map((raw, index) => {\n\t\tconst action = desktopReplayActionInput(raw);\n\t\treturn {\n\t\t\tversion: 1 as const,\n\t\t\toperationId: `${operationId}-${index}`,\n\t\t\tsessionId,\n\t\t\taction,\n\t\t\t// Replay always re-observes so per-action results carry fresh state.\n\t\t\treobserveAfterAction: true,\n\t\t} satisfies DesktopOperationRequestV1;\n\t});\n\treturn {\n\t\tversion: 1,\n\t\tsessionId,\n\t\toperations,\n\t\tstopOnFailure: input.stopOnFailure === undefined ? true : input.stopOnFailure === true,\n\t};\n}\n\nfunction desktopReplayResult(value: unknown, operationId: string): unknown {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst result = value as Record<string, unknown>;\n\tif (\n\t\tresult.version !== 1 ||\n\t\t(result.status !== \"succeeded\" &&\n\t\t\tresult.status !== \"failed\" &&\n\t\t\tresult.status !== \"cancelled\" &&\n\t\t\tresult.status !== \"needs_user\") ||\n\t\t!Array.isArray(result.results)\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tconst results = result.results.map((entry) => {\n\t\tif (entry === null || typeof entry !== \"object\" || Array.isArray(entry))\n\t\t\tthrow new Error(\"desktop-result-invalid\");\n\t\tconst record = entry as Record<string, unknown>;\n\t\tif (\n\t\t\trecord.version !== 1 ||\n\t\t\ttypeof record.operationId !== \"string\" ||\n\t\t\t(record.status !== \"succeeded\" &&\n\t\t\t\trecord.status !== \"failed\" &&\n\t\t\t\trecord.status !== \"cancelled\" &&\n\t\t\t\trecord.status !== \"needs_user\" &&\n\t\t\t\trecord.status !== \"unsupported\")\n\t\t)\n\t\t\tthrow new Error(\"desktop-result-invalid\");\n\t\treturn {\n\t\t\toperationId: desktopBoundedString(record.operationId, \"replay operationId\"),\n\t\t\tstatus: record.status,\n\t\t\tsummary: desktopBoundedString(record.summary, \"replay summary\"),\n\t\t};\n\t});\n\tconst last = result.results[result.results.length - 1] as Record<string, unknown> | undefined;\n\tconst observation =\n\t\tlast?.observation === undefined ? undefined : projectDesktopObservation(last.observation).observation;\n\tconst needsUser = result.results.find((entry) => (entry as Record<string, unknown>).status === \"needs_user\") as\n\t\t| Record<string, unknown>\n\t\t| undefined;\n\tconst causeCode =\n\t\tneedsUser !== undefined &&\n\t\tneedsUser.error !== null &&\n\t\ttypeof needsUser.error === \"object\" &&\n\t\t\"causeCode\" in needsUser.error &&\n\t\ttypeof (needsUser.error as Record<string, unknown>).causeCode === \"string\"\n\t\t\t? desktopBoundedString((needsUser.error as Record<string, unknown>).causeCode, \"replay causeCode\")\n\t\t\t: undefined;\n\treturn desktopResultWithinBudget({\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: result.status,\n\t\tsummary: result.status === \"succeeded\" ? \"Desktop replay completed\" : \"Desktop replay stopped before completion\",\n\t\tresults,\n\t\t...(observation === undefined ? {} : { observation }),\n\t\t...(result.status === \"needs_user\" && causeCode !== undefined\n\t\t\t? {\n\t\t\t\t\terror: {\n\t\t\t\t\t\tversion: 1 as const,\n\t\t\t\t\t\tcode: \"needs_user\",\n\t\t\t\t\t\tmessage: \"Desktop replay requires user action\",\n\t\t\t\t\t\tcauseCode,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t});\n}\n\nexport function createDesktopInputCapabilityFactoryV1(\n\truntime: DesktopFullControlAdapterV1,\n): CapabilityPluginSyncFactory {\n\treturn (api) => {\n\t\tif (api.host.mode === \"readonly\") return;\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_execute\",\n\t\t\tlabel: \"Execute desktop action\",\n\t\t\tdescription:\n\t\t\t\t\"Execute one bounded UI Automation focus, click, type, key, or scroll action and return a fresh bounded observation; type and key may omit the target to send real keyboard input to the current foreground focus (native dialogs invisible to UI Automation)\",\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tsessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\taction: Type.Object(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: Type.Union([\n\t\t\t\t\t\t\t\tType.Literal(\"focus\"),\n\t\t\t\t\t\t\t\tType.Literal(\"click\"),\n\t\t\t\t\t\t\t\tType.Literal(\"type\"),\n\t\t\t\t\t\t\t\tType.Literal(\"key\"),\n\t\t\t\t\t\t\t\tType.Literal(\"scroll\"),\n\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t// Observed identities; optional for type/key so they can address the\n\t\t\t\t\t\t\t// foreground focus instead. The conditional rules (target required\n\t\t\t\t\t\t\t// for focus/click/scroll, coordinates click-only) are enforced by\n\t\t\t\t\t\t\t// desktopExecuteRequest, not by this schema.\n\t\t\t\t\t\t\ttarget: Type.Optional(\n\t\t\t\t\t\t\t\tType.Union([\n\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\tType.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t// Raw screen pixels; click-only. The conditional click-only rule\n\t\t\t\t\t\t\t\t\t// is enforced by desktopExecuteRequest, not by this schema.\n\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"coordinates\"),\n\t\t\t\t\t\t\t\t\t\t\tx: Type.Integer({ minimum: 0 }),\n\t\t\t\t\t\t\t\t\t\t\ty: Type.Integer({ minimum: 0 }),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\ttext: Type.Optional(Type.String({ maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),\n\t\t\t\t\t\t\tkey: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t),\n\t\t\t\t\tpostconditions: Type.Optional(\n\t\t\t\t\t\tType.Array(\n\t\t\t\t\t\t\tType.Union([\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window-exists\"),\n\t\t\t\t\t\t\t\t\t\twindowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control-exists\"),\n\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"focused\"),\n\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"property-equals\"),\n\t\t\t\t\t\t\t\t\t\ttarget: Type.Union([\n\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tType.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t\t\tproperty: Type.Union([\n\t\t\t\t\t\t\t\t\t\t\tType.Literal(\"enabled\"),\n\t\t\t\t\t\t\t\t\t\t\tType.Literal(\"value\"),\n\t\t\t\t\t\t\t\t\t\t\tType.Literal(\"name\"),\n\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t\t\texpected: Type.Union([\n\t\t\t\t\t\t\t\t\t\t\tType.Boolean(),\n\t\t\t\t\t\t\t\t\t\t\tType.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t{ maxItems: DESKTOP_MAX_POSTCONDITIONS_V1 },\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tconst { input, operationId } = toolInvocation(first, second);\n\t\t\t\tconst signal = signalFrom(third);\n\t\t\t\tif (signal?.aborted)\n\t\t\t\t\treturn desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\");\n\t\t\t\tlet request: DesktopOperationRequestV1;\n\t\t\t\ttry {\n\t\t\t\t\trequest = desktopExecuteRequest(input, operationId);\n\t\t\t\t} catch {\n\t\t\t\t\treturn desktopFailure(operationId, \"desktop_input_invalid\", \"Desktop action input is invalid\");\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst result = runtime.execute(request);\n\t\t\t\t\treturn signal?.aborted\n\t\t\t\t\t\t? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\")\n\t\t\t\t\t\t: desktopExecuteResult(result, request);\n\t\t\t\t} catch {\n\t\t\t\t\treturn desktopFailure(operationId, \"desktop_adapter_failed\", \"The selected desktop adapter failed\");\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t\tconst replay = runtime.replay;\n\t\tif (replay === undefined) return;\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_replay\",\n\t\t\tlabel: \"Replay desktop actions\",\n\t\t\tdescription:\n\t\t\t\t\"Replay a bounded sequence of desktop actions against one session; stops at the first failure, cancellation, or user-confirmation pause by default. Recorded foreground type/key entries may omit the target\",\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tsessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\tactions: Type.Array(\n\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkind: Type.Union([\n\t\t\t\t\t\t\t\t\tType.Literal(\"focus\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"click\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"type\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"key\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"scroll\"),\n\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t// Optional for type/key (foreground replay entries); the per-kind\n\t\t\t\t\t\t\t\t// rule is enforced by desktopReplayActionInput, not by this schema.\n\t\t\t\t\t\t\t\ttarget: Type.Optional(\n\t\t\t\t\t\t\t\t\tType.Union([\n\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\t\tType.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\ttext: Type.Optional(Type.String({ maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),\n\t\t\t\t\t\t\t\tkey: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{ minItems: 1, maxItems: DESKTOP_MAX_REPLAY_ACTIONS_V1 },\n\t\t\t\t\t),\n\t\t\t\t\tstopOnFailure: Type.Optional(Type.Boolean()),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tconst { input, operationId } = toolInvocation(first, second);\n\t\t\t\tconst signal = signalFrom(third);\n\t\t\t\tif (signal?.aborted)\n\t\t\t\t\treturn desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\");\n\t\t\t\tlet request: DesktopReplayRequestV1;\n\t\t\t\ttry {\n\t\t\t\t\trequest = desktopReplayRequest(input, operationId);\n\t\t\t\t} catch {\n\t\t\t\t\treturn desktopFailure(operationId, \"desktop_input_invalid\", \"Desktop replay input is invalid\");\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst result = replay(request);\n\t\t\t\t\treturn signal?.aborted\n\t\t\t\t\t\t? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\")\n\t\t\t\t\t\t: desktopReplayResult(result, operationId);\n\t\t\t\t} catch {\n\t\t\t\t\treturn desktopFailure(operationId, \"desktop_adapter_failed\", \"The selected desktop adapter failed\");\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t};\n}\n"]}
1
+ {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAc3E,OAAO,KAAK,EACX,2BAA2B,EAI3B,MAAM,YAAY,CAAC;AA8VpB,wBAAgB,qCAAqC,CACpD,OAAO,EAAE,2BAA2B,GAClC,2BAA2B,CAoX7B","sourcesContent":["/**\n * Bounded desktop input and replay capability factory, migrated from\n * agent-forge `src/profile/runtime-capabilities-desktop-input.ts`\n * (`desktopInputFactory`, D-075 S3 extraction). Differences from the host\n * original:\n * - The factory type is the public `CapabilityPluginSyncFactory` from the\n * plugin SDK instead of the host-internal `BuiltinCapabilityPlugin`.\n * - Projection helpers live in `projection.ts`, input helpers in `shared.ts`.\n * Tool names, budgets and result shapes are unchanged, including the\n * readonly-mode refusal to register input tools and the optional replay\n * registration when the runtime exposes a replay method. Since the 2026-10-13\n * product decision, type/key actions may omit the target: the request is routed\n * to the driver's foreground keyboard-queue injection instead of being rejected\n * (user ruling: \"AI 操作需要的是任何情况下都能操作,和人一样操作电脑\").\n */\nimport type { CapabilityPluginSyncFactory } from \"@agent-forge/plugin-sdk\";\nimport { Type } from \"typebox\";\nimport {\n\tDESKTOP_MAX_POSTCONDITIONS_V1,\n\tDESKTOP_MAX_REPLAY_ACTIONS_V1,\n\tDESKTOP_MAX_STRING_CHARS_V1,\n\tDESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\tdesktopBoundedString,\n\tdesktopFailure,\n\tdesktopRequiredString,\n\tdesktopResultWithinBudget,\n\tprojectDesktopObservation,\n} from \"./projection.ts\";\nimport { signalFrom, toolInvocation } from \"./shared.ts\";\nimport type {\n\tDesktopFullControlAdapterV1,\n\tDesktopOperationRequestV1,\n\tDesktopPostconditionV1,\n\tDesktopReplayRequestV1,\n} from \"./types.ts\";\n\n/** Surface the original validator/adapter diagnostic: the model needs it to correct the call. */\nfunction errorDetail(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction desktopTarget(input: unknown, allowCoordinates: boolean): DesktopOperationRequestV1[\"action\"][\"target\"] {\n\tif (input === null || typeof input !== \"object\" || Array.isArray(input)) throw new Error(\"desktop-target-invalid\");\n\tconst target = input as Record<string, unknown>;\n\tif (target.kind === \"window\") {\n\t\tdesktopExactKeys(target, [\"kind\", \"windowId\"]);\n\t\treturn { kind: \"window\", windowId: desktopRequiredString(target.windowId, \"windowId\") };\n\t}\n\tif (target.kind === \"control\") {\n\t\tdesktopExactKeys(target, [\"kind\", \"controlId\", \"windowId\"]);\n\t\treturn {\n\t\t\tkind: \"control\",\n\t\t\tcontrolId: desktopRequiredString(target.controlId, \"controlId\"),\n\t\t\t...(target.windowId === undefined ? {} : { windowId: desktopRequiredString(target.windowId, \"windowId\") }),\n\t\t};\n\t}\n\t// Raw screen-pixel coordinates are accepted for click actions only; the\n\t// schema union cannot express that condition, so this validator rejects it.\n\tif (target.kind === \"coordinates\") {\n\t\tif (!allowCoordinates) throw new Error(\"desktop-target-invalid\");\n\t\tdesktopExactKeys(target, [\"kind\", \"x\", \"y\"]);\n\t\tif (\n\t\t\ttypeof target.x !== \"number\" ||\n\t\t\t!Number.isInteger(target.x) ||\n\t\t\ttarget.x < 0 ||\n\t\t\ttypeof target.y !== \"number\" ||\n\t\t\t!Number.isInteger(target.y) ||\n\t\t\ttarget.y < 0\n\t\t)\n\t\t\tthrow new Error(\"desktop-target-invalid\");\n\t\treturn { kind: \"coordinates\", x: target.x, y: target.y };\n\t}\n\tthrow new Error(\"desktop-target-invalid\");\n}\n\nfunction desktopExactKeys(value: Record<string, unknown>, allowed: readonly string[]): void {\n\tif (Object.keys(value).some((key) => !allowed.includes(key))) throw new Error(\"desktop-input-invalid\");\n}\n\n/**\n * Target validation with the foreground-input exception: type and key may omit\n * the target entirely. A target-less type/key is routed by the driver to the\n * real keyboard queue at the current focus (FOREGROUND_INPUT_SCRIPT) — the only\n * path that reaches UIA-invisible surfaces such as the native file dialog's\n * name box. Every other kind still requires an observed identity: a focus,\n * click or scroll without a target has no addressable subject.\n */\nfunction desktopActionTarget(\n\tinput: unknown,\n\tkind: DesktopOperationRequestV1[\"action\"][\"kind\"],\n): DesktopOperationRequestV1[\"action\"][\"target\"] | undefined {\n\tif (input === undefined) {\n\t\tif (kind === \"type\" || kind === \"key\") return undefined;\n\t\tthrow new Error(\"desktop-target-required\");\n\t}\n\treturn desktopTarget(input, kind === \"click\");\n}\n\nfunction desktopPostconditions(input: unknown): readonly DesktopPostconditionV1[] | undefined {\n\tif (input === undefined) return undefined;\n\tif (!Array.isArray(input) || input.length > DESKTOP_MAX_POSTCONDITIONS_V1)\n\t\tthrow new Error(\"desktop-postconditions-invalid\");\n\treturn input.map((entry) => {\n\t\tif (entry === null || typeof entry !== \"object\" || Array.isArray(entry))\n\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\tconst value = entry as Record<string, unknown>;\n\t\tif (value.kind === \"window-exists\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"windowId\"]);\n\t\t\treturn { kind: \"window-exists\", windowId: desktopRequiredString(value.windowId, \"windowId\") } as const;\n\t\t}\n\t\tif (value.kind === \"control-exists\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"controlId\"]);\n\t\t\treturn { kind: \"control-exists\", controlId: desktopRequiredString(value.controlId, \"controlId\") } as const;\n\t\t}\n\t\tif (value.kind === \"focused\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"controlId\"]);\n\t\t\treturn { kind: \"focused\", controlId: desktopRequiredString(value.controlId, \"controlId\") } as const;\n\t\t}\n\t\tif (value.kind === \"property-equals\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"target\", \"property\", \"expected\"]);\n\t\t\tif (value.property !== \"enabled\" && value.property !== \"value\" && value.property !== \"name\")\n\t\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\t\tif (\n\t\t\t\t(value.property === \"enabled\" && typeof value.expected !== \"boolean\") ||\n\t\t\t\t(value.property !== \"enabled\" && typeof value.expected !== \"string\")\n\t\t\t)\n\t\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\t\treturn {\n\t\t\t\tkind: \"property-equals\",\n\t\t\t\ttarget: desktopTarget(value.target, false),\n\t\t\t\tproperty: value.property,\n\t\t\t\texpected:\n\t\t\t\t\ttypeof value.expected === \"string\"\n\t\t\t\t\t\t? desktopBoundedString(value.expected, \"postcondition expected\")\n\t\t\t\t\t\t: value.expected,\n\t\t\t} as DesktopPostconditionV1;\n\t\t}\n\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t});\n}\n\nfunction desktopExecuteRequest(input: Record<string, unknown>, operationId: string): DesktopOperationRequestV1 {\n\tdesktopExactKeys(input, [\"sessionId\", \"action\", \"postconditions\"]);\n\tconst actionInput = input.action;\n\tif (actionInput === null || typeof actionInput !== \"object\" || Array.isArray(actionInput))\n\t\tthrow new Error(\"desktop-action-invalid\");\n\tconst action = actionInput as Record<string, unknown>;\n\tdesktopExactKeys(action, [\"kind\", \"target\", \"text\", \"key\"]);\n\tif (\n\t\taction.kind !== \"focus\" &&\n\t\taction.kind !== \"click\" &&\n\t\taction.kind !== \"type\" &&\n\t\taction.kind !== \"key\" &&\n\t\taction.kind !== \"scroll\"\n\t)\n\t\tthrow new Error(\"desktop-action-invalid\");\n\tconst target = desktopActionTarget(action.target, action.kind);\n\tconst text =\n\t\taction.kind === \"type\" || action.kind === \"scroll\" ? desktopBoundedString(action.text, \"text\") : undefined;\n\tif (text !== undefined && text.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst key = action.kind === \"key\" ? desktopBoundedString(action.key, \"key\") : undefined;\n\tif (key !== undefined && key.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst postconditions = desktopPostconditions(input.postconditions);\n\t// Postcondition scoping for foreground actions: a target-less type/key has no\n\t// action target, so a target-level postcondition cannot describe its effect.\n\t// `property-equals` is the only kind that carries a target; pair it with a\n\t// target-less action and the check would silently assert state the action\n\t// never addressed. Global session-state checks (window-exists,\n\t// control-exists, focused) and the no-postcondition case stay allowed.\n\tif (target === undefined && postconditions?.some((condition) => condition.kind === \"property-equals\"))\n\t\tthrow new Error(\"desktop-postcondition-target-without-action-target\");\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tsessionId: desktopRequiredString(input.sessionId, \"sessionId\"),\n\t\taction: {\n\t\t\tversion: 1,\n\t\t\tkind: action.kind,\n\t\t\t...(target === undefined ? {} : { target }),\n\t\t\t...(text === undefined ? {} : { text }),\n\t\t\t...(key === undefined ? {} : { key }),\n\t\t},\n\t\t...(postconditions === undefined ? {} : { postconditions }),\n\t\t// Input plugin operations always request a fresh observation; callers may\n\t\t// not turn this off because target identity otherwise goes stale.\n\t\treobserveAfterAction: true,\n\t};\n}\n\nfunction desktopVerification(\n\tvalue: unknown,\n): { readonly status: \"passed\" | \"failed\" | \"unknown\"; readonly checks: readonly string[] } | undefined {\n\tif (value === undefined) return undefined;\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst verification = value as Record<string, unknown>;\n\tif (\n\t\t(verification.status !== \"passed\" && verification.status !== \"failed\" && verification.status !== \"unknown\") ||\n\t\t!Array.isArray(verification.checks) ||\n\t\tverification.checks.length > DESKTOP_MAX_POSTCONDITIONS_V1\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\treturn {\n\t\tstatus: verification.status,\n\t\tchecks: verification.checks.map((check) => desktopBoundedString(check, \"verification check\")),\n\t};\n}\n\nfunction desktopExecuteResult(value: unknown, request: DesktopOperationRequestV1) {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst result = value as Record<string, unknown>;\n\tif (\n\t\tresult.version !== 1 ||\n\t\tresult.operationId !== request.operationId ||\n\t\t(result.status !== \"succeeded\" &&\n\t\t\tresult.status !== \"failed\" &&\n\t\t\tresult.status !== \"cancelled\" &&\n\t\t\tresult.status !== \"needs_user\" &&\n\t\t\tresult.status !== \"unsupported\")\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tconst observation = result.observation === undefined ? undefined : projectDesktopObservation(result.observation);\n\tif (\n\t\tresult.status === \"succeeded\" &&\n\t\t(observation === undefined || observation.observation.sessionId !== request.sessionId)\n\t) {\n\t\treturn desktopFailure(\n\t\t\trequest.operationId,\n\t\t\t\"verification_unavailable\",\n\t\t\t\"Desktop action did not produce a fresh observation\",\n\t\t);\n\t}\n\tconst base = {\n\t\tversion: 1 as const,\n\t\toperationId: request.operationId,\n\t\tstatus: result.status,\n\t\tsummary: result.status === \"succeeded\" ? \"Desktop action completed\" : \"Desktop action could not be completed\",\n\t\t...(observation === undefined ? {} : observation),\n\t\t...(desktopVerification(result.verification) === undefined\n\t\t\t? {}\n\t\t\t: { verification: desktopVerification(result.verification) }),\n\t};\n\tif (result.status === \"succeeded\") return desktopResultWithinBudget(base);\n\tconst error = result.error;\n\tif (error === null || typeof error !== \"object\" || Array.isArray(error)) throw new Error(\"desktop-result-invalid\");\n\tconst errorValue = error as Record<string, unknown>;\n\tconst causeCode =\n\t\tresult.status === \"needs_user\" && typeof errorValue.causeCode === \"string\"\n\t\t\t? desktopBoundedString(errorValue.causeCode, \"error causeCode\")\n\t\t\t: undefined;\n\treturn desktopResultWithinBudget({\n\t\t...base,\n\t\terror: {\n\t\t\tversion: 1 as const,\n\t\t\tcode: result.status === \"needs_user\" ? \"needs_user\" : \"desktop_action_failed\",\n\t\t\tmessage: result.status === \"needs_user\" ? \"Desktop action requires user action\" : \"Desktop action failed\",\n\t\t\t...(causeCode === undefined ? {} : { causeCode }),\n\t\t},\n\t});\n}\n\nfunction desktopReplayActionInput(raw: unknown): DesktopOperationRequestV1[\"action\"] {\n\tif (raw === null || typeof raw !== \"object\" || Array.isArray(raw)) throw new Error(\"desktop-action-invalid\");\n\tconst action = raw as Record<string, unknown>;\n\tdesktopExactKeys(action, [\"kind\", \"target\", \"text\", \"key\"]);\n\tif (\n\t\taction.kind !== \"focus\" &&\n\t\taction.kind !== \"click\" &&\n\t\taction.kind !== \"type\" &&\n\t\taction.kind !== \"key\" &&\n\t\taction.kind !== \"scroll\"\n\t)\n\t\tthrow new Error(\"desktop-action-invalid\");\n\t// Replay stays anchored to observed identities; coordinates are execute-only.\n\t// Recorded foreground type/key entries (no target) replay through the same\n\t// driver foreground-injection path as desktop_execute.\n\tconst target = desktopActionTarget(action.target, action.kind);\n\tconst text =\n\t\taction.kind === \"type\" || action.kind === \"scroll\" ? desktopBoundedString(action.text, \"text\") : undefined;\n\tif (text !== undefined && text.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst key = action.kind === \"key\" ? desktopBoundedString(action.key, \"key\") : undefined;\n\tif (key !== undefined && key.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\treturn {\n\t\tversion: 1,\n\t\tkind: action.kind,\n\t\t...(target === undefined ? {} : { target }),\n\t\t...(text === undefined ? {} : { text }),\n\t\t...(key === undefined ? {} : { key }),\n\t};\n}\n\nfunction desktopReplayRequest(input: Record<string, unknown>, operationId: string): DesktopReplayRequestV1 {\n\tdesktopExactKeys(input, [\"sessionId\", \"actions\", \"stopOnFailure\"]);\n\tif (\n\t\t!Array.isArray(input.actions) ||\n\t\tinput.actions.length === 0 ||\n\t\tinput.actions.length > DESKTOP_MAX_REPLAY_ACTIONS_V1\n\t)\n\t\tthrow new Error(\"desktop-replay-actions-invalid\");\n\tconst sessionId = desktopRequiredString(input.sessionId, \"sessionId\");\n\tconst operations = input.actions.map((raw, index) => {\n\t\tconst action = desktopReplayActionInput(raw);\n\t\treturn {\n\t\t\tversion: 1 as const,\n\t\t\toperationId: `${operationId}-${index}`,\n\t\t\tsessionId,\n\t\t\taction,\n\t\t\t// Replay always re-observes so per-action results carry fresh state.\n\t\t\treobserveAfterAction: true,\n\t\t} satisfies DesktopOperationRequestV1;\n\t});\n\treturn {\n\t\tversion: 1,\n\t\tsessionId,\n\t\toperations,\n\t\tstopOnFailure: input.stopOnFailure === undefined ? true : input.stopOnFailure === true,\n\t};\n}\n\nfunction desktopReplayResult(value: unknown, operationId: string): unknown {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst result = value as Record<string, unknown>;\n\tif (\n\t\tresult.version !== 1 ||\n\t\t(result.status !== \"succeeded\" &&\n\t\t\tresult.status !== \"failed\" &&\n\t\t\tresult.status !== \"cancelled\" &&\n\t\t\tresult.status !== \"needs_user\") ||\n\t\t!Array.isArray(result.results)\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tconst results = result.results.map((entry) => {\n\t\tif (entry === null || typeof entry !== \"object\" || Array.isArray(entry))\n\t\t\tthrow new Error(\"desktop-result-invalid\");\n\t\tconst record = entry as Record<string, unknown>;\n\t\tif (\n\t\t\trecord.version !== 1 ||\n\t\t\ttypeof record.operationId !== \"string\" ||\n\t\t\t(record.status !== \"succeeded\" &&\n\t\t\t\trecord.status !== \"failed\" &&\n\t\t\t\trecord.status !== \"cancelled\" &&\n\t\t\t\trecord.status !== \"needs_user\" &&\n\t\t\t\trecord.status !== \"unsupported\")\n\t\t)\n\t\t\tthrow new Error(\"desktop-result-invalid\");\n\t\treturn {\n\t\t\toperationId: desktopBoundedString(record.operationId, \"replay operationId\"),\n\t\t\tstatus: record.status,\n\t\t\tsummary: desktopBoundedString(record.summary, \"replay summary\"),\n\t\t};\n\t});\n\tconst last = result.results[result.results.length - 1] as Record<string, unknown> | undefined;\n\tconst observation =\n\t\tlast?.observation === undefined ? undefined : projectDesktopObservation(last.observation).observation;\n\tconst needsUser = result.results.find((entry) => (entry as Record<string, unknown>).status === \"needs_user\") as\n\t\t| Record<string, unknown>\n\t\t| undefined;\n\tconst causeCode =\n\t\tneedsUser !== undefined &&\n\t\tneedsUser.error !== null &&\n\t\ttypeof needsUser.error === \"object\" &&\n\t\t\"causeCode\" in needsUser.error &&\n\t\ttypeof (needsUser.error as Record<string, unknown>).causeCode === \"string\"\n\t\t\t? desktopBoundedString((needsUser.error as Record<string, unknown>).causeCode, \"replay causeCode\")\n\t\t\t: undefined;\n\treturn desktopResultWithinBudget({\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: result.status,\n\t\tsummary: result.status === \"succeeded\" ? \"Desktop replay completed\" : \"Desktop replay stopped before completion\",\n\t\tresults,\n\t\t...(observation === undefined ? {} : { observation }),\n\t\t...(result.status === \"needs_user\" && causeCode !== undefined\n\t\t\t? {\n\t\t\t\t\terror: {\n\t\t\t\t\t\tversion: 1 as const,\n\t\t\t\t\t\tcode: \"needs_user\",\n\t\t\t\t\t\tmessage: \"Desktop replay requires user action\",\n\t\t\t\t\t\tcauseCode,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t});\n}\n\nexport function createDesktopInputCapabilityFactoryV1(\n\truntime: DesktopFullControlAdapterV1,\n): CapabilityPluginSyncFactory {\n\treturn (api) => {\n\t\tif (api.host.mode === \"readonly\") return;\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_execute\",\n\t\t\tlabel: \"Execute desktop action\",\n\t\t\tdescription:\n\t\t\t\t\"Execute one bounded UI Automation focus, click, type, key, or scroll action and return a fresh bounded observation; type and key may omit the target to send real keyboard input to the current foreground focus (native dialogs invisible to UI Automation)\",\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tsessionId: Type.String({\n\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\tdescription: \"Session id from a previous desktop observation; a fresh observation is returned\",\n\t\t\t\t\t}),\n\t\t\t\t\taction: Type.Object(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: Type.Union(\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\tType.Literal(\"focus\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"click\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"type\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"key\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"scroll\"),\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t{ description: \"focus, click, type, key, or scroll\" },\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t// Observed identities; optional for type/key so they can address the\n\t\t\t\t\t\t\t// foreground focus instead. The conditional rules (target required\n\t\t\t\t\t\t\t// for focus/click/scroll, coordinates click-only) are enforced by\n\t\t\t\t\t\t\t// desktopExecuteRequest, not by this schema.\n\t\t\t\t\t\t\ttarget: Type.Optional(\n\t\t\t\t\t\t\t\tType.Union(\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Window id from a previous observation\",\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Control id from a previous observation; a stale identity fails with stale_target\",\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Optional owning-window id for the control lookup\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t// Raw screen pixels; click-only. The conditional click-only rule\n\t\t\t\t\t\t\t\t\t\t// is enforced by desktopExecuteRequest, not by this schema.\n\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"coordinates\"),\n\t\t\t\t\t\t\t\t\t\t\t\tx: Type.Integer({\n\t\t\t\t\t\t\t\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Raw screen-pixel coordinate (non-negative integer); valid only for click\",\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\ty: Type.Integer({\n\t\t\t\t\t\t\t\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Raw screen-pixel coordinate (non-negative integer); valid only for click\",\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\"Observed window/control identity, or raw screen coordinates for click only; omit only for type/key\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\ttext: Type.Optional(\n\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\"Text for type, or scroll direction as up|down with optional :lines (1..100, default 3)\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tkey: Type.Optional(\n\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\"Key sequence for key: +-joined modifiers (ctrl, alt, shift, meta/win) plus a named key or single character; sent via the real keyboard queue\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ additionalProperties: false, description: \"Exactly one action object; unknown keys are rejected\" },\n\t\t\t\t\t),\n\t\t\t\t\tpostconditions: Type.Optional(\n\t\t\t\t\t\tType.Array(\n\t\t\t\t\t\t\tType.Union([\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window-exists\"),\n\t\t\t\t\t\t\t\t\t\twindowId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\tdescription: \"Window id that must exist after the action\",\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control-exists\"),\n\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\tdescription: \"Control id that must still exist after the action\",\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"focused\"),\n\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\tdescription: \"Control id that must hold keyboard focus after the action\",\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"property-equals\"),\n\t\t\t\t\t\t\t\t\t\ttarget: Type.Union(\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Window id from a previous observation\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Control id from a previous observation; a stale identity fails with stale_target\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Optional owning-window id for the control lookup\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Window or control whose property is compared (coordinates not allowed)\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tproperty: Type.Union(\n\t\t\t\t\t\t\t\t\t\t\t[Type.Literal(\"enabled\"), Type.Literal(\"value\"), Type.Literal(\"name\")],\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"enabled (boolean expected), value, or name (string expected)\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\texpected: Type.Union(\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\tType.Boolean(),\n\t\t\t\t\t\t\t\t\t\t\t\tType.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Expected value: boolean for enabled, non-empty string for value/name\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmaxItems: DESKTOP_MAX_POSTCONDITIONS_V1,\n\t\t\t\t\t\t\t\tdescription: \"Up to 32 checks evaluated against the fresh observation after the action\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tconst { input, operationId } = toolInvocation(first, second);\n\t\t\t\tconst signal = signalFrom(third);\n\t\t\t\tif (signal?.aborted)\n\t\t\t\t\treturn desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\");\n\t\t\t\tlet request: DesktopOperationRequestV1;\n\t\t\t\ttry {\n\t\t\t\t\trequest = desktopExecuteRequest(input, operationId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn desktopFailure(\n\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\"desktop_input_invalid\",\n\t\t\t\t\t\t`Desktop action input is invalid: ${errorDetail(error)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst result = runtime.execute(request);\n\t\t\t\t\treturn signal?.aborted\n\t\t\t\t\t\t? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\")\n\t\t\t\t\t\t: desktopExecuteResult(result, request);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn desktopFailure(\n\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\"desktop_adapter_failed\",\n\t\t\t\t\t\t`The selected desktop adapter failed: ${errorDetail(error)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t\tconst replay = runtime.replay;\n\t\tif (replay === undefined) return;\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_replay\",\n\t\t\tlabel: \"Replay desktop actions\",\n\t\t\tdescription:\n\t\t\t\t\"Replay a bounded sequence of desktop actions against one session; stops at the first failure, cancellation, or user-confirmation pause by default. Recorded foreground type/key entries may omit the target\",\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tsessionId: Type.String({\n\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\tdescription: \"Session id from a previous desktop observation; all actions replay against it\",\n\t\t\t\t\t}),\n\t\t\t\t\tactions: Type.Array(\n\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkind: Type.Union(\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\tType.Literal(\"focus\"),\n\t\t\t\t\t\t\t\t\t\tType.Literal(\"click\"),\n\t\t\t\t\t\t\t\t\t\tType.Literal(\"type\"),\n\t\t\t\t\t\t\t\t\t\tType.Literal(\"key\"),\n\t\t\t\t\t\t\t\t\t\tType.Literal(\"scroll\"),\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t{ description: \"focus, click, type, key, or scroll\" },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t// Optional for type/key (foreground replay entries); the per-kind\n\t\t\t\t\t\t\t\t// rule is enforced by desktopReplayActionInput, not by this schema.\n\t\t\t\t\t\t\t\ttarget: Type.Optional(\n\t\t\t\t\t\t\t\t\tType.Union(\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Window id from a previous observation\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Control id from a previous observation; a stale identity fails with stale_target\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Optional owning-window id for the control lookup\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\"Observed window/control identity; omit only for recorded foreground type/key entries (no coordinates in replay)\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\ttext: Type.Optional(\n\t\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\"Text for type, or scroll direction as up|down with optional :lines (1..100, default 3)\",\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tkey: Type.Optional(\n\t\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\"Key sequence for key: +-joined modifiers (ctrl, alt, shift, meta/win) plus a named key or single character; sent via the real keyboard queue\",\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tminItems: 1,\n\t\t\t\t\t\t\tmaxItems: DESKTOP_MAX_REPLAY_ACTIONS_V1,\n\t\t\t\t\t\t\tdescription: \"1..32 actions replayed in order\",\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t\tstopOnFailure: Type.Optional(\n\t\t\t\t\t\tType.Boolean({\n\t\t\t\t\t\t\tdescription: \"Stop at the first failure when true (default); false continues through failures\",\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tconst { input, operationId } = toolInvocation(first, second);\n\t\t\t\tconst signal = signalFrom(third);\n\t\t\t\tif (signal?.aborted)\n\t\t\t\t\treturn desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\");\n\t\t\t\tlet request: DesktopReplayRequestV1;\n\t\t\t\ttry {\n\t\t\t\t\trequest = desktopReplayRequest(input, operationId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn desktopFailure(\n\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\"desktop_input_invalid\",\n\t\t\t\t\t\t`Desktop replay input is invalid: ${errorDetail(error)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst result = replay(request);\n\t\t\t\t\treturn signal?.aborted\n\t\t\t\t\t\t? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\")\n\t\t\t\t\t\t: desktopReplayResult(result, operationId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn desktopFailure(\n\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\"desktop_adapter_failed\",\n\t\t\t\t\t\t`The selected desktop adapter failed: ${errorDetail(error)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t};\n}\n"]}
@@ -1,6 +1,10 @@
1
1
  import { Type } from "typebox";
2
2
  import { DESKTOP_MAX_POSTCONDITIONS_V1, DESKTOP_MAX_REPLAY_ACTIONS_V1, DESKTOP_MAX_STRING_CHARS_V1, DESKTOP_MAX_TYPE_TEXT_CHARS_V1, desktopBoundedString, desktopFailure, desktopRequiredString, desktopResultWithinBudget, projectDesktopObservation, } from "./projection.js";
3
3
  import { signalFrom, toolInvocation } from "./shared.js";
4
+ /** Surface the original validator/adapter diagnostic: the model needs it to correct the call. */
5
+ function errorDetail(error) {
6
+ return error instanceof Error ? error.message : String(error);
7
+ }
4
8
  function desktopTarget(input, allowCoordinates) {
5
9
  if (input === null || typeof input !== "object" || Array.isArray(input))
6
10
  throw new Error("desktop-target-invalid");
@@ -322,7 +326,11 @@ export function createDesktopInputCapabilityFactoryV1(runtime) {
322
326
  label: "Execute desktop action",
323
327
  description: "Execute one bounded UI Automation focus, click, type, key, or scroll action and return a fresh bounded observation; type and key may omit the target to send real keyboard input to the current foreground focus (native dialogs invisible to UI Automation)",
324
328
  parameters: Type.Object({
325
- sessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
329
+ sessionId: Type.String({
330
+ minLength: 1,
331
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
332
+ description: "Session id from a previous desktop observation; a fresh observation is returned",
333
+ }),
326
334
  action: Type.Object({
327
335
  kind: Type.Union([
328
336
  Type.Literal("focus"),
@@ -330,7 +338,7 @@ export function createDesktopInputCapabilityFactoryV1(runtime) {
330
338
  Type.Literal("type"),
331
339
  Type.Literal("key"),
332
340
  Type.Literal("scroll"),
333
- ]),
341
+ ], { description: "focus, click, type, key, or scroll" }),
334
342
  // Observed identities; optional for type/key so they can address the
335
343
  // foreground focus instead. The conditional rules (target required
336
344
  // for focus/click/scroll, coordinates click-only) are enforced by
@@ -338,61 +346,117 @@ export function createDesktopInputCapabilityFactoryV1(runtime) {
338
346
  target: Type.Optional(Type.Union([
339
347
  Type.Object({
340
348
  kind: Type.Literal("window"),
341
- windowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
349
+ windowId: Type.String({
350
+ minLength: 1,
351
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
352
+ description: "Window id from a previous observation",
353
+ }),
342
354
  }, { additionalProperties: false }),
343
355
  Type.Object({
344
356
  kind: Type.Literal("control"),
345
- controlId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
346
- windowId: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 })),
357
+ controlId: Type.String({
358
+ minLength: 1,
359
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
360
+ description: "Control id from a previous observation; a stale identity fails with stale_target",
361
+ }),
362
+ windowId: Type.Optional(Type.String({
363
+ minLength: 1,
364
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
365
+ description: "Optional owning-window id for the control lookup",
366
+ })),
347
367
  }, { additionalProperties: false }),
348
368
  // Raw screen pixels; click-only. The conditional click-only rule
349
369
  // is enforced by desktopExecuteRequest, not by this schema.
350
370
  Type.Object({
351
371
  kind: Type.Literal("coordinates"),
352
- x: Type.Integer({ minimum: 0 }),
353
- y: Type.Integer({ minimum: 0 }),
372
+ x: Type.Integer({
373
+ minimum: 0,
374
+ description: "Raw screen-pixel coordinate (non-negative integer); valid only for click",
375
+ }),
376
+ y: Type.Integer({
377
+ minimum: 0,
378
+ description: "Raw screen-pixel coordinate (non-negative integer); valid only for click",
379
+ }),
354
380
  }, { additionalProperties: false }),
355
- ])),
356
- text: Type.Optional(Type.String({ maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),
357
- key: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),
358
- }, { additionalProperties: false }),
381
+ ], {
382
+ description: "Observed window/control identity, or raw screen coordinates for click only; omit only for type/key",
383
+ })),
384
+ text: Type.Optional(Type.String({
385
+ maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,
386
+ description: "Text for type, or scroll direction as up|down with optional :lines (1..100, default 3)",
387
+ })),
388
+ key: Type.Optional(Type.String({
389
+ minLength: 1,
390
+ maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,
391
+ description: "Key sequence for key: +-joined modifiers (ctrl, alt, shift, meta/win) plus a named key or single character; sent via the real keyboard queue",
392
+ })),
393
+ }, { additionalProperties: false, description: "Exactly one action object; unknown keys are rejected" }),
359
394
  postconditions: Type.Optional(Type.Array(Type.Union([
360
395
  Type.Object({
361
396
  kind: Type.Literal("window-exists"),
362
- windowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
397
+ windowId: Type.String({
398
+ minLength: 1,
399
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
400
+ description: "Window id that must exist after the action",
401
+ }),
363
402
  }, { additionalProperties: false }),
364
403
  Type.Object({
365
404
  kind: Type.Literal("control-exists"),
366
- controlId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
405
+ controlId: Type.String({
406
+ minLength: 1,
407
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
408
+ description: "Control id that must still exist after the action",
409
+ }),
367
410
  }, { additionalProperties: false }),
368
411
  Type.Object({
369
412
  kind: Type.Literal("focused"),
370
- controlId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
413
+ controlId: Type.String({
414
+ minLength: 1,
415
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
416
+ description: "Control id that must hold keyboard focus after the action",
417
+ }),
371
418
  }, { additionalProperties: false }),
372
419
  Type.Object({
373
420
  kind: Type.Literal("property-equals"),
374
421
  target: Type.Union([
375
422
  Type.Object({
376
423
  kind: Type.Literal("window"),
377
- windowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
424
+ windowId: Type.String({
425
+ minLength: 1,
426
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
427
+ description: "Window id from a previous observation",
428
+ }),
378
429
  }, { additionalProperties: false }),
379
430
  Type.Object({
380
431
  kind: Type.Literal("control"),
381
- controlId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
382
- windowId: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 })),
432
+ controlId: Type.String({
433
+ minLength: 1,
434
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
435
+ description: "Control id from a previous observation; a stale identity fails with stale_target",
436
+ }),
437
+ windowId: Type.Optional(Type.String({
438
+ minLength: 1,
439
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
440
+ description: "Optional owning-window id for the control lookup",
441
+ })),
383
442
  }, { additionalProperties: false }),
384
- ]),
385
- property: Type.Union([
386
- Type.Literal("enabled"),
387
- Type.Literal("value"),
388
- Type.Literal("name"),
389
- ]),
443
+ ], {
444
+ description: "Window or control whose property is compared (coordinates not allowed)",
445
+ }),
446
+ property: Type.Union([Type.Literal("enabled"), Type.Literal("value"), Type.Literal("name")], {
447
+ description: "enabled (boolean expected), value, or name (string expected)",
448
+ }),
390
449
  expected: Type.Union([
391
450
  Type.Boolean(),
392
451
  Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
393
- ]),
452
+ ], {
453
+ description: "Expected value: boolean for enabled, non-empty string for value/name",
454
+ }),
394
455
  }, { additionalProperties: false }),
395
- ]), { maxItems: DESKTOP_MAX_POSTCONDITIONS_V1 })),
456
+ ]), {
457
+ maxItems: DESKTOP_MAX_POSTCONDITIONS_V1,
458
+ description: "Up to 32 checks evaluated against the fresh observation after the action",
459
+ })),
396
460
  }, { additionalProperties: false }),
397
461
  execute: async (first, second, third) => {
398
462
  const { input, operationId } = toolInvocation(first, second);
@@ -403,8 +467,8 @@ export function createDesktopInputCapabilityFactoryV1(runtime) {
403
467
  try {
404
468
  request = desktopExecuteRequest(input, operationId);
405
469
  }
406
- catch {
407
- return desktopFailure(operationId, "desktop_input_invalid", "Desktop action input is invalid");
470
+ catch (error) {
471
+ return desktopFailure(operationId, "desktop_input_invalid", `Desktop action input is invalid: ${errorDetail(error)}`);
408
472
  }
409
473
  try {
410
474
  const result = runtime.execute(request);
@@ -412,8 +476,8 @@ export function createDesktopInputCapabilityFactoryV1(runtime) {
412
476
  ? desktopFailure(operationId, "cancelled", "Desktop operation was cancelled", "cancelled")
413
477
  : desktopExecuteResult(result, request);
414
478
  }
415
- catch {
416
- return desktopFailure(operationId, "desktop_adapter_failed", "The selected desktop adapter failed");
479
+ catch (error) {
480
+ return desktopFailure(operationId, "desktop_adapter_failed", `The selected desktop adapter failed: ${errorDetail(error)}`);
417
481
  }
418
482
  },
419
483
  });
@@ -425,7 +489,11 @@ export function createDesktopInputCapabilityFactoryV1(runtime) {
425
489
  label: "Replay desktop actions",
426
490
  description: "Replay a bounded sequence of desktop actions against one session; stops at the first failure, cancellation, or user-confirmation pause by default. Recorded foreground type/key entries may omit the target",
427
491
  parameters: Type.Object({
428
- sessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
492
+ sessionId: Type.String({
493
+ minLength: 1,
494
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
495
+ description: "Session id from a previous desktop observation; all actions replay against it",
496
+ }),
429
497
  actions: Type.Array(Type.Object({
430
498
  kind: Type.Union([
431
499
  Type.Literal("focus"),
@@ -433,24 +501,51 @@ export function createDesktopInputCapabilityFactoryV1(runtime) {
433
501
  Type.Literal("type"),
434
502
  Type.Literal("key"),
435
503
  Type.Literal("scroll"),
436
- ]),
504
+ ], { description: "focus, click, type, key, or scroll" }),
437
505
  // Optional for type/key (foreground replay entries); the per-kind
438
506
  // rule is enforced by desktopReplayActionInput, not by this schema.
439
507
  target: Type.Optional(Type.Union([
440
508
  Type.Object({
441
509
  kind: Type.Literal("window"),
442
- windowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
510
+ windowId: Type.String({
511
+ minLength: 1,
512
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
513
+ description: "Window id from a previous observation",
514
+ }),
443
515
  }, { additionalProperties: false }),
444
516
  Type.Object({
445
517
  kind: Type.Literal("control"),
446
- controlId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
447
- windowId: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 })),
518
+ controlId: Type.String({
519
+ minLength: 1,
520
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
521
+ description: "Control id from a previous observation; a stale identity fails with stale_target",
522
+ }),
523
+ windowId: Type.Optional(Type.String({
524
+ minLength: 1,
525
+ maxLength: DESKTOP_MAX_STRING_CHARS_V1,
526
+ description: "Optional owning-window id for the control lookup",
527
+ })),
448
528
  }, { additionalProperties: false }),
449
- ])),
450
- text: Type.Optional(Type.String({ maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),
451
- key: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),
452
- }, { additionalProperties: false }), { minItems: 1, maxItems: DESKTOP_MAX_REPLAY_ACTIONS_V1 }),
453
- stopOnFailure: Type.Optional(Type.Boolean()),
529
+ ], {
530
+ description: "Observed window/control identity; omit only for recorded foreground type/key entries (no coordinates in replay)",
531
+ })),
532
+ text: Type.Optional(Type.String({
533
+ maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,
534
+ description: "Text for type, or scroll direction as up|down with optional :lines (1..100, default 3)",
535
+ })),
536
+ key: Type.Optional(Type.String({
537
+ minLength: 1,
538
+ maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,
539
+ description: "Key sequence for key: +-joined modifiers (ctrl, alt, shift, meta/win) plus a named key or single character; sent via the real keyboard queue",
540
+ })),
541
+ }, { additionalProperties: false }), {
542
+ minItems: 1,
543
+ maxItems: DESKTOP_MAX_REPLAY_ACTIONS_V1,
544
+ description: "1..32 actions replayed in order",
545
+ }),
546
+ stopOnFailure: Type.Optional(Type.Boolean({
547
+ description: "Stop at the first failure when true (default); false continues through failures",
548
+ })),
454
549
  }, { additionalProperties: false }),
455
550
  execute: async (first, second, third) => {
456
551
  const { input, operationId } = toolInvocation(first, second);
@@ -461,8 +556,8 @@ export function createDesktopInputCapabilityFactoryV1(runtime) {
461
556
  try {
462
557
  request = desktopReplayRequest(input, operationId);
463
558
  }
464
- catch {
465
- return desktopFailure(operationId, "desktop_input_invalid", "Desktop replay input is invalid");
559
+ catch (error) {
560
+ return desktopFailure(operationId, "desktop_input_invalid", `Desktop replay input is invalid: ${errorDetail(error)}`);
466
561
  }
467
562
  try {
468
563
  const result = replay(request);
@@ -470,8 +565,8 @@ export function createDesktopInputCapabilityFactoryV1(runtime) {
470
565
  ? desktopFailure(operationId, "cancelled", "Desktop operation was cancelled", "cancelled")
471
566
  : desktopReplayResult(result, operationId);
472
567
  }
473
- catch {
474
- return desktopFailure(operationId, "desktop_adapter_failed", "The selected desktop adapter failed");
568
+ catch (error) {
569
+ return desktopFailure(operationId, "desktop_adapter_failed", `The selected desktop adapter failed: ${errorDetail(error)}`);
475
570
  }
476
571
  },
477
572
  });
@@ -1 +1 @@
1
- {"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bounded desktop input and replay capability factory, migrated from\n * agent-forge `src/profile/runtime-capabilities-desktop-input.ts`\n * (`desktopInputFactory`, D-075 S3 extraction). Differences from the host\n * original:\n * - The factory type is the public `CapabilityPluginSyncFactory` from the\n * plugin SDK instead of the host-internal `BuiltinCapabilityPlugin`.\n * - Projection helpers live in `projection.ts`, input helpers in `shared.ts`.\n * Tool names, budgets and result shapes are unchanged, including the\n * readonly-mode refusal to register input tools and the optional replay\n * registration when the runtime exposes a replay method. Since the 2026-10-13\n * product decision, type/key actions may omit the target: the request is routed\n * to the driver's foreground keyboard-queue injection instead of being rejected\n * (user ruling: \"AI 操作需要的是任何情况下都能操作,和人一样操作电脑\").\n */\nimport type { CapabilityPluginSyncFactory } from \"@agent-forge/plugin-sdk\";\nimport { Type } from \"typebox\";\nimport {\n\tDESKTOP_MAX_POSTCONDITIONS_V1,\n\tDESKTOP_MAX_REPLAY_ACTIONS_V1,\n\tDESKTOP_MAX_STRING_CHARS_V1,\n\tDESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\tdesktopBoundedString,\n\tdesktopFailure,\n\tdesktopRequiredString,\n\tdesktopResultWithinBudget,\n\tprojectDesktopObservation,\n} from \"./projection.ts\";\nimport { signalFrom, toolInvocation } from \"./shared.ts\";\nimport type {\n\tDesktopFullControlAdapterV1,\n\tDesktopOperationRequestV1,\n\tDesktopPostconditionV1,\n\tDesktopReplayRequestV1,\n} from \"./types.ts\";\n\nfunction desktopTarget(input: unknown, allowCoordinates: boolean): DesktopOperationRequestV1[\"action\"][\"target\"] {\n\tif (input === null || typeof input !== \"object\" || Array.isArray(input)) throw new Error(\"desktop-target-invalid\");\n\tconst target = input as Record<string, unknown>;\n\tif (target.kind === \"window\") {\n\t\tdesktopExactKeys(target, [\"kind\", \"windowId\"]);\n\t\treturn { kind: \"window\", windowId: desktopRequiredString(target.windowId, \"windowId\") };\n\t}\n\tif (target.kind === \"control\") {\n\t\tdesktopExactKeys(target, [\"kind\", \"controlId\", \"windowId\"]);\n\t\treturn {\n\t\t\tkind: \"control\",\n\t\t\tcontrolId: desktopRequiredString(target.controlId, \"controlId\"),\n\t\t\t...(target.windowId === undefined ? {} : { windowId: desktopRequiredString(target.windowId, \"windowId\") }),\n\t\t};\n\t}\n\t// Raw screen-pixel coordinates are accepted for click actions only; the\n\t// schema union cannot express that condition, so this validator rejects it.\n\tif (target.kind === \"coordinates\") {\n\t\tif (!allowCoordinates) throw new Error(\"desktop-target-invalid\");\n\t\tdesktopExactKeys(target, [\"kind\", \"x\", \"y\"]);\n\t\tif (\n\t\t\ttypeof target.x !== \"number\" ||\n\t\t\t!Number.isInteger(target.x) ||\n\t\t\ttarget.x < 0 ||\n\t\t\ttypeof target.y !== \"number\" ||\n\t\t\t!Number.isInteger(target.y) ||\n\t\t\ttarget.y < 0\n\t\t)\n\t\t\tthrow new Error(\"desktop-target-invalid\");\n\t\treturn { kind: \"coordinates\", x: target.x, y: target.y };\n\t}\n\tthrow new Error(\"desktop-target-invalid\");\n}\n\nfunction desktopExactKeys(value: Record<string, unknown>, allowed: readonly string[]): void {\n\tif (Object.keys(value).some((key) => !allowed.includes(key))) throw new Error(\"desktop-input-invalid\");\n}\n\n/**\n * Target validation with the foreground-input exception: type and key may omit\n * the target entirely. A target-less type/key is routed by the driver to the\n * real keyboard queue at the current focus (FOREGROUND_INPUT_SCRIPT) — the only\n * path that reaches UIA-invisible surfaces such as the native file dialog's\n * name box. Every other kind still requires an observed identity: a focus,\n * click or scroll without a target has no addressable subject.\n */\nfunction desktopActionTarget(\n\tinput: unknown,\n\tkind: DesktopOperationRequestV1[\"action\"][\"kind\"],\n): DesktopOperationRequestV1[\"action\"][\"target\"] | undefined {\n\tif (input === undefined) {\n\t\tif (kind === \"type\" || kind === \"key\") return undefined;\n\t\tthrow new Error(\"desktop-target-required\");\n\t}\n\treturn desktopTarget(input, kind === \"click\");\n}\n\nfunction desktopPostconditions(input: unknown): readonly DesktopPostconditionV1[] | undefined {\n\tif (input === undefined) return undefined;\n\tif (!Array.isArray(input) || input.length > DESKTOP_MAX_POSTCONDITIONS_V1)\n\t\tthrow new Error(\"desktop-postconditions-invalid\");\n\treturn input.map((entry) => {\n\t\tif (entry === null || typeof entry !== \"object\" || Array.isArray(entry))\n\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\tconst value = entry as Record<string, unknown>;\n\t\tif (value.kind === \"window-exists\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"windowId\"]);\n\t\t\treturn { kind: \"window-exists\", windowId: desktopRequiredString(value.windowId, \"windowId\") } as const;\n\t\t}\n\t\tif (value.kind === \"control-exists\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"controlId\"]);\n\t\t\treturn { kind: \"control-exists\", controlId: desktopRequiredString(value.controlId, \"controlId\") } as const;\n\t\t}\n\t\tif (value.kind === \"focused\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"controlId\"]);\n\t\t\treturn { kind: \"focused\", controlId: desktopRequiredString(value.controlId, \"controlId\") } as const;\n\t\t}\n\t\tif (value.kind === \"property-equals\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"target\", \"property\", \"expected\"]);\n\t\t\tif (value.property !== \"enabled\" && value.property !== \"value\" && value.property !== \"name\")\n\t\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\t\tif (\n\t\t\t\t(value.property === \"enabled\" && typeof value.expected !== \"boolean\") ||\n\t\t\t\t(value.property !== \"enabled\" && typeof value.expected !== \"string\")\n\t\t\t)\n\t\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\t\treturn {\n\t\t\t\tkind: \"property-equals\",\n\t\t\t\ttarget: desktopTarget(value.target, false),\n\t\t\t\tproperty: value.property,\n\t\t\t\texpected:\n\t\t\t\t\ttypeof value.expected === \"string\"\n\t\t\t\t\t\t? desktopBoundedString(value.expected, \"postcondition expected\")\n\t\t\t\t\t\t: value.expected,\n\t\t\t} as DesktopPostconditionV1;\n\t\t}\n\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t});\n}\n\nfunction desktopExecuteRequest(input: Record<string, unknown>, operationId: string): DesktopOperationRequestV1 {\n\tdesktopExactKeys(input, [\"sessionId\", \"action\", \"postconditions\"]);\n\tconst actionInput = input.action;\n\tif (actionInput === null || typeof actionInput !== \"object\" || Array.isArray(actionInput))\n\t\tthrow new Error(\"desktop-action-invalid\");\n\tconst action = actionInput as Record<string, unknown>;\n\tdesktopExactKeys(action, [\"kind\", \"target\", \"text\", \"key\"]);\n\tif (\n\t\taction.kind !== \"focus\" &&\n\t\taction.kind !== \"click\" &&\n\t\taction.kind !== \"type\" &&\n\t\taction.kind !== \"key\" &&\n\t\taction.kind !== \"scroll\"\n\t)\n\t\tthrow new Error(\"desktop-action-invalid\");\n\tconst target = desktopActionTarget(action.target, action.kind);\n\tconst text =\n\t\taction.kind === \"type\" || action.kind === \"scroll\" ? desktopBoundedString(action.text, \"text\") : undefined;\n\tif (text !== undefined && text.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst key = action.kind === \"key\" ? desktopBoundedString(action.key, \"key\") : undefined;\n\tif (key !== undefined && key.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst postconditions = desktopPostconditions(input.postconditions);\n\t// Postcondition scoping for foreground actions: a target-less type/key has no\n\t// action target, so a target-level postcondition cannot describe its effect.\n\t// `property-equals` is the only kind that carries a target; pair it with a\n\t// target-less action and the check would silently assert state the action\n\t// never addressed. Global session-state checks (window-exists,\n\t// control-exists, focused) and the no-postcondition case stay allowed.\n\tif (target === undefined && postconditions?.some((condition) => condition.kind === \"property-equals\"))\n\t\tthrow new Error(\"desktop-postcondition-target-without-action-target\");\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tsessionId: desktopRequiredString(input.sessionId, \"sessionId\"),\n\t\taction: {\n\t\t\tversion: 1,\n\t\t\tkind: action.kind,\n\t\t\t...(target === undefined ? {} : { target }),\n\t\t\t...(text === undefined ? {} : { text }),\n\t\t\t...(key === undefined ? {} : { key }),\n\t\t},\n\t\t...(postconditions === undefined ? {} : { postconditions }),\n\t\t// Input plugin operations always request a fresh observation; callers may\n\t\t// not turn this off because target identity otherwise goes stale.\n\t\treobserveAfterAction: true,\n\t};\n}\n\nfunction desktopVerification(\n\tvalue: unknown,\n): { readonly status: \"passed\" | \"failed\" | \"unknown\"; readonly checks: readonly string[] } | undefined {\n\tif (value === undefined) return undefined;\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst verification = value as Record<string, unknown>;\n\tif (\n\t\t(verification.status !== \"passed\" && verification.status !== \"failed\" && verification.status !== \"unknown\") ||\n\t\t!Array.isArray(verification.checks) ||\n\t\tverification.checks.length > DESKTOP_MAX_POSTCONDITIONS_V1\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\treturn {\n\t\tstatus: verification.status,\n\t\tchecks: verification.checks.map((check) => desktopBoundedString(check, \"verification check\")),\n\t};\n}\n\nfunction desktopExecuteResult(value: unknown, request: DesktopOperationRequestV1) {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst result = value as Record<string, unknown>;\n\tif (\n\t\tresult.version !== 1 ||\n\t\tresult.operationId !== request.operationId ||\n\t\t(result.status !== \"succeeded\" &&\n\t\t\tresult.status !== \"failed\" &&\n\t\t\tresult.status !== \"cancelled\" &&\n\t\t\tresult.status !== \"needs_user\" &&\n\t\t\tresult.status !== \"unsupported\")\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tconst observation = result.observation === undefined ? undefined : projectDesktopObservation(result.observation);\n\tif (\n\t\tresult.status === \"succeeded\" &&\n\t\t(observation === undefined || observation.observation.sessionId !== request.sessionId)\n\t) {\n\t\treturn desktopFailure(\n\t\t\trequest.operationId,\n\t\t\t\"verification_unavailable\",\n\t\t\t\"Desktop action did not produce a fresh observation\",\n\t\t);\n\t}\n\tconst base = {\n\t\tversion: 1 as const,\n\t\toperationId: request.operationId,\n\t\tstatus: result.status,\n\t\tsummary: result.status === \"succeeded\" ? \"Desktop action completed\" : \"Desktop action could not be completed\",\n\t\t...(observation === undefined ? {} : observation),\n\t\t...(desktopVerification(result.verification) === undefined\n\t\t\t? {}\n\t\t\t: { verification: desktopVerification(result.verification) }),\n\t};\n\tif (result.status === \"succeeded\") return desktopResultWithinBudget(base);\n\tconst error = result.error;\n\tif (error === null || typeof error !== \"object\" || Array.isArray(error)) throw new Error(\"desktop-result-invalid\");\n\tconst errorValue = error as Record<string, unknown>;\n\tconst causeCode =\n\t\tresult.status === \"needs_user\" && typeof errorValue.causeCode === \"string\"\n\t\t\t? desktopBoundedString(errorValue.causeCode, \"error causeCode\")\n\t\t\t: undefined;\n\treturn desktopResultWithinBudget({\n\t\t...base,\n\t\terror: {\n\t\t\tversion: 1 as const,\n\t\t\tcode: result.status === \"needs_user\" ? \"needs_user\" : \"desktop_action_failed\",\n\t\t\tmessage: result.status === \"needs_user\" ? \"Desktop action requires user action\" : \"Desktop action failed\",\n\t\t\t...(causeCode === undefined ? {} : { causeCode }),\n\t\t},\n\t});\n}\n\nfunction desktopReplayActionInput(raw: unknown): DesktopOperationRequestV1[\"action\"] {\n\tif (raw === null || typeof raw !== \"object\" || Array.isArray(raw)) throw new Error(\"desktop-action-invalid\");\n\tconst action = raw as Record<string, unknown>;\n\tdesktopExactKeys(action, [\"kind\", \"target\", \"text\", \"key\"]);\n\tif (\n\t\taction.kind !== \"focus\" &&\n\t\taction.kind !== \"click\" &&\n\t\taction.kind !== \"type\" &&\n\t\taction.kind !== \"key\" &&\n\t\taction.kind !== \"scroll\"\n\t)\n\t\tthrow new Error(\"desktop-action-invalid\");\n\t// Replay stays anchored to observed identities; coordinates are execute-only.\n\t// Recorded foreground type/key entries (no target) replay through the same\n\t// driver foreground-injection path as desktop_execute.\n\tconst target = desktopActionTarget(action.target, action.kind);\n\tconst text =\n\t\taction.kind === \"type\" || action.kind === \"scroll\" ? desktopBoundedString(action.text, \"text\") : undefined;\n\tif (text !== undefined && text.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst key = action.kind === \"key\" ? desktopBoundedString(action.key, \"key\") : undefined;\n\tif (key !== undefined && key.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\treturn {\n\t\tversion: 1,\n\t\tkind: action.kind,\n\t\t...(target === undefined ? {} : { target }),\n\t\t...(text === undefined ? {} : { text }),\n\t\t...(key === undefined ? {} : { key }),\n\t};\n}\n\nfunction desktopReplayRequest(input: Record<string, unknown>, operationId: string): DesktopReplayRequestV1 {\n\tdesktopExactKeys(input, [\"sessionId\", \"actions\", \"stopOnFailure\"]);\n\tif (\n\t\t!Array.isArray(input.actions) ||\n\t\tinput.actions.length === 0 ||\n\t\tinput.actions.length > DESKTOP_MAX_REPLAY_ACTIONS_V1\n\t)\n\t\tthrow new Error(\"desktop-replay-actions-invalid\");\n\tconst sessionId = desktopRequiredString(input.sessionId, \"sessionId\");\n\tconst operations = input.actions.map((raw, index) => {\n\t\tconst action = desktopReplayActionInput(raw);\n\t\treturn {\n\t\t\tversion: 1 as const,\n\t\t\toperationId: `${operationId}-${index}`,\n\t\t\tsessionId,\n\t\t\taction,\n\t\t\t// Replay always re-observes so per-action results carry fresh state.\n\t\t\treobserveAfterAction: true,\n\t\t} satisfies DesktopOperationRequestV1;\n\t});\n\treturn {\n\t\tversion: 1,\n\t\tsessionId,\n\t\toperations,\n\t\tstopOnFailure: input.stopOnFailure === undefined ? true : input.stopOnFailure === true,\n\t};\n}\n\nfunction desktopReplayResult(value: unknown, operationId: string): unknown {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst result = value as Record<string, unknown>;\n\tif (\n\t\tresult.version !== 1 ||\n\t\t(result.status !== \"succeeded\" &&\n\t\t\tresult.status !== \"failed\" &&\n\t\t\tresult.status !== \"cancelled\" &&\n\t\t\tresult.status !== \"needs_user\") ||\n\t\t!Array.isArray(result.results)\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tconst results = result.results.map((entry) => {\n\t\tif (entry === null || typeof entry !== \"object\" || Array.isArray(entry))\n\t\t\tthrow new Error(\"desktop-result-invalid\");\n\t\tconst record = entry as Record<string, unknown>;\n\t\tif (\n\t\t\trecord.version !== 1 ||\n\t\t\ttypeof record.operationId !== \"string\" ||\n\t\t\t(record.status !== \"succeeded\" &&\n\t\t\t\trecord.status !== \"failed\" &&\n\t\t\t\trecord.status !== \"cancelled\" &&\n\t\t\t\trecord.status !== \"needs_user\" &&\n\t\t\t\trecord.status !== \"unsupported\")\n\t\t)\n\t\t\tthrow new Error(\"desktop-result-invalid\");\n\t\treturn {\n\t\t\toperationId: desktopBoundedString(record.operationId, \"replay operationId\"),\n\t\t\tstatus: record.status,\n\t\t\tsummary: desktopBoundedString(record.summary, \"replay summary\"),\n\t\t};\n\t});\n\tconst last = result.results[result.results.length - 1] as Record<string, unknown> | undefined;\n\tconst observation =\n\t\tlast?.observation === undefined ? undefined : projectDesktopObservation(last.observation).observation;\n\tconst needsUser = result.results.find((entry) => (entry as Record<string, unknown>).status === \"needs_user\") as\n\t\t| Record<string, unknown>\n\t\t| undefined;\n\tconst causeCode =\n\t\tneedsUser !== undefined &&\n\t\tneedsUser.error !== null &&\n\t\ttypeof needsUser.error === \"object\" &&\n\t\t\"causeCode\" in needsUser.error &&\n\t\ttypeof (needsUser.error as Record<string, unknown>).causeCode === \"string\"\n\t\t\t? desktopBoundedString((needsUser.error as Record<string, unknown>).causeCode, \"replay causeCode\")\n\t\t\t: undefined;\n\treturn desktopResultWithinBudget({\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: result.status,\n\t\tsummary: result.status === \"succeeded\" ? \"Desktop replay completed\" : \"Desktop replay stopped before completion\",\n\t\tresults,\n\t\t...(observation === undefined ? {} : { observation }),\n\t\t...(result.status === \"needs_user\" && causeCode !== undefined\n\t\t\t? {\n\t\t\t\t\terror: {\n\t\t\t\t\t\tversion: 1 as const,\n\t\t\t\t\t\tcode: \"needs_user\",\n\t\t\t\t\t\tmessage: \"Desktop replay requires user action\",\n\t\t\t\t\t\tcauseCode,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t});\n}\n\nexport function createDesktopInputCapabilityFactoryV1(\n\truntime: DesktopFullControlAdapterV1,\n): CapabilityPluginSyncFactory {\n\treturn (api) => {\n\t\tif (api.host.mode === \"readonly\") return;\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_execute\",\n\t\t\tlabel: \"Execute desktop action\",\n\t\t\tdescription:\n\t\t\t\t\"Execute one bounded UI Automation focus, click, type, key, or scroll action and return a fresh bounded observation; type and key may omit the target to send real keyboard input to the current foreground focus (native dialogs invisible to UI Automation)\",\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tsessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\taction: Type.Object(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: Type.Union([\n\t\t\t\t\t\t\t\tType.Literal(\"focus\"),\n\t\t\t\t\t\t\t\tType.Literal(\"click\"),\n\t\t\t\t\t\t\t\tType.Literal(\"type\"),\n\t\t\t\t\t\t\t\tType.Literal(\"key\"),\n\t\t\t\t\t\t\t\tType.Literal(\"scroll\"),\n\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t// Observed identities; optional for type/key so they can address the\n\t\t\t\t\t\t\t// foreground focus instead. The conditional rules (target required\n\t\t\t\t\t\t\t// for focus/click/scroll, coordinates click-only) are enforced by\n\t\t\t\t\t\t\t// desktopExecuteRequest, not by this schema.\n\t\t\t\t\t\t\ttarget: Type.Optional(\n\t\t\t\t\t\t\t\tType.Union([\n\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\tType.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t// Raw screen pixels; click-only. The conditional click-only rule\n\t\t\t\t\t\t\t\t\t// is enforced by desktopExecuteRequest, not by this schema.\n\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"coordinates\"),\n\t\t\t\t\t\t\t\t\t\t\tx: Type.Integer({ minimum: 0 }),\n\t\t\t\t\t\t\t\t\t\t\ty: Type.Integer({ minimum: 0 }),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\ttext: Type.Optional(Type.String({ maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),\n\t\t\t\t\t\t\tkey: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t),\n\t\t\t\t\tpostconditions: Type.Optional(\n\t\t\t\t\t\tType.Array(\n\t\t\t\t\t\t\tType.Union([\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window-exists\"),\n\t\t\t\t\t\t\t\t\t\twindowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control-exists\"),\n\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"focused\"),\n\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"property-equals\"),\n\t\t\t\t\t\t\t\t\t\ttarget: Type.Union([\n\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tType.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t\t\tproperty: Type.Union([\n\t\t\t\t\t\t\t\t\t\t\tType.Literal(\"enabled\"),\n\t\t\t\t\t\t\t\t\t\t\tType.Literal(\"value\"),\n\t\t\t\t\t\t\t\t\t\t\tType.Literal(\"name\"),\n\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t\t\texpected: Type.Union([\n\t\t\t\t\t\t\t\t\t\t\tType.Boolean(),\n\t\t\t\t\t\t\t\t\t\t\tType.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t{ maxItems: DESKTOP_MAX_POSTCONDITIONS_V1 },\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tconst { input, operationId } = toolInvocation(first, second);\n\t\t\t\tconst signal = signalFrom(third);\n\t\t\t\tif (signal?.aborted)\n\t\t\t\t\treturn desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\");\n\t\t\t\tlet request: DesktopOperationRequestV1;\n\t\t\t\ttry {\n\t\t\t\t\trequest = desktopExecuteRequest(input, operationId);\n\t\t\t\t} catch {\n\t\t\t\t\treturn desktopFailure(operationId, \"desktop_input_invalid\", \"Desktop action input is invalid\");\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst result = runtime.execute(request);\n\t\t\t\t\treturn signal?.aborted\n\t\t\t\t\t\t? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\")\n\t\t\t\t\t\t: desktopExecuteResult(result, request);\n\t\t\t\t} catch {\n\t\t\t\t\treturn desktopFailure(operationId, \"desktop_adapter_failed\", \"The selected desktop adapter failed\");\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t\tconst replay = runtime.replay;\n\t\tif (replay === undefined) return;\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_replay\",\n\t\t\tlabel: \"Replay desktop actions\",\n\t\t\tdescription:\n\t\t\t\t\"Replay a bounded sequence of desktop actions against one session; stops at the first failure, cancellation, or user-confirmation pause by default. Recorded foreground type/key entries may omit the target\",\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tsessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\tactions: Type.Array(\n\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkind: Type.Union([\n\t\t\t\t\t\t\t\t\tType.Literal(\"focus\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"click\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"type\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"key\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"scroll\"),\n\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t// Optional for type/key (foreground replay entries); the per-kind\n\t\t\t\t\t\t\t\t// rule is enforced by desktopReplayActionInput, not by this schema.\n\t\t\t\t\t\t\t\ttarget: Type.Optional(\n\t\t\t\t\t\t\t\t\tType.Union([\n\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\t\tType.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\ttext: Type.Optional(Type.String({ maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),\n\t\t\t\t\t\t\t\tkey: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1 })),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{ minItems: 1, maxItems: DESKTOP_MAX_REPLAY_ACTIONS_V1 },\n\t\t\t\t\t),\n\t\t\t\t\tstopOnFailure: Type.Optional(Type.Boolean()),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tconst { input, operationId } = toolInvocation(first, second);\n\t\t\t\tconst signal = signalFrom(third);\n\t\t\t\tif (signal?.aborted)\n\t\t\t\t\treturn desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\");\n\t\t\t\tlet request: DesktopReplayRequestV1;\n\t\t\t\ttry {\n\t\t\t\t\trequest = desktopReplayRequest(input, operationId);\n\t\t\t\t} catch {\n\t\t\t\t\treturn desktopFailure(operationId, \"desktop_input_invalid\", \"Desktop replay input is invalid\");\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst result = replay(request);\n\t\t\t\t\treturn signal?.aborted\n\t\t\t\t\t\t? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\")\n\t\t\t\t\t\t: desktopReplayResult(result, operationId);\n\t\t\t\t} catch {\n\t\t\t\t\treturn desktopFailure(operationId, \"desktop_adapter_failed\", \"The selected desktop adapter failed\");\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t};\n}\n"]}
1
+ {"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bounded desktop input and replay capability factory, migrated from\n * agent-forge `src/profile/runtime-capabilities-desktop-input.ts`\n * (`desktopInputFactory`, D-075 S3 extraction). Differences from the host\n * original:\n * - The factory type is the public `CapabilityPluginSyncFactory` from the\n * plugin SDK instead of the host-internal `BuiltinCapabilityPlugin`.\n * - Projection helpers live in `projection.ts`, input helpers in `shared.ts`.\n * Tool names, budgets and result shapes are unchanged, including the\n * readonly-mode refusal to register input tools and the optional replay\n * registration when the runtime exposes a replay method. Since the 2026-10-13\n * product decision, type/key actions may omit the target: the request is routed\n * to the driver's foreground keyboard-queue injection instead of being rejected\n * (user ruling: \"AI 操作需要的是任何情况下都能操作,和人一样操作电脑\").\n */\nimport type { CapabilityPluginSyncFactory } from \"@agent-forge/plugin-sdk\";\nimport { Type } from \"typebox\";\nimport {\n\tDESKTOP_MAX_POSTCONDITIONS_V1,\n\tDESKTOP_MAX_REPLAY_ACTIONS_V1,\n\tDESKTOP_MAX_STRING_CHARS_V1,\n\tDESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\tdesktopBoundedString,\n\tdesktopFailure,\n\tdesktopRequiredString,\n\tdesktopResultWithinBudget,\n\tprojectDesktopObservation,\n} from \"./projection.ts\";\nimport { signalFrom, toolInvocation } from \"./shared.ts\";\nimport type {\n\tDesktopFullControlAdapterV1,\n\tDesktopOperationRequestV1,\n\tDesktopPostconditionV1,\n\tDesktopReplayRequestV1,\n} from \"./types.ts\";\n\n/** Surface the original validator/adapter diagnostic: the model needs it to correct the call. */\nfunction errorDetail(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction desktopTarget(input: unknown, allowCoordinates: boolean): DesktopOperationRequestV1[\"action\"][\"target\"] {\n\tif (input === null || typeof input !== \"object\" || Array.isArray(input)) throw new Error(\"desktop-target-invalid\");\n\tconst target = input as Record<string, unknown>;\n\tif (target.kind === \"window\") {\n\t\tdesktopExactKeys(target, [\"kind\", \"windowId\"]);\n\t\treturn { kind: \"window\", windowId: desktopRequiredString(target.windowId, \"windowId\") };\n\t}\n\tif (target.kind === \"control\") {\n\t\tdesktopExactKeys(target, [\"kind\", \"controlId\", \"windowId\"]);\n\t\treturn {\n\t\t\tkind: \"control\",\n\t\t\tcontrolId: desktopRequiredString(target.controlId, \"controlId\"),\n\t\t\t...(target.windowId === undefined ? {} : { windowId: desktopRequiredString(target.windowId, \"windowId\") }),\n\t\t};\n\t}\n\t// Raw screen-pixel coordinates are accepted for click actions only; the\n\t// schema union cannot express that condition, so this validator rejects it.\n\tif (target.kind === \"coordinates\") {\n\t\tif (!allowCoordinates) throw new Error(\"desktop-target-invalid\");\n\t\tdesktopExactKeys(target, [\"kind\", \"x\", \"y\"]);\n\t\tif (\n\t\t\ttypeof target.x !== \"number\" ||\n\t\t\t!Number.isInteger(target.x) ||\n\t\t\ttarget.x < 0 ||\n\t\t\ttypeof target.y !== \"number\" ||\n\t\t\t!Number.isInteger(target.y) ||\n\t\t\ttarget.y < 0\n\t\t)\n\t\t\tthrow new Error(\"desktop-target-invalid\");\n\t\treturn { kind: \"coordinates\", x: target.x, y: target.y };\n\t}\n\tthrow new Error(\"desktop-target-invalid\");\n}\n\nfunction desktopExactKeys(value: Record<string, unknown>, allowed: readonly string[]): void {\n\tif (Object.keys(value).some((key) => !allowed.includes(key))) throw new Error(\"desktop-input-invalid\");\n}\n\n/**\n * Target validation with the foreground-input exception: type and key may omit\n * the target entirely. A target-less type/key is routed by the driver to the\n * real keyboard queue at the current focus (FOREGROUND_INPUT_SCRIPT) — the only\n * path that reaches UIA-invisible surfaces such as the native file dialog's\n * name box. Every other kind still requires an observed identity: a focus,\n * click or scroll without a target has no addressable subject.\n */\nfunction desktopActionTarget(\n\tinput: unknown,\n\tkind: DesktopOperationRequestV1[\"action\"][\"kind\"],\n): DesktopOperationRequestV1[\"action\"][\"target\"] | undefined {\n\tif (input === undefined) {\n\t\tif (kind === \"type\" || kind === \"key\") return undefined;\n\t\tthrow new Error(\"desktop-target-required\");\n\t}\n\treturn desktopTarget(input, kind === \"click\");\n}\n\nfunction desktopPostconditions(input: unknown): readonly DesktopPostconditionV1[] | undefined {\n\tif (input === undefined) return undefined;\n\tif (!Array.isArray(input) || input.length > DESKTOP_MAX_POSTCONDITIONS_V1)\n\t\tthrow new Error(\"desktop-postconditions-invalid\");\n\treturn input.map((entry) => {\n\t\tif (entry === null || typeof entry !== \"object\" || Array.isArray(entry))\n\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\tconst value = entry as Record<string, unknown>;\n\t\tif (value.kind === \"window-exists\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"windowId\"]);\n\t\t\treturn { kind: \"window-exists\", windowId: desktopRequiredString(value.windowId, \"windowId\") } as const;\n\t\t}\n\t\tif (value.kind === \"control-exists\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"controlId\"]);\n\t\t\treturn { kind: \"control-exists\", controlId: desktopRequiredString(value.controlId, \"controlId\") } as const;\n\t\t}\n\t\tif (value.kind === \"focused\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"controlId\"]);\n\t\t\treturn { kind: \"focused\", controlId: desktopRequiredString(value.controlId, \"controlId\") } as const;\n\t\t}\n\t\tif (value.kind === \"property-equals\") {\n\t\t\tdesktopExactKeys(value, [\"kind\", \"target\", \"property\", \"expected\"]);\n\t\t\tif (value.property !== \"enabled\" && value.property !== \"value\" && value.property !== \"name\")\n\t\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\t\tif (\n\t\t\t\t(value.property === \"enabled\" && typeof value.expected !== \"boolean\") ||\n\t\t\t\t(value.property !== \"enabled\" && typeof value.expected !== \"string\")\n\t\t\t)\n\t\t\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t\t\treturn {\n\t\t\t\tkind: \"property-equals\",\n\t\t\t\ttarget: desktopTarget(value.target, false),\n\t\t\t\tproperty: value.property,\n\t\t\t\texpected:\n\t\t\t\t\ttypeof value.expected === \"string\"\n\t\t\t\t\t\t? desktopBoundedString(value.expected, \"postcondition expected\")\n\t\t\t\t\t\t: value.expected,\n\t\t\t} as DesktopPostconditionV1;\n\t\t}\n\t\tthrow new Error(\"desktop-postcondition-invalid\");\n\t});\n}\n\nfunction desktopExecuteRequest(input: Record<string, unknown>, operationId: string): DesktopOperationRequestV1 {\n\tdesktopExactKeys(input, [\"sessionId\", \"action\", \"postconditions\"]);\n\tconst actionInput = input.action;\n\tif (actionInput === null || typeof actionInput !== \"object\" || Array.isArray(actionInput))\n\t\tthrow new Error(\"desktop-action-invalid\");\n\tconst action = actionInput as Record<string, unknown>;\n\tdesktopExactKeys(action, [\"kind\", \"target\", \"text\", \"key\"]);\n\tif (\n\t\taction.kind !== \"focus\" &&\n\t\taction.kind !== \"click\" &&\n\t\taction.kind !== \"type\" &&\n\t\taction.kind !== \"key\" &&\n\t\taction.kind !== \"scroll\"\n\t)\n\t\tthrow new Error(\"desktop-action-invalid\");\n\tconst target = desktopActionTarget(action.target, action.kind);\n\tconst text =\n\t\taction.kind === \"type\" || action.kind === \"scroll\" ? desktopBoundedString(action.text, \"text\") : undefined;\n\tif (text !== undefined && text.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst key = action.kind === \"key\" ? desktopBoundedString(action.key, \"key\") : undefined;\n\tif (key !== undefined && key.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst postconditions = desktopPostconditions(input.postconditions);\n\t// Postcondition scoping for foreground actions: a target-less type/key has no\n\t// action target, so a target-level postcondition cannot describe its effect.\n\t// `property-equals` is the only kind that carries a target; pair it with a\n\t// target-less action and the check would silently assert state the action\n\t// never addressed. Global session-state checks (window-exists,\n\t// control-exists, focused) and the no-postcondition case stay allowed.\n\tif (target === undefined && postconditions?.some((condition) => condition.kind === \"property-equals\"))\n\t\tthrow new Error(\"desktop-postcondition-target-without-action-target\");\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tsessionId: desktopRequiredString(input.sessionId, \"sessionId\"),\n\t\taction: {\n\t\t\tversion: 1,\n\t\t\tkind: action.kind,\n\t\t\t...(target === undefined ? {} : { target }),\n\t\t\t...(text === undefined ? {} : { text }),\n\t\t\t...(key === undefined ? {} : { key }),\n\t\t},\n\t\t...(postconditions === undefined ? {} : { postconditions }),\n\t\t// Input plugin operations always request a fresh observation; callers may\n\t\t// not turn this off because target identity otherwise goes stale.\n\t\treobserveAfterAction: true,\n\t};\n}\n\nfunction desktopVerification(\n\tvalue: unknown,\n): { readonly status: \"passed\" | \"failed\" | \"unknown\"; readonly checks: readonly string[] } | undefined {\n\tif (value === undefined) return undefined;\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst verification = value as Record<string, unknown>;\n\tif (\n\t\t(verification.status !== \"passed\" && verification.status !== \"failed\" && verification.status !== \"unknown\") ||\n\t\t!Array.isArray(verification.checks) ||\n\t\tverification.checks.length > DESKTOP_MAX_POSTCONDITIONS_V1\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\treturn {\n\t\tstatus: verification.status,\n\t\tchecks: verification.checks.map((check) => desktopBoundedString(check, \"verification check\")),\n\t};\n}\n\nfunction desktopExecuteResult(value: unknown, request: DesktopOperationRequestV1) {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst result = value as Record<string, unknown>;\n\tif (\n\t\tresult.version !== 1 ||\n\t\tresult.operationId !== request.operationId ||\n\t\t(result.status !== \"succeeded\" &&\n\t\t\tresult.status !== \"failed\" &&\n\t\t\tresult.status !== \"cancelled\" &&\n\t\t\tresult.status !== \"needs_user\" &&\n\t\t\tresult.status !== \"unsupported\")\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tconst observation = result.observation === undefined ? undefined : projectDesktopObservation(result.observation);\n\tif (\n\t\tresult.status === \"succeeded\" &&\n\t\t(observation === undefined || observation.observation.sessionId !== request.sessionId)\n\t) {\n\t\treturn desktopFailure(\n\t\t\trequest.operationId,\n\t\t\t\"verification_unavailable\",\n\t\t\t\"Desktop action did not produce a fresh observation\",\n\t\t);\n\t}\n\tconst base = {\n\t\tversion: 1 as const,\n\t\toperationId: request.operationId,\n\t\tstatus: result.status,\n\t\tsummary: result.status === \"succeeded\" ? \"Desktop action completed\" : \"Desktop action could not be completed\",\n\t\t...(observation === undefined ? {} : observation),\n\t\t...(desktopVerification(result.verification) === undefined\n\t\t\t? {}\n\t\t\t: { verification: desktopVerification(result.verification) }),\n\t};\n\tif (result.status === \"succeeded\") return desktopResultWithinBudget(base);\n\tconst error = result.error;\n\tif (error === null || typeof error !== \"object\" || Array.isArray(error)) throw new Error(\"desktop-result-invalid\");\n\tconst errorValue = error as Record<string, unknown>;\n\tconst causeCode =\n\t\tresult.status === \"needs_user\" && typeof errorValue.causeCode === \"string\"\n\t\t\t? desktopBoundedString(errorValue.causeCode, \"error causeCode\")\n\t\t\t: undefined;\n\treturn desktopResultWithinBudget({\n\t\t...base,\n\t\terror: {\n\t\t\tversion: 1 as const,\n\t\t\tcode: result.status === \"needs_user\" ? \"needs_user\" : \"desktop_action_failed\",\n\t\t\tmessage: result.status === \"needs_user\" ? \"Desktop action requires user action\" : \"Desktop action failed\",\n\t\t\t...(causeCode === undefined ? {} : { causeCode }),\n\t\t},\n\t});\n}\n\nfunction desktopReplayActionInput(raw: unknown): DesktopOperationRequestV1[\"action\"] {\n\tif (raw === null || typeof raw !== \"object\" || Array.isArray(raw)) throw new Error(\"desktop-action-invalid\");\n\tconst action = raw as Record<string, unknown>;\n\tdesktopExactKeys(action, [\"kind\", \"target\", \"text\", \"key\"]);\n\tif (\n\t\taction.kind !== \"focus\" &&\n\t\taction.kind !== \"click\" &&\n\t\taction.kind !== \"type\" &&\n\t\taction.kind !== \"key\" &&\n\t\taction.kind !== \"scroll\"\n\t)\n\t\tthrow new Error(\"desktop-action-invalid\");\n\t// Replay stays anchored to observed identities; coordinates are execute-only.\n\t// Recorded foreground type/key entries (no target) replay through the same\n\t// driver foreground-injection path as desktop_execute.\n\tconst target = desktopActionTarget(action.target, action.kind);\n\tconst text =\n\t\taction.kind === \"type\" || action.kind === \"scroll\" ? desktopBoundedString(action.text, \"text\") : undefined;\n\tif (text !== undefined && text.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\tconst key = action.kind === \"key\" ? desktopBoundedString(action.key, \"key\") : undefined;\n\tif (key !== undefined && key.length > DESKTOP_MAX_TYPE_TEXT_CHARS_V1) throw new Error(\"desktop-type-text-budget\");\n\treturn {\n\t\tversion: 1,\n\t\tkind: action.kind,\n\t\t...(target === undefined ? {} : { target }),\n\t\t...(text === undefined ? {} : { text }),\n\t\t...(key === undefined ? {} : { key }),\n\t};\n}\n\nfunction desktopReplayRequest(input: Record<string, unknown>, operationId: string): DesktopReplayRequestV1 {\n\tdesktopExactKeys(input, [\"sessionId\", \"actions\", \"stopOnFailure\"]);\n\tif (\n\t\t!Array.isArray(input.actions) ||\n\t\tinput.actions.length === 0 ||\n\t\tinput.actions.length > DESKTOP_MAX_REPLAY_ACTIONS_V1\n\t)\n\t\tthrow new Error(\"desktop-replay-actions-invalid\");\n\tconst sessionId = desktopRequiredString(input.sessionId, \"sessionId\");\n\tconst operations = input.actions.map((raw, index) => {\n\t\tconst action = desktopReplayActionInput(raw);\n\t\treturn {\n\t\t\tversion: 1 as const,\n\t\t\toperationId: `${operationId}-${index}`,\n\t\t\tsessionId,\n\t\t\taction,\n\t\t\t// Replay always re-observes so per-action results carry fresh state.\n\t\t\treobserveAfterAction: true,\n\t\t} satisfies DesktopOperationRequestV1;\n\t});\n\treturn {\n\t\tversion: 1,\n\t\tsessionId,\n\t\toperations,\n\t\tstopOnFailure: input.stopOnFailure === undefined ? true : input.stopOnFailure === true,\n\t};\n}\n\nfunction desktopReplayResult(value: unknown, operationId: string): unknown {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst result = value as Record<string, unknown>;\n\tif (\n\t\tresult.version !== 1 ||\n\t\t(result.status !== \"succeeded\" &&\n\t\t\tresult.status !== \"failed\" &&\n\t\t\tresult.status !== \"cancelled\" &&\n\t\t\tresult.status !== \"needs_user\") ||\n\t\t!Array.isArray(result.results)\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tconst results = result.results.map((entry) => {\n\t\tif (entry === null || typeof entry !== \"object\" || Array.isArray(entry))\n\t\t\tthrow new Error(\"desktop-result-invalid\");\n\t\tconst record = entry as Record<string, unknown>;\n\t\tif (\n\t\t\trecord.version !== 1 ||\n\t\t\ttypeof record.operationId !== \"string\" ||\n\t\t\t(record.status !== \"succeeded\" &&\n\t\t\t\trecord.status !== \"failed\" &&\n\t\t\t\trecord.status !== \"cancelled\" &&\n\t\t\t\trecord.status !== \"needs_user\" &&\n\t\t\t\trecord.status !== \"unsupported\")\n\t\t)\n\t\t\tthrow new Error(\"desktop-result-invalid\");\n\t\treturn {\n\t\t\toperationId: desktopBoundedString(record.operationId, \"replay operationId\"),\n\t\t\tstatus: record.status,\n\t\t\tsummary: desktopBoundedString(record.summary, \"replay summary\"),\n\t\t};\n\t});\n\tconst last = result.results[result.results.length - 1] as Record<string, unknown> | undefined;\n\tconst observation =\n\t\tlast?.observation === undefined ? undefined : projectDesktopObservation(last.observation).observation;\n\tconst needsUser = result.results.find((entry) => (entry as Record<string, unknown>).status === \"needs_user\") as\n\t\t| Record<string, unknown>\n\t\t| undefined;\n\tconst causeCode =\n\t\tneedsUser !== undefined &&\n\t\tneedsUser.error !== null &&\n\t\ttypeof needsUser.error === \"object\" &&\n\t\t\"causeCode\" in needsUser.error &&\n\t\ttypeof (needsUser.error as Record<string, unknown>).causeCode === \"string\"\n\t\t\t? desktopBoundedString((needsUser.error as Record<string, unknown>).causeCode, \"replay causeCode\")\n\t\t\t: undefined;\n\treturn desktopResultWithinBudget({\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: result.status,\n\t\tsummary: result.status === \"succeeded\" ? \"Desktop replay completed\" : \"Desktop replay stopped before completion\",\n\t\tresults,\n\t\t...(observation === undefined ? {} : { observation }),\n\t\t...(result.status === \"needs_user\" && causeCode !== undefined\n\t\t\t? {\n\t\t\t\t\terror: {\n\t\t\t\t\t\tversion: 1 as const,\n\t\t\t\t\t\tcode: \"needs_user\",\n\t\t\t\t\t\tmessage: \"Desktop replay requires user action\",\n\t\t\t\t\t\tcauseCode,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t});\n}\n\nexport function createDesktopInputCapabilityFactoryV1(\n\truntime: DesktopFullControlAdapterV1,\n): CapabilityPluginSyncFactory {\n\treturn (api) => {\n\t\tif (api.host.mode === \"readonly\") return;\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_execute\",\n\t\t\tlabel: \"Execute desktop action\",\n\t\t\tdescription:\n\t\t\t\t\"Execute one bounded UI Automation focus, click, type, key, or scroll action and return a fresh bounded observation; type and key may omit the target to send real keyboard input to the current foreground focus (native dialogs invisible to UI Automation)\",\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tsessionId: Type.String({\n\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\tdescription: \"Session id from a previous desktop observation; a fresh observation is returned\",\n\t\t\t\t\t}),\n\t\t\t\t\taction: Type.Object(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: Type.Union(\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\tType.Literal(\"focus\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"click\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"type\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"key\"),\n\t\t\t\t\t\t\t\t\tType.Literal(\"scroll\"),\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t{ description: \"focus, click, type, key, or scroll\" },\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t// Observed identities; optional for type/key so they can address the\n\t\t\t\t\t\t\t// foreground focus instead. The conditional rules (target required\n\t\t\t\t\t\t\t// for focus/click/scroll, coordinates click-only) are enforced by\n\t\t\t\t\t\t\t// desktopExecuteRequest, not by this schema.\n\t\t\t\t\t\t\ttarget: Type.Optional(\n\t\t\t\t\t\t\t\tType.Union(\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Window id from a previous observation\",\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Control id from a previous observation; a stale identity fails with stale_target\",\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Optional owning-window id for the control lookup\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t// Raw screen pixels; click-only. The conditional click-only rule\n\t\t\t\t\t\t\t\t\t\t// is enforced by desktopExecuteRequest, not by this schema.\n\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"coordinates\"),\n\t\t\t\t\t\t\t\t\t\t\t\tx: Type.Integer({\n\t\t\t\t\t\t\t\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Raw screen-pixel coordinate (non-negative integer); valid only for click\",\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\ty: Type.Integer({\n\t\t\t\t\t\t\t\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Raw screen-pixel coordinate (non-negative integer); valid only for click\",\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\"Observed window/control identity, or raw screen coordinates for click only; omit only for type/key\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\ttext: Type.Optional(\n\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\"Text for type, or scroll direction as up|down with optional :lines (1..100, default 3)\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tkey: Type.Optional(\n\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\"Key sequence for key: +-joined modifiers (ctrl, alt, shift, meta/win) plus a named key or single character; sent via the real keyboard queue\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ additionalProperties: false, description: \"Exactly one action object; unknown keys are rejected\" },\n\t\t\t\t\t),\n\t\t\t\t\tpostconditions: Type.Optional(\n\t\t\t\t\t\tType.Array(\n\t\t\t\t\t\t\tType.Union([\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window-exists\"),\n\t\t\t\t\t\t\t\t\t\twindowId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\tdescription: \"Window id that must exist after the action\",\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control-exists\"),\n\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\tdescription: \"Control id that must still exist after the action\",\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"focused\"),\n\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\tdescription: \"Control id that must hold keyboard focus after the action\",\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"property-equals\"),\n\t\t\t\t\t\t\t\t\t\ttarget: Type.Union(\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Window id from a previous observation\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Control id from a previous observation; a stale identity fails with stale_target\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Optional owning-window id for the control lookup\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Window or control whose property is compared (coordinates not allowed)\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tproperty: Type.Union(\n\t\t\t\t\t\t\t\t\t\t\t[Type.Literal(\"enabled\"), Type.Literal(\"value\"), Type.Literal(\"name\")],\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"enabled (boolean expected), value, or name (string expected)\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\texpected: Type.Union(\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\tType.Boolean(),\n\t\t\t\t\t\t\t\t\t\t\t\tType.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Expected value: boolean for enabled, non-empty string for value/name\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmaxItems: DESKTOP_MAX_POSTCONDITIONS_V1,\n\t\t\t\t\t\t\t\tdescription: \"Up to 32 checks evaluated against the fresh observation after the action\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tconst { input, operationId } = toolInvocation(first, second);\n\t\t\t\tconst signal = signalFrom(third);\n\t\t\t\tif (signal?.aborted)\n\t\t\t\t\treturn desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\");\n\t\t\t\tlet request: DesktopOperationRequestV1;\n\t\t\t\ttry {\n\t\t\t\t\trequest = desktopExecuteRequest(input, operationId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn desktopFailure(\n\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\"desktop_input_invalid\",\n\t\t\t\t\t\t`Desktop action input is invalid: ${errorDetail(error)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst result = runtime.execute(request);\n\t\t\t\t\treturn signal?.aborted\n\t\t\t\t\t\t? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\")\n\t\t\t\t\t\t: desktopExecuteResult(result, request);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn desktopFailure(\n\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\"desktop_adapter_failed\",\n\t\t\t\t\t\t`The selected desktop adapter failed: ${errorDetail(error)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t\tconst replay = runtime.replay;\n\t\tif (replay === undefined) return;\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_replay\",\n\t\t\tlabel: \"Replay desktop actions\",\n\t\t\tdescription:\n\t\t\t\t\"Replay a bounded sequence of desktop actions against one session; stops at the first failure, cancellation, or user-confirmation pause by default. Recorded foreground type/key entries may omit the target\",\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tsessionId: Type.String({\n\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\tdescription: \"Session id from a previous desktop observation; all actions replay against it\",\n\t\t\t\t\t}),\n\t\t\t\t\tactions: Type.Array(\n\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkind: Type.Union(\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\tType.Literal(\"focus\"),\n\t\t\t\t\t\t\t\t\t\tType.Literal(\"click\"),\n\t\t\t\t\t\t\t\t\t\tType.Literal(\"type\"),\n\t\t\t\t\t\t\t\t\t\tType.Literal(\"key\"),\n\t\t\t\t\t\t\t\t\t\tType.Literal(\"scroll\"),\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t{ description: \"focus, click, type, key, or scroll\" },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t// Optional for type/key (foreground replay entries); the per-kind\n\t\t\t\t\t\t\t\t// rule is enforced by desktopReplayActionInput, not by this schema.\n\t\t\t\t\t\t\t\ttarget: Type.Optional(\n\t\t\t\t\t\t\t\t\tType.Union(\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"window\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Window id from a previous observation\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\tType.Object(\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tkind: Type.Literal(\"control\"),\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontrolId: Type.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Control id from a previous observation; a stale identity fails with stale_target\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t\twindowId: Type.Optional(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_STRING_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Optional owning-window id for the control lookup\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\"Observed window/control identity; omit only for recorded foreground type/key entries (no coordinates in replay)\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\ttext: Type.Optional(\n\t\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\"Text for type, or scroll direction as up|down with optional :lines (1..100, default 3)\",\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tkey: Type.Optional(\n\t\t\t\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\t\t\t\tminLength: 1,\n\t\t\t\t\t\t\t\t\t\tmaxLength: DESKTOP_MAX_TYPE_TEXT_CHARS_V1,\n\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\"Key sequence for key: +-joined modifiers (ctrl, alt, shift, meta/win) plus a named key or single character; sent via the real keyboard queue\",\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ additionalProperties: false },\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tminItems: 1,\n\t\t\t\t\t\t\tmaxItems: DESKTOP_MAX_REPLAY_ACTIONS_V1,\n\t\t\t\t\t\t\tdescription: \"1..32 actions replayed in order\",\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t\tstopOnFailure: Type.Optional(\n\t\t\t\t\t\tType.Boolean({\n\t\t\t\t\t\t\tdescription: \"Stop at the first failure when true (default); false continues through failures\",\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tconst { input, operationId } = toolInvocation(first, second);\n\t\t\t\tconst signal = signalFrom(third);\n\t\t\t\tif (signal?.aborted)\n\t\t\t\t\treturn desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\");\n\t\t\t\tlet request: DesktopReplayRequestV1;\n\t\t\t\ttry {\n\t\t\t\t\trequest = desktopReplayRequest(input, operationId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn desktopFailure(\n\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\"desktop_input_invalid\",\n\t\t\t\t\t\t`Desktop replay input is invalid: ${errorDetail(error)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst result = replay(request);\n\t\t\t\t\treturn signal?.aborted\n\t\t\t\t\t\t? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\")\n\t\t\t\t\t\t: desktopReplayResult(result, operationId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn desktopFailure(\n\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\"desktop_adapter_failed\",\n\t\t\t\t\t\t`The selected desktop adapter failed: ${errorDetail(error)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t};\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-agent-forge/plugin-desktop-windows-input",
3
- "version": "0.88.19",
3
+ "version": "0.88.20",
4
4
  "description": "Bounded Windows desktop input capability plugin for Agent Forge (desktop_execute and, when the runtime provides replay, desktop_replay)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -49,7 +49,7 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "typebox": "1.3.27",
52
- "@ai-agent-forge/plugin-sdk": "^0.88.19"
52
+ "@ai-agent-forge/plugin-sdk": "^0.88.20"
53
53
  },
54
54
  "devDependencies": {
55
55
  "shx": "0.3.4",
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "agent-forge.plugin.desktop-windows-input",
3
- "version": "0.88.19",
3
+ "version": "0.88.20",
4
4
  "apiVersion": "1-draft",
5
5
  "entry": "./dist/entry.js",
6
6
  "hostVersion": ">=0.84.4",