@ai-agent-forge/plugin-desktop-macos-observe 0.88.10 → 0.88.12

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 CHANGED
@@ -16,7 +16,7 @@ fail-closed as the probe reason `accessibility-permission-required`; there is no
16
16
  agent-forge plugin install ./plugins/desktop-macos-observe
17
17
 
18
18
  # from npm
19
- agent-forge plugin install @agent-forge/plugin-desktop-macos-observe
19
+ agent-forge plugin install @ai-agent-forge/plugin-desktop-macos-observe
20
20
  ```
21
21
 
22
22
  The package ships two manifests: `agent-forge.json` (ecosystem manifest for the deterministic plugin resolver, `platform.os: ["macos"]`) and
package/agent-forge.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageFormatVersion": 1,
3
3
  "id": "agent-forge.plugin.desktop-macos-observe",
4
- "pluginVersion": "0.88.10",
4
+ "pluginVersion": "0.88.12",
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;;;;;;;;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, mirroring the Windows\n * package's `capability.ts` (migrated from agent-forge\n * `src/profile/runtime-capabilities-desktop.ts`, `desktopFactory`, D-075 S3\n * extraction). Differences from the Windows copy:\n * - The runtime type is the macOS read-only adapter from `types.ts`.\n * - The probe projection reports `driver: \"macos-ax\"`.\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 macOS Accessibility 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: \"macos-ax\" 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 macOS 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 macOS Accessibility 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"]}
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,CA6H7B","sourcesContent":["/**\n * Read-only desktop observation capability factory, mirroring the Windows\n * package's `capability.ts` (migrated from agent-forge\n * `src/profile/runtime-capabilities-desktop.ts`, `desktopFactory`, D-075 S3\n * extraction). Differences from the Windows copy:\n * - The runtime type is the macOS read-only adapter from `types.ts`.\n * - The probe projection reports `driver: \"macos-ax\"`.\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\t// Cancelled is a first-class terminal status: report it explicitly (same\n\t\t\t// semantics as the input packages and the screenshot cancel path), not\n\t\t\t// as desktopFailure's \"failed\" default.\n\t\t\tif (signal?.aborted)\n\t\t\t\treturn Promise.resolve(\n\t\t\t\t\tdesktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\"),\n\t\t\t\t);\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\n\t\t\t\t\t\t? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\")\n\t\t\t\t\t\t: 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 macOS Accessibility 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: \"macos-ax\" 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 macOS 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 macOS Accessibility 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"]}
@@ -4,11 +4,16 @@ import { nonEmptyString, signalFrom, toolInvocation } from "./shared.js";
4
4
  export function createDesktopObserveCapabilityFactoryV1(runtime) {
5
5
  return (api) => {
6
6
  const invoke = (operationId, action, project, signal) => {
7
+ // Cancelled is a first-class terminal status: report it explicitly (same
8
+ // semantics as the input packages and the screenshot cancel path), not
9
+ // as desktopFailure's "failed" default.
7
10
  if (signal?.aborted)
8
- return Promise.resolve(desktopFailure(operationId, "cancelled", "Desktop operation was cancelled"));
11
+ return Promise.resolve(desktopFailure(operationId, "cancelled", "Desktop operation was cancelled", "cancelled"));
9
12
  try {
10
13
  const value = project(action());
11
- return Promise.resolve(signal?.aborted ? desktopFailure(operationId, "cancelled", "Desktop operation was cancelled") : value);
14
+ return Promise.resolve(signal?.aborted
15
+ ? desktopFailure(operationId, "cancelled", "Desktop operation was cancelled", "cancelled")
16
+ : value);
12
17
  }
13
18
  catch (error) {
14
19
  // 透传原始诊断(dogfood 2026-09-25:无信息报错让一次观察失败的排障
@@ -1 +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, mirroring the Windows\n * package's `capability.ts` (migrated from agent-forge\n * `src/profile/runtime-capabilities-desktop.ts`, `desktopFactory`, D-075 S3\n * extraction). Differences from the Windows copy:\n * - The runtime type is the macOS read-only adapter from `types.ts`.\n * - The probe projection reports `driver: \"macos-ax\"`.\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 macOS Accessibility 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: \"macos-ax\" 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 macOS 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 macOS Accessibility 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"]}
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, mirroring the Windows\n * package's `capability.ts` (migrated from agent-forge\n * `src/profile/runtime-capabilities-desktop.ts`, `desktopFactory`, D-075 S3\n * extraction). Differences from the Windows copy:\n * - The runtime type is the macOS read-only adapter from `types.ts`.\n * - The probe projection reports `driver: \"macos-ax\"`.\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\t// Cancelled is a first-class terminal status: report it explicitly (same\n\t\t\t// semantics as the input packages and the screenshot cancel path), not\n\t\t\t// as desktopFailure's \"failed\" default.\n\t\t\tif (signal?.aborted)\n\t\t\t\treturn Promise.resolve(\n\t\t\t\t\tdesktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\"),\n\t\t\t\t);\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\n\t\t\t\t\t\t? desktopFailure(operationId, \"cancelled\", \"Desktop operation was cancelled\", \"cancelled\")\n\t\t\t\t\t\t: 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 macOS Accessibility 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: \"macos-ax\" 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 macOS 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 macOS Accessibility 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-agent-forge/plugin-desktop-macos-observe",
3
- "version": "0.88.10",
3
+ "version": "0.88.12",
4
4
  "description": "Read-only macOS desktop observation capability plugin for Agent Forge (desktop_probe, desktop_session_open, desktop_observe, desktop_reobserve, desktop_session_stop)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -22,7 +22,8 @@
22
22
  "clean": "shx rm -rf dist",
23
23
  "build": "tsgo -p tsconfig.build.json",
24
24
  "test": "vitest --run",
25
- "prepublishOnly": "npm run clean && npm run build"
25
+ "prepublishOnly": "npm run clean && npm run build",
26
+ "test:coverage": "vitest --run --coverage"
26
27
  },
27
28
  "keywords": [
28
29
  "agent-forge",
@@ -48,10 +49,10 @@
48
49
  },
49
50
  "dependencies": {
50
51
  "typebox": "1.3.27",
51
- "@ai-agent-forge/plugin-sdk": "^0.88.10"
52
+ "@ai-agent-forge/plugin-sdk": "^0.88.12"
52
53
  },
53
54
  "devDependencies": {
54
- "shx": "0.4.0",
55
+ "shx": "0.3.4",
55
56
  "vitest": "4.1.11"
56
57
  }
57
58
  }
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "agent-forge.plugin.desktop-macos-observe",
3
- "version": "0.88.10",
3
+ "version": "0.88.12",
4
4
  "apiVersion": "1-draft",
5
5
  "entry": "./dist/entry.js",
6
6
  "hostVersion": ">=0.84.4",