@ai-agent-forge/plugin-desktop-windows-observe 0.85.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/agent-forge.json +15 -0
- package/dist/capability.d.ts +13 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/capability.js +97 -0
- package/dist/capability.js.map +1 -0
- package/dist/entry.d.ts +14 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +15 -0
- package/dist/entry.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/projection.d.ts +113 -0
- package/dist/projection.d.ts.map +1 -0
- package/dist/projection.js +226 -0
- package/dist/projection.js.map +1 -0
- package/dist/shared.d.ts +15 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +30 -0
- package/dist/shared.js.map +1 -0
- package/dist/types.d.ts +202 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/dist/windows-uia-adapter.d.ts +68 -0
- package/dist/windows-uia-adapter.d.ts.map +1 -0
- package/dist/windows-uia-adapter.js +711 -0
- package/dist/windows-uia-adapter.js.map +1 -0
- package/package.json +57 -0
- package/plugin.json +12 -0
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# @agent-forge/plugin-desktop-windows-observe
|
|
2
|
+
|
|
3
|
+
Read-only Windows desktop observation capability plugin for [Agent Forge](https://github.com/agent-forge/agent-forge), extracted from the host's
|
|
4
|
+
`src/plugins/desktop` (D-075 S3). It registers five read-only tools — `desktop_probe`, `desktop_session_open`, `desktop_observe`, `desktop_reobserve`,
|
|
5
|
+
`desktop_session_stop` — backed by the Windows UI Automation PowerShell driver. It never registers an input or replay tool.
|
|
6
|
+
|
|
7
|
+
The plugin ships its own UIA adapter. On non-Windows platforms importing the package does not throw; every tool reports an explicit `unsupported`
|
|
8
|
+
result instead of probing or falling back to a different driver.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
# from a local checkout
|
|
14
|
+
agent-forge plugin install ./plugins/desktop-windows-observe
|
|
15
|
+
|
|
16
|
+
# from npm
|
|
17
|
+
agent-forge plugin install @agent-forge/plugin-desktop-windows-observe
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The package ships two manifests: `agent-forge.json` (ecosystem manifest for the deterministic plugin resolver, `platform.os: ["windows"]`) and
|
|
21
|
+
`plugin.json` (host-load manifest consumed by `loadCapabilityPluginFromManifest`, entry `./dist/entry.js`).
|
|
22
|
+
|
|
23
|
+
## Library surface
|
|
24
|
+
|
|
25
|
+
`import { DesktopWindowsAdapter, WindowsUiAutomationDriver } from "@agent-forge/plugin-desktop-windows-observe";`
|
|
26
|
+
|
|
27
|
+
- `DesktopWindowsAdapter` — UIA adapter facade (the host's default desktop wiring constructs this one).
|
|
28
|
+
- `WindowsUiAutomationDriver(options?)` — PowerShell UIA driver; supports `command`/`timeoutMs`/`spawnSync`/`platform` injection for brokers and tests.
|
|
29
|
+
- `createDesktopObserveCapabilityFactoryV1(runtime)` — registers the five observation tools on a `CapabilityAPI`.
|
|
30
|
+
- Default export of `dist/entry.js` — the precomposed factory used by external plugin loading.
|
|
31
|
+
|
|
32
|
+
The UIA adapter code is a deliberate inlined copy shared with `@agent-forge/plugin-desktop-windows-input` so both packages stay self-contained.
|
|
33
|
+
|
|
34
|
+
## Development
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
npm install --ignore-scripts # repo root, creates the workspace symlink
|
|
38
|
+
npm run build # plugins/desktop-windows-observe (tsgo)
|
|
39
|
+
npm test # vitest; the entry fidelity test requires `npm run build` first
|
|
40
|
+
```
|
package/agent-forge.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"packageFormatVersion": 1,
|
|
3
|
+
"id": "agent-forge.plugin.desktop-windows-observe",
|
|
4
|
+
"pluginVersion": "0.84.4",
|
|
5
|
+
"apiVersion": "1",
|
|
6
|
+
"minHostVersion": "0.84.4",
|
|
7
|
+
"capabilityRefs": [
|
|
8
|
+
{ "id": "desktop-session", "version": 1 },
|
|
9
|
+
{ "id": "desktop-uia", "version": 1 }
|
|
10
|
+
],
|
|
11
|
+
"platform": {
|
|
12
|
+
"os": ["windows"],
|
|
13
|
+
"runtime": [{ "name": "node" }]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only desktop observation capability factory, migrated from agent-forge
|
|
3
|
+
* `src/profile/runtime-capabilities-desktop.ts` (`desktopFactory`, D-075 S3
|
|
4
|
+
* extraction). Differences from the host original:
|
|
5
|
+
* - The factory type is the public `CapabilityPluginSyncFactory` from the
|
|
6
|
+
* plugin SDK instead of the host-internal `BuiltinCapabilityPlugin`.
|
|
7
|
+
* - Projection helpers live in `projection.ts`, input helpers in `shared.ts`.
|
|
8
|
+
* Tool names, parameters, budgets and result shapes are unchanged.
|
|
9
|
+
*/
|
|
10
|
+
import type { CapabilityPluginSyncFactory } from "@agent-forge/plugin-sdk";
|
|
11
|
+
import type { DesktopReadonlyAdapterV1 } from "./types.ts";
|
|
12
|
+
export declare function createDesktopObserveCapabilityFactoryV1(runtime: DesktopReadonlyAdapterV1): CapabilityPluginSyncFactory;
|
|
13
|
+
//# sourceMappingURL=capability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAa3E,OAAO,KAAK,EAAE,wBAAwB,EAA2B,MAAM,YAAY,CAAC;AAEpF,wBAAgB,uCAAuC,CACtD,OAAO,EAAE,wBAAwB,GAC/B,2BAA2B,CAsH7B","sourcesContent":["/**\n * Read-only desktop observation capability factory, migrated from agent-forge\n * `src/profile/runtime-capabilities-desktop.ts` (`desktopFactory`, D-075 S3\n * extraction). Differences from the host 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, parameters, budgets and result shapes are unchanged.\n */\nimport type { CapabilityPluginSyncFactory } from \"@agent-forge/plugin-sdk\";\nimport { Type } from \"typebox\";\nimport {\n\tDESKTOP_MAX_STRING_CHARS_V1,\n\tdesktopCapabilities,\n\tdesktopClampedString,\n\tdesktopFailure,\n\tdesktopObservationResult,\n\tdesktopResultWithinBudget,\n\tdesktopSessionResult,\n\tdesktopStopResult,\n} from \"./projection.ts\";\nimport { nonEmptyString, signalFrom, toolInvocation } from \"./shared.ts\";\nimport type { DesktopReadonlyAdapterV1, DesktopSessionRequestV1 } from \"./types.ts\";\n\nexport function createDesktopObserveCapabilityFactoryV1(\n\truntime: DesktopReadonlyAdapterV1,\n): CapabilityPluginSyncFactory {\n\treturn (api) => {\n\t\tconst invoke = <T>(\n\t\t\toperationId: string,\n\t\t\taction: () => T,\n\t\t\tproject: (value: T) => unknown,\n\t\t\tsignal?: AbortSignal,\n\t\t) => {\n\t\t\tif (signal?.aborted)\n\t\t\t\treturn Promise.resolve(desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\"));\n\t\t\ttry {\n\t\t\t\tconst value = project(action());\n\t\t\t\treturn Promise.resolve(\n\t\t\t\t\tsignal?.aborted ? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\") : value,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\t// 透传原始诊断(dogfood 2026-09-25:无信息报错让一次观察失败的排障\n\t\t\t\t// 成本极高);code 仍是适配器/投影面失败。\n\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\treturn Promise.resolve(desktopFailure(operationId, \"desktop_adapter_failed\", detail));\n\t\t\t}\n\t\t};\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_probe\",\n\t\t\tlabel: \"Desktop probe\",\n\t\t\tdescription: \"Probe whether the selected Windows UI Automation adapter is available\",\n\t\t\tparameters: Type.Object({}),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tconst { operationId } = toolInvocation(first, second);\n\t\t\t\treturn invoke(\n\t\t\t\t\toperationId,\n\t\t\t\t\t() => runtime.probe(),\n\t\t\t\t\t(probe) => {\n\t\t\t\t\t\tconst capabilities = desktopCapabilities(probe.capabilities);\n\t\t\t\t\t\treturn desktopResultWithinBudget({\n\t\t\t\t\t\t\tversion: 1,\n\t\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\tstatus: probe.available ? (\"succeeded\" as const) : (\"unsupported\" as const),\n\t\t\t\t\t\t\tprobe: {\n\t\t\t\t\t\t\t\tavailable: probe.available,\n\t\t\t\t\t\t\t\tplatform: desktopClampedString(probe.platform, \"platform\"),\n\t\t\t\t\t\t\t\tdriver: \"windows-uia\" as const,\n\t\t\t\t\t\t\t\t...(capabilities === undefined ? {} : { capabilities }),\n\t\t\t\t\t\t\t\t...(probe.reason === undefined ? {} : { reason: desktopClampedString(probe.reason, \"reason\") }),\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\tsignalFrom(third),\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_session_open\",\n\t\t\tlabel: \"Open desktop session\",\n\t\t\tdescription: \"Open a foreground or VM-scoped read-only Windows desktop session\",\n\t\t\tparameters: Type.Object({\n\t\t\t\tisolation: Type.Union([Type.Literal(\"foreground\"), Type.Literal(\"vm\")]),\n\t\t\t\tapplicationId: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 })),\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\tif (input.isolation !== \"foreground\" && input.isolation !== \"vm\")\n\t\t\t\t\tthrow new Error(\"isolation must be foreground or vm\");\n\t\t\t\tconst request: DesktopSessionRequestV1 = {\n\t\t\t\t\tversion: 1,\n\t\t\t\t\tisolation: input.isolation,\n\t\t\t\t\t...(input.applicationId === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { applicationId: nonEmptyString(input.applicationId, \"applicationId\") }),\n\t\t\t\t};\n\t\t\t\treturn invoke(\n\t\t\t\t\toperationId,\n\t\t\t\t\t() => runtime.openSession(request),\n\t\t\t\t\t(value) => desktopSessionResult(value, operationId),\n\t\t\t\t\tsignalFrom(third),\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t\tfor (const [name, action] of [\n\t\t\t[\"desktop_observe\", \"observe\"],\n\t\t\t[\"desktop_reobserve\", \"reobserve\"],\n\t\t] as const) {\n\t\t\tapi.registerTool({\n\t\t\t\tname,\n\t\t\t\tlabel: name === \"desktop_observe\" ? \"Observe desktop\" : \"Re-observe desktop\",\n\t\t\t\tdescription: \"Return a bounded Windows UI Automation observation for an existing session\",\n\t\t\t\tparameters: Type.Object({\n\t\t\t\t\tsessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t}),\n\t\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\t\tconst { input, operationId } = toolInvocation(first, second);\n\t\t\t\t\tconst sessionId = nonEmptyString(input.sessionId, \"sessionId\");\n\t\t\t\t\treturn invoke(\n\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t() => runtime[action](sessionId),\n\t\t\t\t\t\t(value) => desktopObservationResult(value, operationId),\n\t\t\t\t\t\tsignalFrom(third),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_session_stop\",\n\t\t\tlabel: \"Stop desktop session\",\n\t\t\tdescription: \"Stop an existing read-only desktop session\",\n\t\t\tparameters: Type.Object({ sessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }) }),\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 sessionId = nonEmptyString(input.sessionId, \"sessionId\");\n\t\t\t\treturn invoke(\n\t\t\t\t\toperationId,\n\t\t\t\t\t() => runtime.stop(sessionId),\n\t\t\t\t\t(value) => desktopStopResult(value, operationId),\n\t\t\t\t\tsignalFrom(third),\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t};\n}\n"]}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { DESKTOP_MAX_STRING_CHARS_V1, desktopCapabilities, desktopClampedString, desktopFailure, desktopObservationResult, desktopResultWithinBudget, desktopSessionResult, desktopStopResult, } from "./projection.js";
|
|
3
|
+
import { nonEmptyString, signalFrom, toolInvocation } from "./shared.js";
|
|
4
|
+
export function createDesktopObserveCapabilityFactoryV1(runtime) {
|
|
5
|
+
return (api) => {
|
|
6
|
+
const invoke = (operationId, action, project, signal) => {
|
|
7
|
+
if (signal?.aborted)
|
|
8
|
+
return Promise.resolve(desktopFailure(operationId, "cancelled", "Desktop operation was cancelled"));
|
|
9
|
+
try {
|
|
10
|
+
const value = project(action());
|
|
11
|
+
return Promise.resolve(signal?.aborted ? desktopFailure(operationId, "cancelled", "Desktop operation was cancelled") : value);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
// 透传原始诊断(dogfood 2026-09-25:无信息报错让一次观察失败的排障
|
|
15
|
+
// 成本极高);code 仍是适配器/投影面失败。
|
|
16
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
17
|
+
return Promise.resolve(desktopFailure(operationId, "desktop_adapter_failed", detail));
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
api.registerTool({
|
|
21
|
+
name: "desktop_probe",
|
|
22
|
+
label: "Desktop probe",
|
|
23
|
+
description: "Probe whether the selected Windows UI Automation adapter is available",
|
|
24
|
+
parameters: Type.Object({}),
|
|
25
|
+
execute: async (first, second, third) => {
|
|
26
|
+
const { operationId } = toolInvocation(first, second);
|
|
27
|
+
return invoke(operationId, () => runtime.probe(), (probe) => {
|
|
28
|
+
const capabilities = desktopCapabilities(probe.capabilities);
|
|
29
|
+
return desktopResultWithinBudget({
|
|
30
|
+
version: 1,
|
|
31
|
+
operationId,
|
|
32
|
+
status: probe.available ? "succeeded" : "unsupported",
|
|
33
|
+
probe: {
|
|
34
|
+
available: probe.available,
|
|
35
|
+
platform: desktopClampedString(probe.platform, "platform"),
|
|
36
|
+
driver: "windows-uia",
|
|
37
|
+
...(capabilities === undefined ? {} : { capabilities }),
|
|
38
|
+
...(probe.reason === undefined ? {} : { reason: desktopClampedString(probe.reason, "reason") }),
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}, signalFrom(third));
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
api.registerTool({
|
|
45
|
+
name: "desktop_session_open",
|
|
46
|
+
label: "Open desktop session",
|
|
47
|
+
description: "Open a foreground or VM-scoped read-only Windows desktop session",
|
|
48
|
+
parameters: Type.Object({
|
|
49
|
+
isolation: Type.Union([Type.Literal("foreground"), Type.Literal("vm")]),
|
|
50
|
+
applicationId: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 })),
|
|
51
|
+
}),
|
|
52
|
+
execute: async (first, second, third) => {
|
|
53
|
+
const { input, operationId } = toolInvocation(first, second);
|
|
54
|
+
if (input.isolation !== "foreground" && input.isolation !== "vm")
|
|
55
|
+
throw new Error("isolation must be foreground or vm");
|
|
56
|
+
const request = {
|
|
57
|
+
version: 1,
|
|
58
|
+
isolation: input.isolation,
|
|
59
|
+
...(input.applicationId === undefined
|
|
60
|
+
? {}
|
|
61
|
+
: { applicationId: nonEmptyString(input.applicationId, "applicationId") }),
|
|
62
|
+
};
|
|
63
|
+
return invoke(operationId, () => runtime.openSession(request), (value) => desktopSessionResult(value, operationId), signalFrom(third));
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
for (const [name, action] of [
|
|
67
|
+
["desktop_observe", "observe"],
|
|
68
|
+
["desktop_reobserve", "reobserve"],
|
|
69
|
+
]) {
|
|
70
|
+
api.registerTool({
|
|
71
|
+
name,
|
|
72
|
+
label: name === "desktop_observe" ? "Observe desktop" : "Re-observe desktop",
|
|
73
|
+
description: "Return a bounded Windows UI Automation observation for an existing session",
|
|
74
|
+
parameters: Type.Object({
|
|
75
|
+
sessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),
|
|
76
|
+
}),
|
|
77
|
+
execute: async (first, second, third) => {
|
|
78
|
+
const { input, operationId } = toolInvocation(first, second);
|
|
79
|
+
const sessionId = nonEmptyString(input.sessionId, "sessionId");
|
|
80
|
+
return invoke(operationId, () => runtime[action](sessionId), (value) => desktopObservationResult(value, operationId), signalFrom(third));
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
api.registerTool({
|
|
85
|
+
name: "desktop_session_stop",
|
|
86
|
+
label: "Stop desktop session",
|
|
87
|
+
description: "Stop an existing read-only desktop session",
|
|
88
|
+
parameters: Type.Object({ sessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }) }),
|
|
89
|
+
execute: async (first, second, third) => {
|
|
90
|
+
const { input, operationId } = toolInvocation(first, second);
|
|
91
|
+
const sessionId = nonEmptyString(input.sessionId, "sessionId");
|
|
92
|
+
return invoke(operationId, () => runtime.stop(sessionId), (value) => desktopStopResult(value, operationId), signalFrom(third));
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=capability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Read-only desktop observation capability factory, migrated from agent-forge\n * `src/profile/runtime-capabilities-desktop.ts` (`desktopFactory`, D-075 S3\n * extraction). Differences from the host 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, parameters, budgets and result shapes are unchanged.\n */\nimport type { CapabilityPluginSyncFactory } from \"@agent-forge/plugin-sdk\";\nimport { Type } from \"typebox\";\nimport {\n\tDESKTOP_MAX_STRING_CHARS_V1,\n\tdesktopCapabilities,\n\tdesktopClampedString,\n\tdesktopFailure,\n\tdesktopObservationResult,\n\tdesktopResultWithinBudget,\n\tdesktopSessionResult,\n\tdesktopStopResult,\n} from \"./projection.ts\";\nimport { nonEmptyString, signalFrom, toolInvocation } from \"./shared.ts\";\nimport type { DesktopReadonlyAdapterV1, DesktopSessionRequestV1 } from \"./types.ts\";\n\nexport function createDesktopObserveCapabilityFactoryV1(\n\truntime: DesktopReadonlyAdapterV1,\n): CapabilityPluginSyncFactory {\n\treturn (api) => {\n\t\tconst invoke = <T>(\n\t\t\toperationId: string,\n\t\t\taction: () => T,\n\t\t\tproject: (value: T) => unknown,\n\t\t\tsignal?: AbortSignal,\n\t\t) => {\n\t\t\tif (signal?.aborted)\n\t\t\t\treturn Promise.resolve(desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\"));\n\t\t\ttry {\n\t\t\t\tconst value = project(action());\n\t\t\t\treturn Promise.resolve(\n\t\t\t\t\tsignal?.aborted ? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\") : value,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\t// 透传原始诊断(dogfood 2026-09-25:无信息报错让一次观察失败的排障\n\t\t\t\t// 成本极高);code 仍是适配器/投影面失败。\n\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\treturn Promise.resolve(desktopFailure(operationId, \"desktop_adapter_failed\", detail));\n\t\t\t}\n\t\t};\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_probe\",\n\t\t\tlabel: \"Desktop probe\",\n\t\t\tdescription: \"Probe whether the selected Windows UI Automation adapter is available\",\n\t\t\tparameters: Type.Object({}),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tconst { operationId } = toolInvocation(first, second);\n\t\t\t\treturn invoke(\n\t\t\t\t\toperationId,\n\t\t\t\t\t() => runtime.probe(),\n\t\t\t\t\t(probe) => {\n\t\t\t\t\t\tconst capabilities = desktopCapabilities(probe.capabilities);\n\t\t\t\t\t\treturn desktopResultWithinBudget({\n\t\t\t\t\t\t\tversion: 1,\n\t\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\tstatus: probe.available ? (\"succeeded\" as const) : (\"unsupported\" as const),\n\t\t\t\t\t\t\tprobe: {\n\t\t\t\t\t\t\t\tavailable: probe.available,\n\t\t\t\t\t\t\t\tplatform: desktopClampedString(probe.platform, \"platform\"),\n\t\t\t\t\t\t\t\tdriver: \"windows-uia\" as const,\n\t\t\t\t\t\t\t\t...(capabilities === undefined ? {} : { capabilities }),\n\t\t\t\t\t\t\t\t...(probe.reason === undefined ? {} : { reason: desktopClampedString(probe.reason, \"reason\") }),\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\tsignalFrom(third),\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_session_open\",\n\t\t\tlabel: \"Open desktop session\",\n\t\t\tdescription: \"Open a foreground or VM-scoped read-only Windows desktop session\",\n\t\t\tparameters: Type.Object({\n\t\t\t\tisolation: Type.Union([Type.Literal(\"foreground\"), Type.Literal(\"vm\")]),\n\t\t\t\tapplicationId: Type.Optional(Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 })),\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\tif (input.isolation !== \"foreground\" && input.isolation !== \"vm\")\n\t\t\t\t\tthrow new Error(\"isolation must be foreground or vm\");\n\t\t\t\tconst request: DesktopSessionRequestV1 = {\n\t\t\t\t\tversion: 1,\n\t\t\t\t\tisolation: input.isolation,\n\t\t\t\t\t...(input.applicationId === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { applicationId: nonEmptyString(input.applicationId, \"applicationId\") }),\n\t\t\t\t};\n\t\t\t\treturn invoke(\n\t\t\t\t\toperationId,\n\t\t\t\t\t() => runtime.openSession(request),\n\t\t\t\t\t(value) => desktopSessionResult(value, operationId),\n\t\t\t\t\tsignalFrom(third),\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t\tfor (const [name, action] of [\n\t\t\t[\"desktop_observe\", \"observe\"],\n\t\t\t[\"desktop_reobserve\", \"reobserve\"],\n\t\t] as const) {\n\t\t\tapi.registerTool({\n\t\t\t\tname,\n\t\t\t\tlabel: name === \"desktop_observe\" ? \"Observe desktop\" : \"Re-observe desktop\",\n\t\t\t\tdescription: \"Return a bounded Windows UI Automation observation for an existing session\",\n\t\t\t\tparameters: Type.Object({\n\t\t\t\t\tsessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }),\n\t\t\t\t}),\n\t\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\t\tconst { input, operationId } = toolInvocation(first, second);\n\t\t\t\t\tconst sessionId = nonEmptyString(input.sessionId, \"sessionId\");\n\t\t\t\t\treturn invoke(\n\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t() => runtime[action](sessionId),\n\t\t\t\t\t\t(value) => desktopObservationResult(value, operationId),\n\t\t\t\t\t\tsignalFrom(third),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\tapi.registerTool({\n\t\t\tname: \"desktop_session_stop\",\n\t\t\tlabel: \"Stop desktop session\",\n\t\t\tdescription: \"Stop an existing read-only desktop session\",\n\t\t\tparameters: Type.Object({ sessionId: Type.String({ minLength: 1, maxLength: DESKTOP_MAX_STRING_CHARS_V1 }) }),\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 sessionId = nonEmptyString(input.sessionId, \"sessionId\");\n\t\t\t\treturn invoke(\n\t\t\t\t\toperationId,\n\t\t\t\t\t() => runtime.stop(sessionId),\n\t\t\t\t\t(value) => desktopStopResult(value, operationId),\n\t\t\t\t\tsignalFrom(third),\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t};\n}\n"]}
|
package/dist/entry.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default-export factory consumed by the host's `loadCapabilityPluginFromManifest`.
|
|
3
|
+
*
|
|
4
|
+
* The adapter is constructed exactly like the host's default desktop wiring
|
|
5
|
+
* (`defaultDesktopRuntimeWiringV1`): one `DesktopWindowsAdapter` over the
|
|
6
|
+
* default `WindowsUiAutomationDriver` (powershell.exe, 15s timeout,
|
|
7
|
+
* `process.platform`). Non-Windows platforms never throw at import or call
|
|
8
|
+
* time: the driver probe reports unavailable and every tool returns an
|
|
9
|
+
* explicit `unsupported` result (fail-closed by design, same contract as the
|
|
10
|
+
* embedded build).
|
|
11
|
+
*/
|
|
12
|
+
declare const _default: import("@agent-forge/plugin-sdk").CapabilityPluginSyncFactory;
|
|
13
|
+
export default _default;
|
|
14
|
+
//# sourceMappingURL=entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;;AACH,wBAAoF","sourcesContent":["import { createDesktopObserveCapabilityFactoryV1 } from \"./capability.ts\";\nimport { DesktopWindowsAdapter } from \"./windows-uia-adapter.ts\";\n\n/**\n * Default-export factory consumed by the host's `loadCapabilityPluginFromManifest`.\n *\n * The adapter is constructed exactly like the host's default desktop wiring\n * (`defaultDesktopRuntimeWiringV1`): one `DesktopWindowsAdapter` over the\n * default `WindowsUiAutomationDriver` (powershell.exe, 15s timeout,\n * `process.platform`). Non-Windows platforms never throw at import or call\n * time: the driver probe reports unavailable and every tool returns an\n * explicit `unsupported` result (fail-closed by design, same contract as the\n * embedded build).\n */\nexport default createDesktopObserveCapabilityFactoryV1(new DesktopWindowsAdapter());\n"]}
|
package/dist/entry.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createDesktopObserveCapabilityFactoryV1 } from "./capability.js";
|
|
2
|
+
import { DesktopWindowsAdapter } from "./windows-uia-adapter.js";
|
|
3
|
+
/**
|
|
4
|
+
* Default-export factory consumed by the host's `loadCapabilityPluginFromManifest`.
|
|
5
|
+
*
|
|
6
|
+
* The adapter is constructed exactly like the host's default desktop wiring
|
|
7
|
+
* (`defaultDesktopRuntimeWiringV1`): one `DesktopWindowsAdapter` over the
|
|
8
|
+
* default `WindowsUiAutomationDriver` (powershell.exe, 15s timeout,
|
|
9
|
+
* `process.platform`). Non-Windows platforms never throw at import or call
|
|
10
|
+
* time: the driver probe reports unavailable and every tool returns an
|
|
11
|
+
* explicit `unsupported` result (fail-closed by design, same contract as the
|
|
12
|
+
* embedded build).
|
|
13
|
+
*/
|
|
14
|
+
export default createDesktopObserveCapabilityFactoryV1(new DesktopWindowsAdapter());
|
|
15
|
+
//# sourceMappingURL=entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uCAAuC,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE;;;;;;;;;;GAUG;AACH,eAAe,uCAAuC,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC","sourcesContent":["import { createDesktopObserveCapabilityFactoryV1 } from \"./capability.ts\";\nimport { DesktopWindowsAdapter } from \"./windows-uia-adapter.ts\";\n\n/**\n * Default-export factory consumed by the host's `loadCapabilityPluginFromManifest`.\n *\n * The adapter is constructed exactly like the host's default desktop wiring\n * (`defaultDesktopRuntimeWiringV1`): one `DesktopWindowsAdapter` over the\n * default `WindowsUiAutomationDriver` (powershell.exe, 15s timeout,\n * `process.platform`). Non-Windows platforms never throw at import or call\n * time: the driver probe reports unavailable and every tool returns an\n * explicit `unsupported` result (fail-closed by design, same contract as the\n * embedded build).\n */\nexport default createDesktopObserveCapabilityFactoryV1(new DesktopWindowsAdapter());\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createDesktopObserveCapabilityFactoryV1 } from "./capability.ts";
|
|
2
|
+
export { DESKTOP_MAX_POSTCONDITIONS_V1, DESKTOP_MAX_REPLAY_ACTIONS_V1, DESKTOP_MAX_STRING_CHARS_V1, DESKTOP_MAX_TYPE_TEXT_CHARS_V1, desktopBoundedString, desktopClampedString, desktopFailure, desktopRequiredString, desktopResultWithinBudget, projectDesktopObservation, } from "./projection.ts";
|
|
3
|
+
export type * from "./types.ts";
|
|
4
|
+
export type { WindowsUiAutomationDriverOptions } from "./windows-uia-adapter.ts";
|
|
5
|
+
export { DesktopWindowsAdapter, WindowsUiAutomationDriver } from "./windows-uia-adapter.ts";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uCAAuC,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EACN,6BAA6B,EAC7B,6BAA6B,EAC7B,2BAA2B,EAC3B,8BAA8B,EAC9B,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,yBAAyB,EACzB,yBAAyB,GACzB,MAAM,iBAAiB,CAAC;AACzB,mBAAmB,YAAY,CAAC;AAChC,YAAY,EAAE,gCAAgC,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["export { createDesktopObserveCapabilityFactoryV1 } from \"./capability.ts\";\nexport {\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\tdesktopClampedString,\n\tdesktopFailure,\n\tdesktopRequiredString,\n\tdesktopResultWithinBudget,\n\tprojectDesktopObservation,\n} from \"./projection.ts\";\nexport type * from \"./types.ts\";\nexport type { WindowsUiAutomationDriverOptions } from \"./windows-uia-adapter.ts\";\nexport { DesktopWindowsAdapter, WindowsUiAutomationDriver } from \"./windows-uia-adapter.ts\";\n"]}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createDesktopObserveCapabilityFactoryV1 } from "./capability.js";
|
|
2
|
+
export { DESKTOP_MAX_POSTCONDITIONS_V1, DESKTOP_MAX_REPLAY_ACTIONS_V1, DESKTOP_MAX_STRING_CHARS_V1, DESKTOP_MAX_TYPE_TEXT_CHARS_V1, desktopBoundedString, desktopClampedString, desktopFailure, desktopRequiredString, desktopResultWithinBudget, projectDesktopObservation, } from "./projection.js";
|
|
3
|
+
export { DesktopWindowsAdapter, WindowsUiAutomationDriver } from "./windows-uia-adapter.js";
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uCAAuC,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EACN,6BAA6B,EAC7B,6BAA6B,EAC7B,2BAA2B,EAC3B,8BAA8B,EAC9B,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,yBAAyB,EACzB,yBAAyB,GACzB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["export { createDesktopObserveCapabilityFactoryV1 } from \"./capability.ts\";\nexport {\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\tdesktopClampedString,\n\tdesktopFailure,\n\tdesktopRequiredString,\n\tdesktopResultWithinBudget,\n\tprojectDesktopObservation,\n} from \"./projection.ts\";\nexport type * from \"./types.ts\";\nexport type { WindowsUiAutomationDriverOptions } from \"./windows-uia-adapter.ts\";\nexport { DesktopWindowsAdapter, WindowsUiAutomationDriver } from \"./windows-uia-adapter.ts\";\n"]}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inlined from agent-forge `src/profile/runtime-capabilities-desktop.ts`
|
|
3
|
+
* (D-075 S3 extraction) so this package keeps its dependency closure limited
|
|
4
|
+
* to the plugin SDK and typebox. Semantics are unchanged. Differences from
|
|
5
|
+
* the host original:
|
|
6
|
+
* - Desktop V1 types import from the package-local `types.ts` copy.
|
|
7
|
+
* - The structural runtime guards (`desktopRuntime`/`desktopFullControlRuntime`)
|
|
8
|
+
and the capability factory stay host-side or live in `capability.ts`.
|
|
9
|
+
* Deliberate copy shared (subset-compatible) with
|
|
10
|
+
* `plugins/desktop-windows-input/src/projection.ts`; keep both in sync.
|
|
11
|
+
*/
|
|
12
|
+
import type { DesktopCapabilityIdV1, DesktopControlIdentityV1, DesktopObservationV1, DesktopWindowIdentityV1 } from "./types.ts";
|
|
13
|
+
export declare const DESKTOP_MAX_STRING_CHARS_V1 = 256;
|
|
14
|
+
export declare const DESKTOP_MAX_POSTCONDITIONS_V1 = 32;
|
|
15
|
+
export declare const DESKTOP_MAX_TYPE_TEXT_CHARS_V1 = 4096;
|
|
16
|
+
export declare const DESKTOP_MAX_REPLAY_ACTIONS_V1 = 32;
|
|
17
|
+
export declare function desktopFailure(operationId: string, code: string, message: string, status?: "failed" | "unsupported" | "cancelled" | "needs_user"): {
|
|
18
|
+
version: 1;
|
|
19
|
+
operationId: string;
|
|
20
|
+
status: "cancelled" | "failed" | "needs_user" | "unsupported";
|
|
21
|
+
summary: string;
|
|
22
|
+
error: {
|
|
23
|
+
version: 1;
|
|
24
|
+
code: string;
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export declare function desktopBoundedString(value: unknown, label: string): string;
|
|
29
|
+
export declare function desktopClampedString(value: unknown, label: string): string;
|
|
30
|
+
export declare function desktopRequiredString(value: unknown, label: string): string;
|
|
31
|
+
declare function desktopCapabilities(value: unknown): readonly DesktopCapabilityIdV1[] | undefined;
|
|
32
|
+
export declare function projectDesktopObservation(value: unknown): {
|
|
33
|
+
readonly observation: DesktopObservationV1;
|
|
34
|
+
readonly truncated: {
|
|
35
|
+
readonly windows: boolean;
|
|
36
|
+
readonly controls: boolean;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export declare function desktopResultWithinBudget<T>(value: T): T;
|
|
40
|
+
declare function desktopObservationResult(value: unknown, operationId: string): {
|
|
41
|
+
version: 1;
|
|
42
|
+
operationId: string;
|
|
43
|
+
status: "cancelled" | "failed" | "needs_user" | "unsupported";
|
|
44
|
+
summary: string;
|
|
45
|
+
error: {
|
|
46
|
+
version: 1;
|
|
47
|
+
code: string;
|
|
48
|
+
message: string;
|
|
49
|
+
};
|
|
50
|
+
} | {
|
|
51
|
+
version: number;
|
|
52
|
+
operationId: string;
|
|
53
|
+
status: "succeeded";
|
|
54
|
+
observation: {
|
|
55
|
+
version: 1;
|
|
56
|
+
sessionId: string;
|
|
57
|
+
observationId: string;
|
|
58
|
+
source: "mock" | "windows-uia";
|
|
59
|
+
focusedControlId?: string | undefined;
|
|
60
|
+
controls: DesktopControlIdentityV1[];
|
|
61
|
+
windows: DesktopWindowIdentityV1[];
|
|
62
|
+
};
|
|
63
|
+
truncated: {
|
|
64
|
+
windows: boolean;
|
|
65
|
+
controls: boolean;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
declare function desktopSessionResult(value: unknown, operationId: string): {
|
|
69
|
+
version: 1;
|
|
70
|
+
operationId: string;
|
|
71
|
+
status: "cancelled" | "failed" | "needs_user" | "unsupported";
|
|
72
|
+
summary: string;
|
|
73
|
+
error: {
|
|
74
|
+
version: 1;
|
|
75
|
+
code: string;
|
|
76
|
+
message: string;
|
|
77
|
+
};
|
|
78
|
+
} | {
|
|
79
|
+
version: number;
|
|
80
|
+
operationId: string;
|
|
81
|
+
status: "succeeded";
|
|
82
|
+
session: {
|
|
83
|
+
version: number;
|
|
84
|
+
sessionId: string;
|
|
85
|
+
isolation: string;
|
|
86
|
+
status: string;
|
|
87
|
+
applicationId?: string | undefined;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
declare function desktopStopResult(value: unknown, operationId: string): {
|
|
91
|
+
version: 1;
|
|
92
|
+
operationId: string;
|
|
93
|
+
status: "cancelled" | "failed" | "needs_user" | "unsupported";
|
|
94
|
+
summary: string;
|
|
95
|
+
error: {
|
|
96
|
+
version: 1;
|
|
97
|
+
code: string;
|
|
98
|
+
message: string;
|
|
99
|
+
};
|
|
100
|
+
} | {
|
|
101
|
+
version: number;
|
|
102
|
+
operationId: string;
|
|
103
|
+
status: "succeeded";
|
|
104
|
+
session: {
|
|
105
|
+
version: number;
|
|
106
|
+
sessionId: string;
|
|
107
|
+
isolation: string;
|
|
108
|
+
status: string;
|
|
109
|
+
applicationId?: string | undefined;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
export { desktopCapabilities, desktopObservationResult, desktopSessionResult, desktopStopResult };
|
|
113
|
+
//# sourceMappingURL=projection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../src/projection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EACX,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,uBAAuB,EACvB,MAAM,YAAY,CAAC;AAIpB,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,8BAA8B,OAAO,CAAC;AACnD,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAShD,wBAAgB,cAAc,CAC7B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,QAAQ,GAAG,aAAa,GAAG,WAAW,GAAG,YAAuB;;;;;;;;;;EASxE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI1E;AAKD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI1E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI3E;AAED,iBAAS,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,qBAAqB,EAAE,GAAG,SAAS,CAQzF;AAiDD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG;IAC1D,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;CAC9E,CAgCA;AAED,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAIxD;AAED,iBAAS,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkDpE;AAED,iBAAS,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;EAsChE;AAED,iBAAS,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;EAS7D;AAED,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["/**\n * Inlined from agent-forge `src/profile/runtime-capabilities-desktop.ts`\n * (D-075 S3 extraction) so this package keeps its dependency closure limited\n * to the plugin SDK and typebox. Semantics are unchanged. Differences from\n * the host original:\n * - Desktop V1 types import from the package-local `types.ts` copy.\n * - The structural runtime guards (`desktopRuntime`/`desktopFullControlRuntime`)\n and the capability factory stay host-side or live in `capability.ts`.\n * Deliberate copy shared (subset-compatible) with\n * `plugins/desktop-windows-input/src/projection.ts`; keep both in sync.\n */\nimport type {\n\tDesktopCapabilityIdV1,\n\tDesktopControlIdentityV1,\n\tDesktopObservationV1,\n\tDesktopWindowIdentityV1,\n} from \"./types.ts\";\n\nconst DESKTOP_MAX_WINDOWS_V1 = 64;\nconst DESKTOP_MAX_CONTROLS_V1 = 256;\nexport const DESKTOP_MAX_STRING_CHARS_V1 = 256;\nconst DESKTOP_MAX_RESULT_BYTES_V1 = 64 * 1024;\nexport const DESKTOP_MAX_POSTCONDITIONS_V1 = 32;\nexport const DESKTOP_MAX_TYPE_TEXT_CHARS_V1 = 4096;\nexport const DESKTOP_MAX_REPLAY_ACTIONS_V1 = 32;\nconst DESKTOP_CAPABILITY_IDS_V1: readonly DesktopCapabilityIdV1[] = [\n\t\"desktop-session\",\n\t\"desktop-uia\",\n\t\"desktop-input\",\n\t\"desktop-vision\",\n\t\"desktop-replay\",\n];\n\nexport function desktopFailure(\n\toperationId: string,\n\tcode: string,\n\tmessage: string,\n\tstatus: \"failed\" | \"unsupported\" | \"cancelled\" | \"needs_user\" = \"failed\",\n) {\n\treturn {\n\t\tversion: 1 as const,\n\t\toperationId,\n\t\tstatus,\n\t\tsummary: message,\n\t\terror: { version: 1 as const, code, message },\n\t};\n}\n\nexport function desktopBoundedString(value: unknown, label: string): string {\n\tif (typeof value !== \"string\" || value.length > DESKTOP_MAX_STRING_CHARS_V1)\n\t\tthrow new Error(`desktop-result-budget:${label}`);\n\treturn value;\n}\n\n/// 观察投影专用:显示文本超长时截断而非抛异常(dogfood 2026-09-25 实测,真实桌面\n/// 单控件文本超上限很常见)。输入校验(type text/key/target)仍用 desktopBoundedString\n/// 严格拒绝——截断输入等于静默打错字。\nexport function desktopClampedString(value: unknown, label: string): string {\n\tif (typeof value !== \"string\") throw new Error(`desktop-result-budget:${label}`);\n\tif (value.length > DESKTOP_MAX_STRING_CHARS_V1) return value.slice(0, DESKTOP_MAX_STRING_CHARS_V1);\n\treturn value;\n}\n\nexport function desktopRequiredString(value: unknown, label: string): string {\n\tconst result = desktopBoundedString(value, label);\n\tif (result.trim() === \"\") throw new Error(`desktop-result-invalid:${label}`);\n\treturn result;\n}\n\nfunction desktopCapabilities(value: unknown): readonly DesktopCapabilityIdV1[] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst capabilities = value.filter(\n\t\t(item): item is DesktopCapabilityIdV1 =>\n\t\t\ttypeof item === \"string\" && DESKTOP_CAPABILITY_IDS_V1.includes(item as DesktopCapabilityIdV1),\n\t);\n\tconst unique = [...new Set(capabilities)].slice(0, DESKTOP_CAPABILITY_IDS_V1.length);\n\treturn unique.length === 0 ? undefined : unique;\n}\n\nfunction desktopBounds(value: unknown): {\n\treadonly x: number;\n\treadonly y: number;\n\treadonly width: number;\n\treadonly height: number;\n} {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst record = value as Record<string, unknown>;\n\tconst bounds = { x: record.x, y: record.y, width: record.width, height: record.height };\n\tif (\n\t\tObject.values(bounds).some((item) => typeof item !== \"number\" || !Number.isFinite(item)) ||\n\t\t(bounds.width as number) < 0 ||\n\t\t(bounds.height as number) < 0\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\treturn bounds as { x: number; y: number; width: number; height: number };\n}\n\nfunction projectDesktopWindow(value: unknown): DesktopWindowIdentityV1 {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst record = value as Record<string, unknown>;\n\tif (record.version !== 1) throw new Error(\"desktop-result-invalid\");\n\treturn {\n\t\tversion: 1,\n\t\twindowId: desktopClampedString(record.windowId, \"windowId\"),\n\t\tappId: desktopClampedString(record.appId, \"appId\"),\n\t\ttitle: desktopClampedString(record.title, \"title\"),\n\t\tbounds: desktopBounds(record.bounds),\n\t};\n}\n\nfunction projectDesktopControl(value: unknown): DesktopControlIdentityV1 {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst record = value as Record<string, unknown>;\n\tif (record.version !== 1 || typeof record.enabled !== \"boolean\") throw new Error(\"desktop-result-invalid\");\n\treturn {\n\t\tversion: 1,\n\t\tcontrolId: desktopClampedString(record.controlId, \"controlId\"),\n\t\twindowId: desktopClampedString(record.windowId, \"windowId\"),\n\t\trole: desktopClampedString(record.role, \"role\"),\n\t\tname: desktopClampedString(record.name, \"name\"),\n\t\tbounds: desktopBounds(record.bounds),\n\t\tenabled: record.enabled,\n\t\t...(record.value === undefined ? {} : { value: desktopClampedString(record.value, \"value\") }),\n\t};\n}\n\nexport function projectDesktopObservation(value: unknown): {\n\treadonly observation: DesktopObservationV1;\n\treadonly truncated: { readonly windows: boolean; readonly controls: boolean };\n} {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"desktop-result-invalid\");\n\tconst record = value as Record<string, unknown>;\n\tif (\n\t\trecord.version !== 1 ||\n\t\ttypeof record.sessionId !== \"string\" ||\n\t\ttypeof record.observationId !== \"string\" ||\n\t\t(record.source !== \"mock\" && record.source !== \"windows-uia\") ||\n\t\t!Array.isArray(record.windows) ||\n\t\t!Array.isArray(record.controls)\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tconst windows = record.windows.slice(0, DESKTOP_MAX_WINDOWS_V1).map(projectDesktopWindow);\n\tconst controls = record.controls.slice(0, DESKTOP_MAX_CONTROLS_V1).map(projectDesktopControl);\n\tconst observation = {\n\t\tversion: 1 as const,\n\t\tsessionId: desktopClampedString(record.sessionId, \"sessionId\"),\n\t\tobservationId: desktopClampedString(record.observationId, \"observationId\"),\n\t\tsource: record.source,\n\t\twindows,\n\t\tcontrols,\n\t\t...(record.focusedControlId === undefined\n\t\t\t? {}\n\t\t\t: { focusedControlId: desktopClampedString(record.focusedControlId, \"focusedControlId\") }),\n\t} satisfies DesktopObservationV1;\n\treturn {\n\t\tobservation,\n\t\ttruncated: {\n\t\t\twindows: record.windows.length > DESKTOP_MAX_WINDOWS_V1,\n\t\t\tcontrols: record.controls.length > DESKTOP_MAX_CONTROLS_V1,\n\t\t},\n\t};\n}\n\nexport function desktopResultWithinBudget<T>(value: T): T {\n\tif (new TextEncoder().encode(JSON.stringify(value)).byteLength > DESKTOP_MAX_RESULT_BYTES_V1)\n\t\tthrow new Error(\"desktop-result-budget\");\n\treturn value;\n}\n\nfunction desktopObservationResult(value: unknown, operationId: string) {\n\tif (value !== null && typeof value === \"object\" && !Array.isArray(value) && \"observationId\" in value) {\n\t\tconst projected = projectDesktopObservation(value);\n\t\t// 真实桌面控件数轻松超出 64KB 结果预算(dogfood 2026-09-25 实测):超预算时\n\t\t// 控件/窗口逐级减半裁剪并如实标记 truncated,而不是让整次观察失败。\n\t\tconst controls = projected.observation.controls;\n\t\tconst windows = projected.observation.windows;\n\t\tlet controlCount = controls.length;\n\t\tlet windowCount = windows.length;\n\t\tfor (;;) {\n\t\t\ttry {\n\t\t\t\treturn desktopResultWithinBudget({\n\t\t\t\t\tversion: 1,\n\t\t\t\t\toperationId,\n\t\t\t\t\tstatus: \"succeeded\" as const,\n\t\t\t\t\tobservation: {\n\t\t\t\t\t\t...projected.observation,\n\t\t\t\t\t\tcontrols: controls.slice(0, controlCount),\n\t\t\t\t\t\twindows: windows.slice(0, windowCount),\n\t\t\t\t\t},\n\t\t\t\t\ttruncated: {\n\t\t\t\t\t\twindows: projected.truncated.windows || windowCount < windows.length,\n\t\t\t\t\t\tcontrols: projected.truncated.controls || controlCount < controls.length,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\tif (controlCount > 0) controlCount = Math.floor(controlCount / 2);\n\t\t\t\telse if (windowCount > 0) windowCount = Math.floor(windowCount / 2);\n\t\t\t\telse throw new Error(\"desktop-result-budget\");\n\t\t\t}\n\t\t}\n\t}\n\tif (value !== null && typeof value === \"object\" && !Array.isArray(value) && \"status\" in value) {\n\t\tconst status = value.status;\n\t\tif (status === \"unsupported\" || status === \"failed\" || status === \"cancelled\" || status === \"needs_user\") {\n\t\t\tconst record0 = value as Record<string, unknown>;\n\t\t\tconst adapterError =\n\t\t\t\t\"error\" in record0 && record0.error !== null && typeof record0.error === \"object\"\n\t\t\t\t\t? (record0.error as Record<string, unknown>)\n\t\t\t\t\t: undefined;\n\t\t\tconst errorCode =\n\t\t\t\tadapterError && typeof adapterError.code === \"string\" ? adapterError.code : \"desktop_adapter_failed\";\n\t\t\tconst errorMessage =\n\t\t\t\tadapterError && typeof adapterError.message === \"string\"\n\t\t\t\t\t? adapterError.message\n\t\t\t\t\t: \"Desktop observation is unavailable\";\n\t\t\treturn desktopFailure(operationId, errorCode, errorMessage, status);\n\t\t}\n\t}\n\tthrow new Error(\"desktop-result-invalid\");\n}\n\nfunction desktopSessionResult(value: unknown, operationId: string) {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value) || !(\"status\" in value))\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tconst record = value as Record<string, unknown>;\n\tif (record.status !== \"succeeded\" && record.status !== \"unsupported\" && record.status !== \"failed\")\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tif (record.status !== \"succeeded\")\n\t\treturn desktopFailure(\n\t\t\toperationId,\n\t\t\t\"desktop_adapter_unavailable\",\n\t\t\t\"Desktop session is unavailable\",\n\t\t\trecord.status,\n\t\t);\n\tconst session = record.session;\n\tif (session === null || typeof session !== \"object\" || Array.isArray(session))\n\t\tthrow new Error(\"desktop-result-invalid\");\n\tconst item = session as Record<string, unknown>;\n\tif (\n\t\titem.version !== 1 ||\n\t\ttypeof item.sessionId !== \"string\" ||\n\t\t(item.isolation !== \"foreground\" && item.isolation !== \"vm\" && item.isolation !== \"mock\") ||\n\t\t(item.status !== \"ready\" && item.status !== \"unavailable\" && item.status !== \"stopped\")\n\t)\n\t\tthrow new Error(\"desktop-result-invalid\");\n\treturn desktopResultWithinBudget({\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: \"succeeded\" as const,\n\t\tsession: {\n\t\t\tversion: 1,\n\t\t\tsessionId: desktopBoundedString(item.sessionId, \"sessionId\"),\n\t\t\tisolation: item.isolation,\n\t\t\tstatus: item.status,\n\t\t\t...(item.applicationId === undefined\n\t\t\t\t? {}\n\t\t\t\t: { applicationId: desktopBoundedString(item.applicationId, \"applicationId\") }),\n\t\t},\n\t});\n}\n\nfunction desktopStopResult(value: unknown, operationId: string) {\n\tif (value !== null && typeof value === \"object\" && !Array.isArray(value) && \"sessionId\" in value)\n\t\treturn desktopSessionResult({ status: \"succeeded\", session: value }, operationId);\n\tif (value !== null && typeof value === \"object\" && !Array.isArray(value) && \"status\" in value) {\n\t\tconst status = value.status;\n\t\tif (status === \"unsupported\" || status === \"failed\" || status === \"cancelled\" || status === \"needs_user\")\n\t\t\treturn desktopFailure(operationId, \"desktop_adapter_failed\", \"Desktop session could not be stopped\", status);\n\t}\n\tthrow new Error(\"desktop-result-invalid\");\n}\n\nexport { desktopCapabilities, desktopObservationResult, desktopSessionResult, desktopStopResult };\n"]}
|