@agimon-ai/po-computer-use 0.0.0-alpha.50 → 0.0.0-alpha.52
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/dist/apiContracts.cjs +3 -3
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.mjs +3 -3
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/extensions/native.mjs +125 -17
- package/dist/extensions/native.mjs.map +1 -1
- package/dist/extensions/server.cjs +10 -9
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.mjs +10 -9
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +161 -139
- package/dist/extensions/web.mjs.map +1 -1
- package/package.json +10 -10
- package/src/prompts/codemode-how-to-computer-use/SKILL.md +11 -9
package/dist/apiContracts.cjs
CHANGED
|
@@ -169,15 +169,15 @@ const apiContracts = (0, _agimon_ai_po_core_apiContracts.defineApiContract)({
|
|
|
169
169
|
path: "/activate",
|
|
170
170
|
method: "POST",
|
|
171
171
|
authentication: "owner",
|
|
172
|
-
description: "Request confirmed Desktop access with admitted caller and remote step-up context.
|
|
172
|
+
description: "Request confirmed Desktop access with admitted caller and remote step-up context. The target is one application window or the whole desktop; a remote caller may omit it so the local Mac selects.",
|
|
173
173
|
body: {
|
|
174
174
|
required: true,
|
|
175
175
|
contentType: "application/json",
|
|
176
176
|
schema: typebox.Type.Object({
|
|
177
|
-
target: O(typebox.Type.Object({
|
|
177
|
+
target: O(typebox.Type.Union([typebox.Type.Object({
|
|
178
178
|
windowId: S,
|
|
179
179
|
bundleId: S
|
|
180
|
-
})),
|
|
180
|
+
}), typebox.Type.Object({ scope: typebox.Type.Literal("desktop") })])),
|
|
181
181
|
durationMs: typebox.Type.Integer({
|
|
182
182
|
minimum: 1e3,
|
|
183
183
|
maximum: 18e5
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.cjs","names":["Type","jsonApiResponses","defineApiContract"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses, type PoHttpContract } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst O = Type.Optional;\nconst values = <T extends string>(items: T[]) => Type.Union(items.map((item) => Type.Literal(item)));\nconst Json = Type.Unknown({\n description:\n 'Desktop provider JSON value. Targets, observations and action results are supplied by the admitted Desktop provider.',\n});\nconst Target = Type.Record(S, Json);\nconst Error = Type.Object({ code: S, message: S });\nconst Artifact = Type.Object({\n artifactId: S,\n status: values(['ready', 'failed']),\n sizeBytes: O(N),\n downloadUrl: O(S),\n previewUrl: O(S),\n actionCount: O(N),\n completedAt: O(S),\n failure: O(Error),\n});\nexport const ComputerStateSchema = Type.Object({\n sessionId: S,\n revision: N,\n wake: N,\n phase: values(['inactive', 'awaiting_confirmation', 'activating', 'active', 'stopping', 'failed']),\n requestId: O(S),\n target: O(Target),\n durationMs: O(N),\n expiresAt: O(N),\n failure: O(Error),\n artifact: O(Artifact),\n});\nconst Permission = values(['accessibility', 'screen-recording', 'microphone', 'automation', 'full-disk-access']);\nconst PermissionState = values(['granted', 'denied', 'not-determined', 'per-app']);\nexport const DesktopPermissionStatesSchema = Type.Object({\n accessibility: PermissionState,\n 'screen-recording': PermissionState,\n microphone: PermissionState,\n automation: PermissionState,\n 'full-disk-access': PermissionState,\n});\nconst Reference = { snapshotId: Type.String({ minLength: 1 }), elementRef: Type.String({ minLength: 1 }) };\nexport const ComputerActionSchema = Type.Union([\n Type.Object({ kind: values(['press', 'focus']), ...Reference }, { additionalProperties: false }),\n Type.Object({ kind: Type.Literal('set_value'), ...Reference, value: S }, { additionalProperties: false }),\n Type.Object(\n {\n kind: Type.Literal('scroll'),\n ...Reference,\n direction: values(['up', 'down', 'left', 'right']),\n amount: values(['line', 'page']),\n },\n { additionalProperties: false },\n ),\n]);\nconst internal = (\n method: 'GET' | 'POST',\n path: string,\n output: object,\n body?: object,\n status = 200,\n): PoHttpContract => ({\n id: `computer.${path.slice(1).replaceAll('/', '.')}`,\n scope: 'session',\n basePath: 'computer-use',\n path,\n method,\n authentication: 'owner',\n description: `Computer use broker ${path}. Requires the host-issued ${path.startsWith('/agent/') ? 'agent' : 'hub'} bearer token.`,\n availability: 'Internal broker route; ordinary browser credentials are insufficient.',\n parameters: [{ name: 'Authorization', in: 'header', required: true, schema: Type.String({ pattern: '^Bearer .+' }) }],\n ...(body ? { body: { required: true, contentType: 'application/json', schema: body } } : {}),\n responses: jsonApiResponses(output, status),\n});\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: ['Desktop provider target extensions, observations and operation results are runtime-defined JSON.'],\n http: [\n ...(['global', 'workspace', 'session'] as const).flatMap((scope) =>\n (['GET', 'POST'] as const).map((method) => ({\n id: `computer.permissions.${method === 'GET' ? 'read' : 'request'}`,\n scope,\n basePath: 'desktop-permissions',\n path: '/',\n method,\n authentication: 'owner' as const,\n description:\n method === 'GET'\n ? 'Read the Mac-owned permission states. Requires an authorized local Desktop caller or trusted remote caller.'\n : 'Ask macOS for one named permission. Requires an authorized local Desktop caller or remote passkey step-up.',\n availability: 'Requires Po Desktop to be running this server; otherwise returns 404.',\n ...(method === 'POST'\n ? {\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ permission: Permission }),\n },\n }\n : {}),\n responses: {\n ...jsonApiResponses(DesktopPermissionStatesSchema),\n '502': { description: 'Desktop permission request failed.', schema: Type.Object({ error: S }) },\n },\n })),\n ),\n {\n id: 'computer.activation.state',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'GET',\n authentication: 'owner',\n description: 'Read state as the matching pending requester or approved recording reader.',\n responses: jsonApiResponses(ComputerStateSchema),\n },\n {\n id: 'computer.activation.cancel',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'DELETE',\n authentication: 'owner',\n description: 'Cancel only the matching requester pending activation.',\n responses: jsonApiResponses(ComputerStateSchema, 202),\n },\n {\n id: 'computer.activate',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'POST',\n authentication: 'owner',\n description:\n 'Request confirmed Desktop access with admitted caller and remote step-up context. A remote caller may omit target so the local Mac selects the window.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({\n target: O(Type.Object({ windowId: S, bundleId: S })),\n durationMs: Type.Integer({ minimum: 1000, maximum: 1800000 }),\n }),\n },\n responses: jsonApiResponses(ComputerStateSchema, 202),\n },\n {\n id: 'computer.artifact',\n scope: 'session',\n basePath: 'computer-use',\n path: '/artifact',\n method: 'GET',\n authentication: 'owner',\n description: 'Read at most 1 MiB of a recording belonging to this session and approved caller.',\n parameters: [\n { name: 'artifactId', in: 'query', required: true, schema: S },\n { name: 'offset', in: 'query', required: true, schema: Type.Integer({ minimum: 0 }) },\n ],\n responses: {\n 206: {\n description: 'Bounded recording bytes.',\n contentType: 'video/mp4',\n schema: Type.String({ format: 'binary' }),\n },\n },\n },\n internal('GET', '/agent/state', ComputerStateSchema),\n internal('GET', '/hub/state', ComputerStateSchema),\n internal('POST', '/agent/observe', Json),\n internal('POST', '/agent/action', Json, ComputerActionSchema),\n internal('POST', '/agent/stop', ComputerStateSchema, undefined, 202),\n internal(\n 'GET',\n '/hub/activation',\n Type.Union([\n Type.Null(),\n Type.Object({\n requestId: S,\n target: Target,\n durationSeconds: N,\n createdAt: N,\n confirmationExpiresAt: N,\n caller: Type.Object({ locality: values(['local', 'remote']), stepUp: S }),\n }),\n ]),\n ),\n internal('GET', '/hub/authorization', Type.Union([Type.Null(), Type.Object({ grantId: S, expiresAt: O(N) })])),\n internal(\n 'GET',\n '/hub/next',\n Type.Union([\n Type.Null(),\n Type.Object({ id: S, operation: values(['observe', 'act']), payload: O(Json), grantId: S, sequence: O(N) }),\n ]),\n ),\n internal('POST', '/hub/complete', ComputerStateSchema, Type.Object({ id: S, error: O(S), result: O(Json) })),\n internal(\n 'POST',\n '/hub/stop',\n ComputerStateSchema,\n Type.Object({ error: O(S), host: O(Type.Object({ grantId: S, expiresAt: N })), artifact: O(Artifact) }),\n ),\n ],\n sockets: (['global', 'workspace'] as const).flatMap((scope) => [\n {\n id: 'computer.state',\n scope,\n service: 'po.hub',\n member: 'computer_use_state',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'Computer use channel payload.',\n input: Type.Object({ state: ComputerStateSchema, targets: Type.Array(Target), busy: O(Type.Literal(true)) }),\n },\n {\n id: 'computer.command',\n scope,\n service: 'po.hub',\n member: 'computer_use_state',\n kind: 'channel',\n direction: 'client-to-server',\n description: 'Computer use browser channel command.',\n input: Type.Object({ action: values(['status', 'targets', 'stop', 'artifacts']) }),\n },\n ]),\n});\nexport default apiContracts;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"apiContracts.cjs","names":["Type","jsonApiResponses","defineApiContract"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses, type PoHttpContract } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst O = Type.Optional;\nconst values = <T extends string>(items: T[]) => Type.Union(items.map((item) => Type.Literal(item)));\nconst Json = Type.Unknown({\n description:\n 'Desktop provider JSON value. Targets, observations and action results are supplied by the admitted Desktop provider.',\n});\nconst Target = Type.Record(S, Json);\nconst Error = Type.Object({ code: S, message: S });\nconst Artifact = Type.Object({\n artifactId: S,\n status: values(['ready', 'failed']),\n sizeBytes: O(N),\n downloadUrl: O(S),\n previewUrl: O(S),\n actionCount: O(N),\n completedAt: O(S),\n failure: O(Error),\n});\nexport const ComputerStateSchema = Type.Object({\n sessionId: S,\n revision: N,\n wake: N,\n phase: values(['inactive', 'awaiting_confirmation', 'activating', 'active', 'stopping', 'failed']),\n requestId: O(S),\n target: O(Target),\n durationMs: O(N),\n expiresAt: O(N),\n failure: O(Error),\n artifact: O(Artifact),\n});\nconst Permission = values(['accessibility', 'screen-recording', 'microphone', 'automation', 'full-disk-access']);\nconst PermissionState = values(['granted', 'denied', 'not-determined', 'per-app']);\nexport const DesktopPermissionStatesSchema = Type.Object({\n accessibility: PermissionState,\n 'screen-recording': PermissionState,\n microphone: PermissionState,\n automation: PermissionState,\n 'full-disk-access': PermissionState,\n});\nconst Reference = { snapshotId: Type.String({ minLength: 1 }), elementRef: Type.String({ minLength: 1 }) };\nexport const ComputerActionSchema = Type.Union([\n Type.Object({ kind: values(['press', 'focus']), ...Reference }, { additionalProperties: false }),\n Type.Object({ kind: Type.Literal('set_value'), ...Reference, value: S }, { additionalProperties: false }),\n Type.Object(\n {\n kind: Type.Literal('scroll'),\n ...Reference,\n direction: values(['up', 'down', 'left', 'right']),\n amount: values(['line', 'page']),\n },\n { additionalProperties: false },\n ),\n]);\nconst internal = (\n method: 'GET' | 'POST',\n path: string,\n output: object,\n body?: object,\n status = 200,\n): PoHttpContract => ({\n id: `computer.${path.slice(1).replaceAll('/', '.')}`,\n scope: 'session',\n basePath: 'computer-use',\n path,\n method,\n authentication: 'owner',\n description: `Computer use broker ${path}. Requires the host-issued ${path.startsWith('/agent/') ? 'agent' : 'hub'} bearer token.`,\n availability: 'Internal broker route; ordinary browser credentials are insufficient.',\n parameters: [{ name: 'Authorization', in: 'header', required: true, schema: Type.String({ pattern: '^Bearer .+' }) }],\n ...(body ? { body: { required: true, contentType: 'application/json', schema: body } } : {}),\n responses: jsonApiResponses(output, status),\n});\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: ['Desktop provider target extensions, observations and operation results are runtime-defined JSON.'],\n http: [\n ...(['global', 'workspace', 'session'] as const).flatMap((scope) =>\n (['GET', 'POST'] as const).map((method) => ({\n id: `computer.permissions.${method === 'GET' ? 'read' : 'request'}`,\n scope,\n basePath: 'desktop-permissions',\n path: '/',\n method,\n authentication: 'owner' as const,\n description:\n method === 'GET'\n ? 'Read the Mac-owned permission states. Requires an authorized local Desktop caller or trusted remote caller.'\n : 'Ask macOS for one named permission. Requires an authorized local Desktop caller or remote passkey step-up.',\n availability: 'Requires Po Desktop to be running this server; otherwise returns 404.',\n ...(method === 'POST'\n ? {\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ permission: Permission }),\n },\n }\n : {}),\n responses: {\n ...jsonApiResponses(DesktopPermissionStatesSchema),\n '502': { description: 'Desktop permission request failed.', schema: Type.Object({ error: S }) },\n },\n })),\n ),\n {\n id: 'computer.activation.state',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'GET',\n authentication: 'owner',\n description: 'Read state as the matching pending requester or approved recording reader.',\n responses: jsonApiResponses(ComputerStateSchema),\n },\n {\n id: 'computer.activation.cancel',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'DELETE',\n authentication: 'owner',\n description: 'Cancel only the matching requester pending activation.',\n responses: jsonApiResponses(ComputerStateSchema, 202),\n },\n {\n id: 'computer.activate',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'POST',\n authentication: 'owner',\n description:\n 'Request confirmed Desktop access with admitted caller and remote step-up context. The target is one application window or the whole desktop; a remote caller may omit it so the local Mac selects.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({\n target: O(\n Type.Union([Type.Object({ windowId: S, bundleId: S }), Type.Object({ scope: Type.Literal('desktop') })]),\n ),\n durationMs: Type.Integer({ minimum: 1000, maximum: 1800000 }),\n }),\n },\n responses: jsonApiResponses(ComputerStateSchema, 202),\n },\n {\n id: 'computer.artifact',\n scope: 'session',\n basePath: 'computer-use',\n path: '/artifact',\n method: 'GET',\n authentication: 'owner',\n description: 'Read at most 1 MiB of a recording belonging to this session and approved caller.',\n parameters: [\n { name: 'artifactId', in: 'query', required: true, schema: S },\n { name: 'offset', in: 'query', required: true, schema: Type.Integer({ minimum: 0 }) },\n ],\n responses: {\n 206: {\n description: 'Bounded recording bytes.',\n contentType: 'video/mp4',\n schema: Type.String({ format: 'binary' }),\n },\n },\n },\n internal('GET', '/agent/state', ComputerStateSchema),\n internal('GET', '/hub/state', ComputerStateSchema),\n internal('POST', '/agent/observe', Json),\n internal('POST', '/agent/action', Json, ComputerActionSchema),\n internal('POST', '/agent/stop', ComputerStateSchema, undefined, 202),\n internal(\n 'GET',\n '/hub/activation',\n Type.Union([\n Type.Null(),\n Type.Object({\n requestId: S,\n target: Target,\n durationSeconds: N,\n createdAt: N,\n confirmationExpiresAt: N,\n caller: Type.Object({ locality: values(['local', 'remote']), stepUp: S }),\n }),\n ]),\n ),\n internal('GET', '/hub/authorization', Type.Union([Type.Null(), Type.Object({ grantId: S, expiresAt: O(N) })])),\n internal(\n 'GET',\n '/hub/next',\n Type.Union([\n Type.Null(),\n Type.Object({ id: S, operation: values(['observe', 'act']), payload: O(Json), grantId: S, sequence: O(N) }),\n ]),\n ),\n internal('POST', '/hub/complete', ComputerStateSchema, Type.Object({ id: S, error: O(S), result: O(Json) })),\n internal(\n 'POST',\n '/hub/stop',\n ComputerStateSchema,\n Type.Object({ error: O(S), host: O(Type.Object({ grantId: S, expiresAt: N })), artifact: O(Artifact) }),\n ),\n ],\n sockets: (['global', 'workspace'] as const).flatMap((scope) => [\n {\n id: 'computer.state',\n scope,\n service: 'po.hub',\n member: 'computer_use_state',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'Computer use channel payload.',\n input: Type.Object({ state: ComputerStateSchema, targets: Type.Array(Target), busy: O(Type.Literal(true)) }),\n },\n {\n id: 'computer.command',\n scope,\n service: 'po.hub',\n member: 'computer_use_state',\n kind: 'channel',\n direction: 'client-to-server',\n description: 'Computer use browser channel command.',\n input: Type.Object({ action: values(['status', 'targets', 'stop', 'artifacts']) }),\n },\n ]),\n});\nexport default apiContracts;\n"],"mappings":"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"}
|
package/dist/apiContracts.mjs
CHANGED
|
@@ -165,15 +165,15 @@ const apiContracts = defineApiContract({
|
|
|
165
165
|
path: "/activate",
|
|
166
166
|
method: "POST",
|
|
167
167
|
authentication: "owner",
|
|
168
|
-
description: "Request confirmed Desktop access with admitted caller and remote step-up context.
|
|
168
|
+
description: "Request confirmed Desktop access with admitted caller and remote step-up context. The target is one application window or the whole desktop; a remote caller may omit it so the local Mac selects.",
|
|
169
169
|
body: {
|
|
170
170
|
required: true,
|
|
171
171
|
contentType: "application/json",
|
|
172
172
|
schema: Type.Object({
|
|
173
|
-
target: O(Type.Object({
|
|
173
|
+
target: O(Type.Union([Type.Object({
|
|
174
174
|
windowId: S,
|
|
175
175
|
bundleId: S
|
|
176
|
-
})),
|
|
176
|
+
}), Type.Object({ scope: Type.Literal("desktop") })])),
|
|
177
177
|
durationMs: Type.Integer({
|
|
178
178
|
minimum: 1e3,
|
|
179
179
|
maximum: 18e5
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses, type PoHttpContract } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst O = Type.Optional;\nconst values = <T extends string>(items: T[]) => Type.Union(items.map((item) => Type.Literal(item)));\nconst Json = Type.Unknown({\n description:\n 'Desktop provider JSON value. Targets, observations and action results are supplied by the admitted Desktop provider.',\n});\nconst Target = Type.Record(S, Json);\nconst Error = Type.Object({ code: S, message: S });\nconst Artifact = Type.Object({\n artifactId: S,\n status: values(['ready', 'failed']),\n sizeBytes: O(N),\n downloadUrl: O(S),\n previewUrl: O(S),\n actionCount: O(N),\n completedAt: O(S),\n failure: O(Error),\n});\nexport const ComputerStateSchema = Type.Object({\n sessionId: S,\n revision: N,\n wake: N,\n phase: values(['inactive', 'awaiting_confirmation', 'activating', 'active', 'stopping', 'failed']),\n requestId: O(S),\n target: O(Target),\n durationMs: O(N),\n expiresAt: O(N),\n failure: O(Error),\n artifact: O(Artifact),\n});\nconst Permission = values(['accessibility', 'screen-recording', 'microphone', 'automation', 'full-disk-access']);\nconst PermissionState = values(['granted', 'denied', 'not-determined', 'per-app']);\nexport const DesktopPermissionStatesSchema = Type.Object({\n accessibility: PermissionState,\n 'screen-recording': PermissionState,\n microphone: PermissionState,\n automation: PermissionState,\n 'full-disk-access': PermissionState,\n});\nconst Reference = { snapshotId: Type.String({ minLength: 1 }), elementRef: Type.String({ minLength: 1 }) };\nexport const ComputerActionSchema = Type.Union([\n Type.Object({ kind: values(['press', 'focus']), ...Reference }, { additionalProperties: false }),\n Type.Object({ kind: Type.Literal('set_value'), ...Reference, value: S }, { additionalProperties: false }),\n Type.Object(\n {\n kind: Type.Literal('scroll'),\n ...Reference,\n direction: values(['up', 'down', 'left', 'right']),\n amount: values(['line', 'page']),\n },\n { additionalProperties: false },\n ),\n]);\nconst internal = (\n method: 'GET' | 'POST',\n path: string,\n output: object,\n body?: object,\n status = 200,\n): PoHttpContract => ({\n id: `computer.${path.slice(1).replaceAll('/', '.')}`,\n scope: 'session',\n basePath: 'computer-use',\n path,\n method,\n authentication: 'owner',\n description: `Computer use broker ${path}. Requires the host-issued ${path.startsWith('/agent/') ? 'agent' : 'hub'} bearer token.`,\n availability: 'Internal broker route; ordinary browser credentials are insufficient.',\n parameters: [{ name: 'Authorization', in: 'header', required: true, schema: Type.String({ pattern: '^Bearer .+' }) }],\n ...(body ? { body: { required: true, contentType: 'application/json', schema: body } } : {}),\n responses: jsonApiResponses(output, status),\n});\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: ['Desktop provider target extensions, observations and operation results are runtime-defined JSON.'],\n http: [\n ...(['global', 'workspace', 'session'] as const).flatMap((scope) =>\n (['GET', 'POST'] as const).map((method) => ({\n id: `computer.permissions.${method === 'GET' ? 'read' : 'request'}`,\n scope,\n basePath: 'desktop-permissions',\n path: '/',\n method,\n authentication: 'owner' as const,\n description:\n method === 'GET'\n ? 'Read the Mac-owned permission states. Requires an authorized local Desktop caller or trusted remote caller.'\n : 'Ask macOS for one named permission. Requires an authorized local Desktop caller or remote passkey step-up.',\n availability: 'Requires Po Desktop to be running this server; otherwise returns 404.',\n ...(method === 'POST'\n ? {\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ permission: Permission }),\n },\n }\n : {}),\n responses: {\n ...jsonApiResponses(DesktopPermissionStatesSchema),\n '502': { description: 'Desktop permission request failed.', schema: Type.Object({ error: S }) },\n },\n })),\n ),\n {\n id: 'computer.activation.state',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'GET',\n authentication: 'owner',\n description: 'Read state as the matching pending requester or approved recording reader.',\n responses: jsonApiResponses(ComputerStateSchema),\n },\n {\n id: 'computer.activation.cancel',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'DELETE',\n authentication: 'owner',\n description: 'Cancel only the matching requester pending activation.',\n responses: jsonApiResponses(ComputerStateSchema, 202),\n },\n {\n id: 'computer.activate',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'POST',\n authentication: 'owner',\n description:\n 'Request confirmed Desktop access with admitted caller and remote step-up context. A remote caller may omit target so the local Mac selects the window.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({\n target: O(Type.Object({ windowId: S, bundleId: S })),\n durationMs: Type.Integer({ minimum: 1000, maximum: 1800000 }),\n }),\n },\n responses: jsonApiResponses(ComputerStateSchema, 202),\n },\n {\n id: 'computer.artifact',\n scope: 'session',\n basePath: 'computer-use',\n path: '/artifact',\n method: 'GET',\n authentication: 'owner',\n description: 'Read at most 1 MiB of a recording belonging to this session and approved caller.',\n parameters: [\n { name: 'artifactId', in: 'query', required: true, schema: S },\n { name: 'offset', in: 'query', required: true, schema: Type.Integer({ minimum: 0 }) },\n ],\n responses: {\n 206: {\n description: 'Bounded recording bytes.',\n contentType: 'video/mp4',\n schema: Type.String({ format: 'binary' }),\n },\n },\n },\n internal('GET', '/agent/state', ComputerStateSchema),\n internal('GET', '/hub/state', ComputerStateSchema),\n internal('POST', '/agent/observe', Json),\n internal('POST', '/agent/action', Json, ComputerActionSchema),\n internal('POST', '/agent/stop', ComputerStateSchema, undefined, 202),\n internal(\n 'GET',\n '/hub/activation',\n Type.Union([\n Type.Null(),\n Type.Object({\n requestId: S,\n target: Target,\n durationSeconds: N,\n createdAt: N,\n confirmationExpiresAt: N,\n caller: Type.Object({ locality: values(['local', 'remote']), stepUp: S }),\n }),\n ]),\n ),\n internal('GET', '/hub/authorization', Type.Union([Type.Null(), Type.Object({ grantId: S, expiresAt: O(N) })])),\n internal(\n 'GET',\n '/hub/next',\n Type.Union([\n Type.Null(),\n Type.Object({ id: S, operation: values(['observe', 'act']), payload: O(Json), grantId: S, sequence: O(N) }),\n ]),\n ),\n internal('POST', '/hub/complete', ComputerStateSchema, Type.Object({ id: S, error: O(S), result: O(Json) })),\n internal(\n 'POST',\n '/hub/stop',\n ComputerStateSchema,\n Type.Object({ error: O(S), host: O(Type.Object({ grantId: S, expiresAt: N })), artifact: O(Artifact) }),\n ),\n ],\n sockets: (['global', 'workspace'] as const).flatMap((scope) => [\n {\n id: 'computer.state',\n scope,\n service: 'po.hub',\n member: 'computer_use_state',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'Computer use channel payload.',\n input: Type.Object({ state: ComputerStateSchema, targets: Type.Array(Target), busy: O(Type.Literal(true)) }),\n },\n {\n id: 'computer.command',\n scope,\n service: 'po.hub',\n member: 'computer_use_state',\n kind: 'channel',\n direction: 'client-to-server',\n description: 'Computer use browser channel command.',\n input: Type.Object({ action: values(['status', 'targets', 'stop', 'artifacts']) }),\n },\n ]),\n});\nexport default apiContracts;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses, type PoHttpContract } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst O = Type.Optional;\nconst values = <T extends string>(items: T[]) => Type.Union(items.map((item) => Type.Literal(item)));\nconst Json = Type.Unknown({\n description:\n 'Desktop provider JSON value. Targets, observations and action results are supplied by the admitted Desktop provider.',\n});\nconst Target = Type.Record(S, Json);\nconst Error = Type.Object({ code: S, message: S });\nconst Artifact = Type.Object({\n artifactId: S,\n status: values(['ready', 'failed']),\n sizeBytes: O(N),\n downloadUrl: O(S),\n previewUrl: O(S),\n actionCount: O(N),\n completedAt: O(S),\n failure: O(Error),\n});\nexport const ComputerStateSchema = Type.Object({\n sessionId: S,\n revision: N,\n wake: N,\n phase: values(['inactive', 'awaiting_confirmation', 'activating', 'active', 'stopping', 'failed']),\n requestId: O(S),\n target: O(Target),\n durationMs: O(N),\n expiresAt: O(N),\n failure: O(Error),\n artifact: O(Artifact),\n});\nconst Permission = values(['accessibility', 'screen-recording', 'microphone', 'automation', 'full-disk-access']);\nconst PermissionState = values(['granted', 'denied', 'not-determined', 'per-app']);\nexport const DesktopPermissionStatesSchema = Type.Object({\n accessibility: PermissionState,\n 'screen-recording': PermissionState,\n microphone: PermissionState,\n automation: PermissionState,\n 'full-disk-access': PermissionState,\n});\nconst Reference = { snapshotId: Type.String({ minLength: 1 }), elementRef: Type.String({ minLength: 1 }) };\nexport const ComputerActionSchema = Type.Union([\n Type.Object({ kind: values(['press', 'focus']), ...Reference }, { additionalProperties: false }),\n Type.Object({ kind: Type.Literal('set_value'), ...Reference, value: S }, { additionalProperties: false }),\n Type.Object(\n {\n kind: Type.Literal('scroll'),\n ...Reference,\n direction: values(['up', 'down', 'left', 'right']),\n amount: values(['line', 'page']),\n },\n { additionalProperties: false },\n ),\n]);\nconst internal = (\n method: 'GET' | 'POST',\n path: string,\n output: object,\n body?: object,\n status = 200,\n): PoHttpContract => ({\n id: `computer.${path.slice(1).replaceAll('/', '.')}`,\n scope: 'session',\n basePath: 'computer-use',\n path,\n method,\n authentication: 'owner',\n description: `Computer use broker ${path}. Requires the host-issued ${path.startsWith('/agent/') ? 'agent' : 'hub'} bearer token.`,\n availability: 'Internal broker route; ordinary browser credentials are insufficient.',\n parameters: [{ name: 'Authorization', in: 'header', required: true, schema: Type.String({ pattern: '^Bearer .+' }) }],\n ...(body ? { body: { required: true, contentType: 'application/json', schema: body } } : {}),\n responses: jsonApiResponses(output, status),\n});\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: ['Desktop provider target extensions, observations and operation results are runtime-defined JSON.'],\n http: [\n ...(['global', 'workspace', 'session'] as const).flatMap((scope) =>\n (['GET', 'POST'] as const).map((method) => ({\n id: `computer.permissions.${method === 'GET' ? 'read' : 'request'}`,\n scope,\n basePath: 'desktop-permissions',\n path: '/',\n method,\n authentication: 'owner' as const,\n description:\n method === 'GET'\n ? 'Read the Mac-owned permission states. Requires an authorized local Desktop caller or trusted remote caller.'\n : 'Ask macOS for one named permission. Requires an authorized local Desktop caller or remote passkey step-up.',\n availability: 'Requires Po Desktop to be running this server; otherwise returns 404.',\n ...(method === 'POST'\n ? {\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ permission: Permission }),\n },\n }\n : {}),\n responses: {\n ...jsonApiResponses(DesktopPermissionStatesSchema),\n '502': { description: 'Desktop permission request failed.', schema: Type.Object({ error: S }) },\n },\n })),\n ),\n {\n id: 'computer.activation.state',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'GET',\n authentication: 'owner',\n description: 'Read state as the matching pending requester or approved recording reader.',\n responses: jsonApiResponses(ComputerStateSchema),\n },\n {\n id: 'computer.activation.cancel',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'DELETE',\n authentication: 'owner',\n description: 'Cancel only the matching requester pending activation.',\n responses: jsonApiResponses(ComputerStateSchema, 202),\n },\n {\n id: 'computer.activate',\n scope: 'session',\n basePath: 'computer-use',\n path: '/activate',\n method: 'POST',\n authentication: 'owner',\n description:\n 'Request confirmed Desktop access with admitted caller and remote step-up context. The target is one application window or the whole desktop; a remote caller may omit it so the local Mac selects.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({\n target: O(\n Type.Union([Type.Object({ windowId: S, bundleId: S }), Type.Object({ scope: Type.Literal('desktop') })]),\n ),\n durationMs: Type.Integer({ minimum: 1000, maximum: 1800000 }),\n }),\n },\n responses: jsonApiResponses(ComputerStateSchema, 202),\n },\n {\n id: 'computer.artifact',\n scope: 'session',\n basePath: 'computer-use',\n path: '/artifact',\n method: 'GET',\n authentication: 'owner',\n description: 'Read at most 1 MiB of a recording belonging to this session and approved caller.',\n parameters: [\n { name: 'artifactId', in: 'query', required: true, schema: S },\n { name: 'offset', in: 'query', required: true, schema: Type.Integer({ minimum: 0 }) },\n ],\n responses: {\n 206: {\n description: 'Bounded recording bytes.',\n contentType: 'video/mp4',\n schema: Type.String({ format: 'binary' }),\n },\n },\n },\n internal('GET', '/agent/state', ComputerStateSchema),\n internal('GET', '/hub/state', ComputerStateSchema),\n internal('POST', '/agent/observe', Json),\n internal('POST', '/agent/action', Json, ComputerActionSchema),\n internal('POST', '/agent/stop', ComputerStateSchema, undefined, 202),\n internal(\n 'GET',\n '/hub/activation',\n Type.Union([\n Type.Null(),\n Type.Object({\n requestId: S,\n target: Target,\n durationSeconds: N,\n createdAt: N,\n confirmationExpiresAt: N,\n caller: Type.Object({ locality: values(['local', 'remote']), stepUp: S }),\n }),\n ]),\n ),\n internal('GET', '/hub/authorization', Type.Union([Type.Null(), Type.Object({ grantId: S, expiresAt: O(N) })])),\n internal(\n 'GET',\n '/hub/next',\n Type.Union([\n Type.Null(),\n Type.Object({ id: S, operation: values(['observe', 'act']), payload: O(Json), grantId: S, sequence: O(N) }),\n ]),\n ),\n internal('POST', '/hub/complete', ComputerStateSchema, Type.Object({ id: S, error: O(S), result: O(Json) })),\n internal(\n 'POST',\n '/hub/stop',\n ComputerStateSchema,\n Type.Object({ error: O(S), host: O(Type.Object({ grantId: S, expiresAt: N })), artifact: O(Artifact) }),\n ),\n ],\n sockets: (['global', 'workspace'] as const).flatMap((scope) => [\n {\n id: 'computer.state',\n scope,\n service: 'po.hub',\n member: 'computer_use_state',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'Computer use channel payload.',\n input: Type.Object({ state: ComputerStateSchema, targets: Type.Array(Target), busy: O(Type.Literal(true)) }),\n },\n {\n id: 'computer.command',\n scope,\n service: 'po.hub',\n member: 'computer_use_state',\n kind: 'channel',\n direction: 'client-to-server',\n description: 'Computer use browser channel command.',\n input: Type.Object({ action: values(['status', 'targets', 'stop', 'artifacts']) }),\n },\n ]),\n});\nexport default apiContracts;\n"],"mappings":";;;AAGA,MAAM,IAAI,KAAK,OAAO;AACtB,MAAM,IAAI,KAAK,OAAO;AACtB,MAAM,IAAI,KAAK;AACf,MAAM,UAA4B,UAAe,KAAK,MAAM,MAAM,KAAK,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC;AACnG,MAAM,OAAO,KAAK,QAAQ,EACxB,aACE,uHACJ,CAAC;AACD,MAAM,SAAS,KAAK,OAAO,GAAG,IAAI;AAClC,MAAM,QAAQ,KAAK,OAAO;CAAE,MAAM;CAAG,SAAS;AAAE,CAAC;AACjD,MAAM,WAAW,KAAK,OAAO;CAC3B,YAAY;CACZ,QAAQ,OAAO,CAAC,SAAS,QAAQ,CAAC;CAClC,WAAW,EAAE,CAAC;CACd,aAAa,EAAE,CAAC;CAChB,YAAY,EAAE,CAAC;CACf,aAAa,EAAE,CAAC;CAChB,aAAa,EAAE,CAAC;CAChB,SAAS,EAAE,KAAK;AAClB,CAAC;AACD,MAAa,sBAAsB,KAAK,OAAO;CAC7C,WAAW;CACX,UAAU;CACV,MAAM;CACN,OAAO,OAAO;EAAC;EAAY;EAAyB;EAAc;EAAU;EAAY;CAAQ,CAAC;CACjG,WAAW,EAAE,CAAC;CACd,QAAQ,EAAE,MAAM;CAChB,YAAY,EAAE,CAAC;CACf,WAAW,EAAE,CAAC;CACd,SAAS,EAAE,KAAK;CAChB,UAAU,EAAE,QAAQ;AACtB,CAAC;AACD,MAAM,aAAa,OAAO;CAAC;CAAiB;CAAoB;CAAc;CAAc;AAAkB,CAAC;AAC/G,MAAM,kBAAkB,OAAO;CAAC;CAAW;CAAU;CAAkB;AAAS,CAAC;AACjF,MAAa,gCAAgC,KAAK,OAAO;CACvD,eAAe;CACf,oBAAoB;CACpB,YAAY;CACZ,YAAY;CACZ,oBAAoB;AACtB,CAAC;AACD,MAAM,YAAY;CAAE,YAAY,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;CAAG,YAAY,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;AAAE;AACzG,MAAa,uBAAuB,KAAK,MAAM;CAC7C,KAAK,OAAO;EAAE,MAAM,OAAO,CAAC,SAAS,OAAO,CAAC;EAAG,GAAG;CAAU,GAAG,EAAE,sBAAsB,MAAM,CAAC;CAC/F,KAAK,OAAO;EAAE,MAAM,KAAK,QAAQ,WAAW;EAAG,GAAG;EAAW,OAAO;CAAE,GAAG,EAAE,sBAAsB,MAAM,CAAC;CACxG,KAAK,OACH;EACE,MAAM,KAAK,QAAQ,QAAQ;EAC3B,GAAG;EACH,WAAW,OAAO;GAAC;GAAM;GAAQ;GAAQ;EAAO,CAAC;EACjD,QAAQ,OAAO,CAAC,QAAQ,MAAM,CAAC;CACjC,GACA,EAAE,sBAAsB,MAAM,CAChC;AACF,CAAC;AACD,MAAM,YACJ,QACA,MACA,QACA,MACA,SAAS,SACW;CACpB,IAAI,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,KAAK,GAAG;CACjD,OAAO;CACP,UAAU;CACV;CACA;CACA,gBAAgB;CAChB,aAAa,uBAAuB,KAAK,6BAA6B,KAAK,WAAW,SAAS,IAAI,UAAU,MAAM;CACnH,cAAc;CACd,YAAY,CAAC;EAAE,MAAM;EAAiB,IAAI;EAAU,UAAU;EAAM,QAAQ,KAAK,OAAO,EAAE,SAAS,aAAa,CAAC;CAAE,CAAC;CACpH,GAAI,OAAO,EAAE,MAAM;EAAE,UAAU;EAAM,aAAa;EAAoB,QAAQ;CAAK,EAAE,IAAI,CAAC;CAC1F,WAAW,iBAAiB,QAAQ,MAAM;AAC5C;AACA,MAAa,eAAe,kBAAkB;CAC5C,SAAS;CACT,SAAS,CAAC,kGAAkG;CAC5G,MAAM;EACJ,GAAI;GAAC;GAAU;GAAa;EAAS,CAAC,CAAW,SAAS,UACvD,CAAC,OAAO,MAAM,CAAC,CAAW,KAAK,YAAY;GAC1C,IAAI,wBAAwB,WAAW,QAAQ,SAAS;GACxD;GACA,UAAU;GACV,MAAM;GACN;GACA,gBAAgB;GAChB,aACE,WAAW,QACP,gHACA;GACN,cAAc;GACd,GAAI,WAAW,SACX,EACE,MAAM;IACJ,UAAU;IACV,aAAa;IACb,QAAQ,KAAK,OAAO,EAAE,YAAY,WAAW,CAAC;GAChD,EACF,IACA,CAAC;GACL,WAAW;IACT,GAAG,iBAAiB,6BAA6B;IACjD,OAAO;KAAE,aAAa;KAAsC,QAAQ,KAAK,OAAO,EAAE,OAAO,EAAE,CAAC;IAAE;GAChG;EACF,EAAE,CACJ;EACA;GACE,IAAI;GACJ,OAAO;GACP,UAAU;GACV,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,aAAa;GACb,WAAW,iBAAiB,mBAAmB;EACjD;EACA;GACE,IAAI;GACJ,OAAO;GACP,UAAU;GACV,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,aAAa;GACb,WAAW,iBAAiB,qBAAqB,GAAG;EACtD;EACA;GACE,IAAI;GACJ,OAAO;GACP,UAAU;GACV,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,aACE;GACF,MAAM;IACJ,UAAU;IACV,aAAa;IACb,QAAQ,KAAK,OAAO;KAClB,QAAQ,EACN,KAAK,MAAM,CAAC,KAAK,OAAO;MAAE,UAAU;MAAG,UAAU;KAAE,CAAC,GAAG,KAAK,OAAO,EAAE,OAAO,KAAK,QAAQ,SAAS,EAAE,CAAC,CAAC,CAAC,CACzG;KACA,YAAY,KAAK,QAAQ;MAAE,SAAS;MAAM,SAAS;KAAQ,CAAC;IAC9D,CAAC;GACH;GACA,WAAW,iBAAiB,qBAAqB,GAAG;EACtD;EACA;GACE,IAAI;GACJ,OAAO;GACP,UAAU;GACV,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,aAAa;GACb,YAAY,CACV;IAAE,MAAM;IAAc,IAAI;IAAS,UAAU;IAAM,QAAQ;GAAE,GAC7D;IAAE,MAAM;IAAU,IAAI;IAAS,UAAU;IAAM,QAAQ,KAAK,QAAQ,EAAE,SAAS,EAAE,CAAC;GAAE,CACtF;GACA,WAAW,EACT,KAAK;IACH,aAAa;IACb,aAAa;IACb,QAAQ,KAAK,OAAO,EAAE,QAAQ,SAAS,CAAC;GAC1C,EACF;EACF;EACA,SAAS,OAAO,gBAAgB,mBAAmB;EACnD,SAAS,OAAO,cAAc,mBAAmB;EACjD,SAAS,QAAQ,kBAAkB,IAAI;EACvC,SAAS,QAAQ,iBAAiB,MAAM,oBAAoB;EAC5D,SAAS,QAAQ,eAAe,qBAAqB,KAAA,GAAW,GAAG;EACnE,SACE,OACA,mBACA,KAAK,MAAM,CACT,KAAK,KAAK,GACV,KAAK,OAAO;GACV,WAAW;GACX,QAAQ;GACR,iBAAiB;GACjB,WAAW;GACX,uBAAuB;GACvB,QAAQ,KAAK,OAAO;IAAE,UAAU,OAAO,CAAC,SAAS,QAAQ,CAAC;IAAG,QAAQ;GAAE,CAAC;EAC1E,CAAC,CACH,CAAC,CACH;EACA,SAAS,OAAO,sBAAsB,KAAK,MAAM,CAAC,KAAK,KAAK,GAAG,KAAK,OAAO;GAAE,SAAS;GAAG,WAAW,EAAE,CAAC;EAAE,CAAC,CAAC,CAAC,CAAC;EAC7G,SACE,OACA,aACA,KAAK,MAAM,CACT,KAAK,KAAK,GACV,KAAK,OAAO;GAAE,IAAI;GAAG,WAAW,OAAO,CAAC,WAAW,KAAK,CAAC;GAAG,SAAS,EAAE,IAAI;GAAG,SAAS;GAAG,UAAU,EAAE,CAAC;EAAE,CAAC,CAC5G,CAAC,CACH;EACA,SAAS,QAAQ,iBAAiB,qBAAqB,KAAK,OAAO;GAAE,IAAI;GAAG,OAAO,EAAE,CAAC;GAAG,QAAQ,EAAE,IAAI;EAAE,CAAC,CAAC;EAC3G,SACE,QACA,aACA,qBACA,KAAK,OAAO;GAAE,OAAO,EAAE,CAAC;GAAG,MAAM,EAAE,KAAK,OAAO;IAAE,SAAS;IAAG,WAAW;GAAE,CAAC,CAAC;GAAG,UAAU,EAAE,QAAQ;EAAE,CAAC,CACxG;CACF;CACA,SAAU,CAAC,UAAU,WAAW,CAAC,CAAW,SAAS,UAAU,CAC7D;EACE,IAAI;EACJ;EACA,SAAS;EACT,QAAQ;EACR,MAAM;EACN,WAAW;EACX,aAAa;EACb,OAAO,KAAK,OAAO;GAAE,OAAO;GAAqB,SAAS,KAAK,MAAM,MAAM;GAAG,MAAM,EAAE,KAAK,QAAQ,IAAI,CAAC;EAAE,CAAC;CAC7G,GACA;EACE,IAAI;EACJ;EACA,SAAS;EACT,QAAQ;EACR,MAAM;EACN,WAAW;EACX,aAAa;EACb,OAAO,KAAK,OAAO,EAAE,QAAQ,OAAO;GAAC;GAAU;GAAW;GAAQ;EAAW,CAAC,EAAE,CAAC;CACnF,CACF,CAAC;AACH,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createApiClient, defineActivityGroup, defineChannelFile, defineFill, defineNativePlugin, defineSessionStore, nativeApiTransport, sessionApiAddress } from "@agimon-ai/po-core/native";
|
|
2
2
|
import { View } from "react-native-unistyles/components/native/View";
|
|
3
3
|
import { Text } from "react-native-unistyles/components/native/Text";
|
|
4
|
-
import { Button, fontOf } from "@agimon-ai/po-native-components";
|
|
4
|
+
import { Button, CheckIcon, fontOf } from "@agimon-ai/po-native-components";
|
|
5
5
|
import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
6
6
|
import { StyleSheet } from "react-native-unistyles";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -197,17 +197,31 @@ createApiClient(routes, {
|
|
|
197
197
|
});
|
|
198
198
|
//#endregion
|
|
199
199
|
//#region src/extensions/workspaces/sessions/(frontend)/fill/_components/ComputerUsePanel.native.tsx
|
|
200
|
+
function remaining(ms) {
|
|
201
|
+
const seconds = Math.max(0, Math.ceil(ms / 1e3));
|
|
202
|
+
return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, "0")} left`;
|
|
203
|
+
}
|
|
200
204
|
function ComputerUseView({ state, busy = false, error, submitting = false, onActivate, onCancel, onStop }) {
|
|
201
205
|
const pending = state.phase === "awaiting_confirmation" || state.phase === "activating";
|
|
202
206
|
const active = state.phase === "active" || state.phase === "stopping";
|
|
203
207
|
const failure = error ?? state.failure?.message;
|
|
208
|
+
const expiresAt = state.phase === "active" ? state.expiresAt : void 0;
|
|
209
|
+
const [now, setNow] = useState(Date.now);
|
|
210
|
+
useEffect(() => {
|
|
211
|
+
if (expiresAt === void 0) return;
|
|
212
|
+
const timer = setInterval(() => setNow(Date.now()), 1e3);
|
|
213
|
+
return () => clearInterval(timer);
|
|
214
|
+
}, [expiresAt]);
|
|
215
|
+
const left = expiresAt === void 0 ? void 0 : expiresAt - now;
|
|
216
|
+
const total = state.durationMs ?? 3e5;
|
|
217
|
+
const controlled = state.target?.scope === "desktop" ? "your whole desktop" : typeof state.target?.applicationName === "string" ? state.target.applicationName : "the chosen window";
|
|
204
218
|
return /* @__PURE__ */ jsxs(View, {
|
|
205
219
|
style: styles.panel,
|
|
206
220
|
children: [
|
|
207
221
|
/* @__PURE__ */ jsx(Text, {
|
|
208
|
-
style: styles.
|
|
209
|
-
|
|
210
|
-
children:
|
|
222
|
+
style: styles.title,
|
|
223
|
+
accessibilityRole: "header",
|
|
224
|
+
children: "Computer use"
|
|
211
225
|
}),
|
|
212
226
|
busy ? /* @__PURE__ */ jsx(Text, {
|
|
213
227
|
style: styles.detail,
|
|
@@ -218,14 +232,31 @@ function ComputerUseView({ state, busy = false, error, submitting = false, onAct
|
|
|
218
232
|
accessibilityRole: "alert",
|
|
219
233
|
children: failure
|
|
220
234
|
}) : null,
|
|
235
|
+
state.artifact?.status === "ready" ? /* @__PURE__ */ jsxs(View, {
|
|
236
|
+
style: styles.row,
|
|
237
|
+
children: [/* @__PURE__ */ jsx(View, {
|
|
238
|
+
style: styles.check,
|
|
239
|
+
children: /* @__PURE__ */ jsx(CheckIcon, {
|
|
240
|
+
size: 12,
|
|
241
|
+
color: "rail"
|
|
242
|
+
})
|
|
243
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
244
|
+
style: styles.text,
|
|
245
|
+
children: "Recording saved to session artifacts."
|
|
246
|
+
})]
|
|
247
|
+
}) : null,
|
|
248
|
+
state.artifact?.failure ? /* @__PURE__ */ jsx(Text, {
|
|
249
|
+
style: styles.error,
|
|
250
|
+
children: state.artifact.failure.message
|
|
251
|
+
}) : null,
|
|
221
252
|
pending ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
222
253
|
/* @__PURE__ */ jsx(Text, {
|
|
223
254
|
style: styles.text,
|
|
224
|
-
children: "
|
|
255
|
+
children: "Waiting for you on your Mac."
|
|
225
256
|
}),
|
|
226
257
|
/* @__PURE__ */ jsx(Text, {
|
|
227
258
|
style: styles.detail,
|
|
228
|
-
children: "Choose
|
|
259
|
+
children: "Choose the whole desktop or one window, then confirm."
|
|
229
260
|
}),
|
|
230
261
|
/* @__PURE__ */ jsx(Button, {
|
|
231
262
|
variant: "outline",
|
|
@@ -233,22 +264,46 @@ function ComputerUseView({ state, busy = false, error, submitting = false, onAct
|
|
|
233
264
|
onPress: onCancel,
|
|
234
265
|
children: "Cancel activation"
|
|
235
266
|
})
|
|
236
|
-
] }) : active ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
267
|
+
] }) : active ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
268
|
+
/* @__PURE__ */ jsxs(View, {
|
|
269
|
+
style: styles.row,
|
|
270
|
+
accessibilityLiveRegion: "polite",
|
|
271
|
+
children: [/* @__PURE__ */ jsx(View, { style: styles.dot }), /* @__PURE__ */ jsx(Text, {
|
|
272
|
+
style: styles.live,
|
|
273
|
+
children: state.phase === "stopping" ? "Po is handing control back" : `Po is controlling ${controlled}`
|
|
274
|
+
})]
|
|
275
|
+
}),
|
|
276
|
+
left === void 0 ? null : /* @__PURE__ */ jsxs(View, {
|
|
277
|
+
style: styles.row,
|
|
278
|
+
children: [/* @__PURE__ */ jsx(View, {
|
|
279
|
+
style: styles.track,
|
|
280
|
+
accessibilityRole: "progressbar",
|
|
281
|
+
accessibilityLabel: "Time left",
|
|
282
|
+
accessibilityValue: {
|
|
283
|
+
min: 0,
|
|
284
|
+
max: total,
|
|
285
|
+
now: Math.max(0, left)
|
|
286
|
+
},
|
|
287
|
+
children: /* @__PURE__ */ jsx(View, { style: [styles.fill, { width: `${Math.min(100, Math.max(0, left / total * 100))}%` }] })
|
|
288
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
289
|
+
style: styles.detail,
|
|
290
|
+
children: remaining(left)
|
|
291
|
+
})]
|
|
292
|
+
}),
|
|
293
|
+
/* @__PURE__ */ jsx(Button, {
|
|
294
|
+
variant: "outline",
|
|
295
|
+
disabled: submitting || state.phase === "stopping",
|
|
296
|
+
onPress: onStop,
|
|
297
|
+
children: "Stop computer use"
|
|
298
|
+
})
|
|
299
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Text, {
|
|
245
300
|
style: styles.detail,
|
|
246
|
-
children: "
|
|
301
|
+
children: "Po asks before it takes control. Choose the whole desktop or one window on your Mac. You can stop at any time."
|
|
247
302
|
}), /* @__PURE__ */ jsx(Button, {
|
|
248
303
|
variant: "primary",
|
|
249
304
|
disabled: busy || submitting,
|
|
250
305
|
onPress: onActivate,
|
|
251
|
-
children: "Choose
|
|
306
|
+
children: "Choose on Mac"
|
|
252
307
|
})] })
|
|
253
308
|
]
|
|
254
309
|
});
|
|
@@ -339,6 +394,59 @@ const styles = StyleSheet.create((theme) => ({
|
|
|
339
394
|
gap: theme.spacing(3),
|
|
340
395
|
uni__dependencies: [0]
|
|
341
396
|
},
|
|
397
|
+
title: {
|
|
398
|
+
fontFamily: fontOf(theme.fontFamily.sans),
|
|
399
|
+
fontSize: theme.fontSize.base,
|
|
400
|
+
fontWeight: "600",
|
|
401
|
+
color: theme.colors.hi,
|
|
402
|
+
paddingBottom: theme.spacing(2),
|
|
403
|
+
borderBottomWidth: 1,
|
|
404
|
+
borderBottomColor: theme.colors["border-soft"],
|
|
405
|
+
uni__dependencies: [0]
|
|
406
|
+
},
|
|
407
|
+
row: {
|
|
408
|
+
flexDirection: "row",
|
|
409
|
+
alignItems: "center",
|
|
410
|
+
gap: theme.spacing(2),
|
|
411
|
+
uni__dependencies: [0]
|
|
412
|
+
},
|
|
413
|
+
dot: {
|
|
414
|
+
width: 8,
|
|
415
|
+
height: 8,
|
|
416
|
+
borderRadius: 4,
|
|
417
|
+
backgroundColor: theme.colors.green,
|
|
418
|
+
uni__dependencies: [0]
|
|
419
|
+
},
|
|
420
|
+
live: {
|
|
421
|
+
fontFamily: fontOf(theme.fontFamily.sans),
|
|
422
|
+
fontSize: theme.fontSize.base,
|
|
423
|
+
lineHeight: theme.lineHeightRelaxed.base,
|
|
424
|
+
color: theme.colors.green,
|
|
425
|
+
uni__dependencies: [0]
|
|
426
|
+
},
|
|
427
|
+
track: {
|
|
428
|
+
flex: 1,
|
|
429
|
+
height: 6,
|
|
430
|
+
borderRadius: 3,
|
|
431
|
+
overflow: "hidden",
|
|
432
|
+
backgroundColor: theme.colors["border-soft"],
|
|
433
|
+
uni__dependencies: [0]
|
|
434
|
+
},
|
|
435
|
+
fill: {
|
|
436
|
+
height: "100%",
|
|
437
|
+
borderRadius: 3,
|
|
438
|
+
backgroundColor: theme.colors.green,
|
|
439
|
+
uni__dependencies: [0]
|
|
440
|
+
},
|
|
441
|
+
check: {
|
|
442
|
+
width: 20,
|
|
443
|
+
height: 20,
|
|
444
|
+
borderRadius: 10,
|
|
445
|
+
alignItems: "center",
|
|
446
|
+
justifyContent: "center",
|
|
447
|
+
backgroundColor: theme.colors.green,
|
|
448
|
+
uni__dependencies: [0]
|
|
449
|
+
},
|
|
342
450
|
text: {
|
|
343
451
|
fontFamily: fontOf(theme.fontFamily.sans),
|
|
344
452
|
fontSize: theme.fontSize.base,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.mjs","names":["computerUse","WebPluginSlotProps","Button","fontOf","PoNativeTheme","useCallback","useEffect","useRef","useState","useSyncExternalStore","StyleSheet","computerUse","api","COMPUTER_USE_DEFAULT_DURATION_MS","computerUseChannelType","ComputerUseSessionView","updateComputerUseState","ComputerUseView","state","busy","error","submitting","onActivate","onCancel","onStop","pending","phase","active","failure","message","styles","panel","detail","replaceAll","text","target","applicationName","windowTitle","SessionPanel","sessionId","sendSessionFrame","subscribe","listener","subscription","store","unsubscribe","session","select","setError","setSubmitting","requests","AbortController","controller","current","timer","ReturnType","setTimeout","type","payload","action","poll","result","activationState","signal","ok","aborted","data","abort","clearTimeout","submit","undefined","client","activate","body","durationMs","cancelActivation","status","ComputerUsePanel","props","create","theme","gap","spacing","uni__dependencies","fontFamily","sans","fontSize","base","lineHeight","lineHeightRelaxed","color","colors","sm","dim","red","computerUse","api","activityGroupComputerUse","channelComputerUse","fillComputerUse"],"sources":["../../src/types/computerUseApi.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/computer-use.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/computerUseStore.native.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/computer-use.native.ts","../../src/types/apiRoutes.ts","../../generated/client.native.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/ComputerUsePanel.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/ComputerUse.activity.computer-use.native.tsx","../../generated/native.ts"],"sourcesContent":["import type { PoApiCaller } from '@agimon-ai/po-core/packageApi';\n\nexport const API_BASE_PATH = 'computer-use';\nexport const computerUseChannelType = 'computer_use_state';\nexport const COMPUTER_USE_MODE_ID = 'computer-use';\nexport const COMPUTER_USE_STATUS_KEY = 'po-computer-use';\nexport const COMPUTER_USE_MODE_STATUS_KEY = 'po-computer-use-mode';\nexport const COMPUTER_USE_MAX_DURATION_MS = 1_800 * 1_000;\nexport const COMPUTER_USE_DEFAULT_DURATION_MS = 300 * 1_000;\nexport const COMPUTER_USE_CONFIRMATION_WINDOW_MS = 2 * 60 * 1_000;\n\n/**\n * Every path this API answers on, below its mount.\n *\n * The typed route table in `./apiRoutes` is built from this, the dispatcher\n * reads that table, and the hub channel addresses the broker with these same\n * strings, so a route cannot move on one side alone.\n */\nexport const COMPUTER_USE_ROUTES = {\n activate: '/activate',\n artifact: '/artifact',\n agentState: '/agent/state',\n agentObserve: '/agent/observe',\n agentAction: '/agent/action',\n agentStop: '/agent/stop',\n hubState: '/hub/state',\n hubActivation: '/hub/activation',\n hubAuthorization: '/hub/authorization',\n hubNext: '/hub/next',\n hubComplete: '/hub/complete',\n hubStop: '/hub/stop',\n} as const;\n\nexport const COMPUTER_USE_WAKE_LIMIT = 1_000_000;\n\nexport interface ComputerUseArtifactView {\n readonly artifactId: string;\n readonly status: 'ready' | 'failed';\n readonly sizeBytes?: number;\n readonly downloadUrl?: string;\n readonly previewUrl?: string;\n readonly actionCount?: number;\n readonly completedAt?: string;\n readonly failure?: { readonly code: string; readonly message: string };\n}\n\nexport interface ComputerUseSessionView {\n readonly sessionId: string;\n readonly revision: number;\n readonly wake: number;\n readonly phase: 'inactive' | 'awaiting_confirmation' | 'activating' | 'active' | 'stopping' | 'failed';\n readonly requestId?: string;\n readonly target?: Record<string, unknown>;\n readonly durationMs?: number;\n readonly expiresAt?: number;\n readonly failure?: { readonly code: string; readonly message: string };\n readonly artifact?: ComputerUseArtifactView;\n}\n\nexport interface ComputerUseActivationRequest {\n readonly requestId: string;\n readonly target?: Record<string, unknown>;\n readonly durationSeconds: number;\n readonly createdAt: number;\n readonly confirmationExpiresAt: number;\n readonly caller: PoApiCaller;\n}\n\nexport interface ComputerUseBrokerRequest {\n readonly id: string;\n readonly operation: 'observe' | 'act';\n readonly payload?: unknown;\n readonly grantId: string;\n readonly sequence?: number;\n}\n\nexport interface ComputerUseChannelPayload {\n readonly state: ComputerUseSessionView;\n readonly targets: readonly Record<string, unknown>[];\n readonly busy?: true;\n}\n\nexport type ComputerUseBrowserCommand = { readonly action: 'status' | 'targets' | 'stop' | 'artifacts' };\n","import { defineActivityGroup } from '@agimon-ai/po-core/native';\n\nimport { COMPUTER_USE_STATUS_KEY } from '../../../../../types/computerUseApi';\n\n/** Remote clients request control from the Desktop host through their session Activity. */\nexport default defineActivityGroup({\n name: 'computer-use',\n keys: 'c e',\n order: 70,\n statusKey: COMPUTER_USE_STATUS_KEY,\n hideWhenEmpty: true,\n marksBackgroundWork: false,\n});\n","import { defineSessionStore } from '@agimon-ai/po-core/native';\n\nimport { computerUseChannelType } from '../../../../../types/computerUseApi';\nimport type { ComputerUseChannelPayload, ComputerUseSessionView } from '../../../../../types/computerUseApi';\n\nexport interface ComputerUseSession extends ComputerUseChannelPayload {}\n\nconst initialState: ComputerUseSession = {\n state: { sessionId: '', revision: 0, wake: 0, phase: 'inactive' },\n targets: [],\n};\n\nexport const computerUse = defineSessionStore<ComputerUseSession>(initialState);\n\n/** Revision zero must hydrate the empty selector once; equal status polls then retain identity. */\nexport function updateComputerUseState(sessionId: string, state: ComputerUseSessionView) {\n computerUse.update(sessionId, (current) =>\n current.state.sessionId === '' || state.revision > current.state.revision ? { ...current, state } : current,\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport const computerUseChannel = computerUse.channel<ComputerUseChannelPayload>({\n channel: computerUseChannelType,\n parse(input) {\n if (!isRecord(input) || !isRecord(input.state) || !Array.isArray(input.targets)) return null;\n if (typeof input.state.phase !== 'string' || typeof input.state.revision !== 'number') return null;\n return input as unknown as ComputerUseChannelPayload;\n },\n reduce: (_current, payload) => payload,\n});\n","import { defineChannelFile } from '@agimon-ai/po-core/native';\n\nimport { computerUseChannel } from '../_lib/computerUseStore.native';\n\nexport default defineChannelFile(computerUseChannel);\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport {\n COMPUTER_USE_ROUTES,\n type ComputerUseActivationRequest,\n type ComputerUseBrokerRequest,\n type ComputerUseSessionView,\n} from './computerUseApi';\nimport { DESKTOP_PERMISSIONS_PATH, type DesktopPermissionStates } from './desktopPermissions';\n\n/**\n * This package's routes, as data.\n *\n * No scope and no base path: the build reads both off\n * `src/extensions/workspaces/sessions/(backend)/api/computer-use/`, so the\n * mount is stated once, by the folder that creates it.\n *\n * The paths come from `COMPUTER_USE_ROUTES` rather than being written out\n * again. That table already addressed the broker from the hub channel and from\n * the broker's own dispatcher, and a second copy here is exactly the\n * disagreement this file exists to prevent. The dispatcher now reads this\n * table, so the page, the broker and the hub all resolve one set of strings.\n *\n * Activation, status, cancellation and recording reads are reachable from a browser. The `/agent/` and `/hub/` routes\n * each demand a host-issued bearer token and answer 404 without one; they are\n * declared here because they are this API's surface, not because a page calls\n * them.\n */\nconst routes = {\n artifact: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.artifact,\n query: ['artifactId', 'offset'],\n raw: true,\n },\n activationState: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.activate,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n cancelActivation: {\n method: 'DELETE',\n path: COMPUTER_USE_ROUTES.activate,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n activate: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.activate,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n agentState: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.agentState,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n /** Answers whatever the admitted Desktop provider returned, which is runtime-defined JSON. */\n agentObserve: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.agentObserve,\n response: undefined as unknown as ApiResponseOf<unknown>,\n },\n agentAction: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.agentAction,\n response: undefined as unknown as ApiResponseOf<unknown>,\n },\n agentStop: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.agentStop,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n hubState: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.hubState,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n /** Null until a reader has confirmed one; reading it moves the session to `activating`. */\n hubActivation: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.hubActivation,\n response: undefined as unknown as ApiResponseOf<ComputerUseActivationRequest | null>,\n },\n hubAuthorization: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.hubAuthorization,\n response: undefined as unknown as ApiResponseOf<{ readonly grantId: string; readonly expiresAt?: number } | null>,\n },\n hubNext: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.hubNext,\n response: undefined as unknown as ApiResponseOf<ComputerUseBrokerRequest | null>,\n },\n hubComplete: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.hubComplete,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n hubStop: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.hubStop,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n /** Desktop's macOS permission states, served by the hub's `desktop-permissions` mount. */\n desktopPermissions: {\n method: 'GET',\n path: DESKTOP_PERMISSIONS_PATH,\n response: undefined as unknown as ApiResponseOf<DesktopPermissionStates>,\n },\n /** Asks macOS for the body's permission on the Mac running Desktop; answers the states after. */\n requestDesktopPermission: {\n method: 'POST',\n path: DESKTOP_PERMISSIONS_PATH,\n response: undefined as unknown as ApiResponseOf<DesktopPermissionStates>,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { createApiClient, nativeApiTransport, sessionApiAddress } from '@agimon-ai/po-core/native';\n\nimport routes from '../src/types/apiRoutes';\n\n/** Scopes the tree mounts 'computer-use' at for the computer-use mount. */\nexport const computerUseScopes = ['session'] as const;\n\nexport const computerUse = createApiClient(routes, {\n scopes: computerUseScopes,\n basePath: 'computer-use',\n transport: nativeApiTransport,\n sessionAddress: sessionApiAddress,\n});\n\n/** Scopes the tree mounts 'desktop-permissions' at for the desktop-permissions mount. */\nexport const desktopPermissionsScopes = ['global', 'workspace', 'session'] as const;\n\nexport const desktopPermissions = createApiClient(routes, {\n scopes: desktopPermissionsScopes,\n basePath: 'desktop-permissions',\n transport: nativeApiTransport,\n sessionAddress: sessionApiAddress,\n});\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { Button, fontOf } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react';\nimport { Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { computerUse as api } from '../../../../../../../generated/client.native';\nimport { COMPUTER_USE_DEFAULT_DURATION_MS, computerUseChannelType } from '../../../../../../types/computerUseApi';\nimport type { ComputerUseSessionView } from '../../../../../../types/computerUseApi';\nimport { computerUse, updateComputerUseState } from '../../_lib/computerUseStore.native';\n\nexport function ComputerUseView({\n state,\n busy = false,\n error,\n submitting = false,\n onActivate,\n onCancel,\n onStop,\n}: {\n state: ComputerUseSessionView;\n busy?: boolean;\n error?: string;\n submitting?: boolean;\n onActivate: () => void;\n onCancel: () => void;\n onStop: () => void;\n}) {\n const pending = state.phase === 'awaiting_confirmation' || state.phase === 'activating';\n const active = state.phase === 'active' || state.phase === 'stopping';\n const failure = error ?? state.failure?.message;\n return (\n <View style={styles.panel}>\n <Text style={styles.detail} accessibilityLiveRegion=\"polite\">\n {state.phase.replaceAll('_', ' ')}\n </Text>\n {busy ? <Text style={styles.detail}>Computer use is busy in another session.</Text> : null}\n {failure ? (\n <Text style={styles.error} accessibilityRole=\"alert\">\n {failure}\n </Text>\n ) : null}\n {pending ? (\n <>\n <Text style={styles.text}>Desktop activation is pending.</Text>\n <Text style={styles.detail}>Choose and confirm an application window on your Mac.</Text>\n <Button variant=\"outline\" disabled={submitting} onPress={onCancel}>\n Cancel activation\n </Button>\n </>\n ) : active ? (\n <>\n {state.target ? (\n <Text style={styles.text}>\n {`${typeof state.target.applicationName === 'string' ? state.target.applicationName : 'Application'}: ${typeof state.target.windowTitle === 'string' ? state.target.windowTitle : 'Window'}`}\n </Text>\n ) : null}\n <Button variant=\"outline\" disabled={submitting || state.phase === 'stopping'} onPress={onStop}>\n Stop computer use\n </Button>\n </>\n ) : (\n <>\n <Text style={styles.detail}>\n Request 5 minutes of control. Your Mac asks you to choose and confirm a window.\n </Text>\n <Button variant=\"primary\" disabled={busy || submitting} onPress={onActivate}>\n Choose window on Mac\n </Button>\n </>\n )}\n </View>\n );\n}\n\nfunction SessionPanel({ sessionId, sendSessionFrame }: WebPluginSlotProps & { sessionId: string }) {\n const subscribe = useCallback((listener: () => void) => {\n const subscription = computerUse.store.subscribe(listener);\n return () => subscription.unsubscribe();\n }, []);\n // Native plugins may not import @tanstack/react-store; it is not a native host module.\n const session = useSyncExternalStore(subscribe, () => computerUse.select(computerUse.store.state, sessionId));\n const [error, setError] = useState<string>();\n const [submitting, setSubmitting] = useState(false);\n const requests = useRef<AbortController | null>(null);\n\n useEffect(() => {\n const controller = new AbortController();\n requests.current = controller;\n let timer: ReturnType<typeof setTimeout> | undefined;\n sendSessionFrame(sessionId, { type: computerUseChannelType, payload: { action: 'status' } });\n const poll = async () => {\n try {\n const result = await api.session(sessionId).activationState({ signal: controller.signal });\n if (result.ok && !controller.signal.aborted) updateComputerUseState(sessionId, result.data);\n } catch {\n if (!controller.signal.aborted) setError('The session is unreachable.');\n }\n if (!controller.signal.aborted) timer = setTimeout(() => void poll(), 2000);\n };\n void poll();\n return () => {\n controller.abort();\n clearTimeout(timer);\n };\n }, [sessionId, sendSessionFrame]);\n\n const submit = async (action: 'activate' | 'cancel') => {\n const signal = requests.current?.signal;\n if (!signal || signal.aborted || submitting) return;\n setError(undefined);\n setSubmitting(true);\n try {\n const client = api.session(sessionId);\n const result =\n action === 'activate'\n ? await client.activate({ body: { durationMs: COMPUTER_USE_DEFAULT_DURATION_MS }, signal })\n : await client.cancelActivation({ signal });\n if (signal.aborted) return;\n if (result.ok) updateComputerUseState(sessionId, result.data);\n else\n setError(\n result.status === 0 ? 'The session is unreachable.' : result.error || 'The activation request failed.',\n );\n } catch {\n if (!signal.aborted) setError('The activation request is unavailable.');\n } finally {\n if (!signal.aborted) setSubmitting(false);\n }\n };\n\n return (\n <ComputerUseView\n state={session.state}\n busy={session.busy}\n error={error}\n submitting={submitting}\n onActivate={() => void submit('activate')}\n onCancel={() => void submit('cancel')}\n onStop={() => {\n setError(undefined);\n try {\n sendSessionFrame(sessionId, { type: computerUseChannelType, payload: { action: 'stop' } });\n } catch {\n setError('The stop request is unavailable.');\n }\n }}\n />\n );\n}\n\nexport function ComputerUsePanel(props: WebPluginSlotProps) {\n return props.sessionId === null ? (\n <Text style={styles.detail}>Select a session.</Text>\n ) : (\n <SessionPanel key={props.sessionId} {...props} sessionId={props.sessionId} />\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n panel: { gap: theme.spacing(3) },\n text: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeightRelaxed.base,\n color: theme.colors.text,\n },\n detail: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeightRelaxed.sm,\n color: theme.colors.dim,\n },\n error: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeightRelaxed.base,\n color: theme.colors.red,\n },\n}));\n","import { defineFill } from '@agimon-ai/po-core/native';\n\nimport { ComputerUsePanel } from './_components/ComputerUsePanel.native';\n\nexport default defineFill({ id: 'computer-use', slot: 'activity.computer-use', component: ComputerUsePanel });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineNativePlugin, type WebPluginContributions } from '@agimon-ai/po-core/native';\n\nimport activityGroupComputerUse from '../src/extensions/workspaces/sessions/(frontend)/activity-group/computer-use.native';\nimport channelComputerUse from '../src/extensions/workspaces/sessions/(frontend)/channel/computer-use.native';\nimport fillComputerUse from '../src/extensions/workspaces/sessions/(frontend)/fill/ComputerUse.activity.computer-use.native';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const nativePlugin = defineNativePlugin({\n id: 'computer-use',\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'computer-use' }, activityGroupComputerUse)]; },\n get channels(): WebPluginContributions['channels'] { return [via({ channel: 'computer_use' }, channelComputerUse)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'activity.computer-use', id: 'computer-use' }, fillComputerUse)]; },\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"native.mjs","names":["computerUse","WebPluginSlotProps","Button","CheckIcon","fontOf","PoNativeTheme","useCallback","useEffect","useRef","useState","useSyncExternalStore","StyleSheet","computerUse","api","COMPUTER_USE_DEFAULT_DURATION_MS","computerUseChannelType","ComputerUseSessionView","updateComputerUseState","remaining","ms","seconds","Math","max","ceil","floor","String","padStart","ComputerUseView","state","busy","error","submitting","onActivate","onCancel","onStop","pending","phase","active","failure","message","expiresAt","undefined","now","setNow","Date","timer","setInterval","clearInterval","left","total","durationMs","controlled","target","scope","applicationName","styles","panel","title","detail","artifact","status","row","check","text","dot","live","track","min","fill","width","SessionPanel","sessionId","sendSessionFrame","subscribe","listener","subscription","store","unsubscribe","session","select","setError","setSubmitting","requests","AbortController","controller","current","ReturnType","setTimeout","type","payload","action","poll","result","activationState","signal","ok","aborted","data","abort","clearTimeout","submit","client","activate","body","cancelActivation","ComputerUsePanel","props","create","theme","gap","spacing","uni__dependencies","fontFamily","sans","fontSize","base","fontWeight","color","colors","hi","paddingBottom","borderBottomWidth","borderBottomColor","flexDirection","alignItems","height","borderRadius","backgroundColor","green","lineHeight","lineHeightRelaxed","flex","overflow","justifyContent","sm","dim","red","computerUse","api","activityGroupComputerUse","channelComputerUse","fillComputerUse"],"sources":["../../src/types/computerUseApi.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/computer-use.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/computerUseStore.native.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/computer-use.native.ts","../../src/types/apiRoutes.ts","../../generated/client.native.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/ComputerUsePanel.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/ComputerUse.activity.computer-use.native.tsx","../../generated/native.ts"],"sourcesContent":["import type { PoApiCaller } from '@agimon-ai/po-core/packageApi';\n\nexport const API_BASE_PATH = 'computer-use';\nexport const computerUseChannelType = 'computer_use_state';\nexport const COMPUTER_USE_MODE_ID = 'computer-use';\nexport const COMPUTER_USE_STATUS_KEY = 'po-computer-use';\nexport const COMPUTER_USE_MODE_STATUS_KEY = 'po-computer-use-mode';\nexport const COMPUTER_USE_MAX_DURATION_MS = 1_800 * 1_000;\nexport const COMPUTER_USE_DEFAULT_DURATION_MS = 300 * 1_000;\nexport const COMPUTER_USE_CONFIRMATION_WINDOW_MS = 2 * 60 * 1_000;\n\n/**\n * Every path this API answers on, below its mount.\n *\n * The typed route table in `./apiRoutes` is built from this, the dispatcher\n * reads that table, and the hub channel addresses the broker with these same\n * strings, so a route cannot move on one side alone.\n */\nexport const COMPUTER_USE_ROUTES = {\n activate: '/activate',\n artifact: '/artifact',\n agentState: '/agent/state',\n agentObserve: '/agent/observe',\n agentAction: '/agent/action',\n agentStop: '/agent/stop',\n hubState: '/hub/state',\n hubActivation: '/hub/activation',\n hubAuthorization: '/hub/authorization',\n hubNext: '/hub/next',\n hubComplete: '/hub/complete',\n hubStop: '/hub/stop',\n} as const;\n\nexport const COMPUTER_USE_WAKE_LIMIT = 1_000_000;\n\nexport interface ComputerUseArtifactView {\n readonly artifactId: string;\n readonly status: 'ready' | 'failed';\n readonly sizeBytes?: number;\n readonly downloadUrl?: string;\n readonly previewUrl?: string;\n readonly actionCount?: number;\n readonly completedAt?: string;\n readonly failure?: { readonly code: string; readonly message: string };\n}\n\nexport interface ComputerUseSessionView {\n readonly sessionId: string;\n readonly revision: number;\n readonly wake: number;\n readonly phase: 'inactive' | 'awaiting_confirmation' | 'activating' | 'active' | 'stopping' | 'failed';\n readonly requestId?: string;\n readonly target?: Record<string, unknown>;\n readonly durationMs?: number;\n readonly expiresAt?: number;\n readonly failure?: { readonly code: string; readonly message: string };\n readonly artifact?: ComputerUseArtifactView;\n}\n\nexport interface ComputerUseActivationRequest {\n readonly requestId: string;\n readonly target?: Record<string, unknown>;\n readonly durationSeconds: number;\n readonly createdAt: number;\n readonly confirmationExpiresAt: number;\n readonly caller: PoApiCaller;\n}\n\nexport interface ComputerUseBrokerRequest {\n readonly id: string;\n readonly operation: 'observe' | 'act';\n readonly payload?: unknown;\n readonly grantId: string;\n readonly sequence?: number;\n}\n\nexport interface ComputerUseChannelPayload {\n readonly state: ComputerUseSessionView;\n readonly targets: readonly Record<string, unknown>[];\n readonly busy?: true;\n}\n\nexport type ComputerUseBrowserCommand = { readonly action: 'status' | 'targets' | 'stop' | 'artifacts' };\n","import { defineActivityGroup } from '@agimon-ai/po-core/native';\n\nimport { COMPUTER_USE_STATUS_KEY } from '../../../../../types/computerUseApi';\n\n/** Remote clients request control from the Desktop host through their session Activity. */\nexport default defineActivityGroup({\n name: 'computer-use',\n keys: 'c e',\n order: 70,\n statusKey: COMPUTER_USE_STATUS_KEY,\n hideWhenEmpty: true,\n marksBackgroundWork: false,\n});\n","import { defineSessionStore } from '@agimon-ai/po-core/native';\n\nimport { computerUseChannelType } from '../../../../../types/computerUseApi';\nimport type { ComputerUseChannelPayload, ComputerUseSessionView } from '../../../../../types/computerUseApi';\n\nexport interface ComputerUseSession extends ComputerUseChannelPayload {}\n\nconst initialState: ComputerUseSession = {\n state: { sessionId: '', revision: 0, wake: 0, phase: 'inactive' },\n targets: [],\n};\n\nexport const computerUse = defineSessionStore<ComputerUseSession>(initialState);\n\n/** Revision zero must hydrate the empty selector once; equal status polls then retain identity. */\nexport function updateComputerUseState(sessionId: string, state: ComputerUseSessionView) {\n computerUse.update(sessionId, (current) =>\n current.state.sessionId === '' || state.revision > current.state.revision ? { ...current, state } : current,\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport const computerUseChannel = computerUse.channel<ComputerUseChannelPayload>({\n channel: computerUseChannelType,\n parse(input) {\n if (!isRecord(input) || !isRecord(input.state) || !Array.isArray(input.targets)) return null;\n if (typeof input.state.phase !== 'string' || typeof input.state.revision !== 'number') return null;\n return input as unknown as ComputerUseChannelPayload;\n },\n reduce: (_current, payload) => payload,\n});\n","import { defineChannelFile } from '@agimon-ai/po-core/native';\n\nimport { computerUseChannel } from '../_lib/computerUseStore.native';\n\nexport default defineChannelFile(computerUseChannel);\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport {\n COMPUTER_USE_ROUTES,\n type ComputerUseActivationRequest,\n type ComputerUseBrokerRequest,\n type ComputerUseSessionView,\n} from './computerUseApi';\nimport { DESKTOP_PERMISSIONS_PATH, type DesktopPermissionStates } from './desktopPermissions';\n\n/**\n * This package's routes, as data.\n *\n * No scope and no base path: the build reads both off\n * `src/extensions/workspaces/sessions/(backend)/api/computer-use/`, so the\n * mount is stated once, by the folder that creates it.\n *\n * The paths come from `COMPUTER_USE_ROUTES` rather than being written out\n * again. That table already addressed the broker from the hub channel and from\n * the broker's own dispatcher, and a second copy here is exactly the\n * disagreement this file exists to prevent. The dispatcher now reads this\n * table, so the page, the broker and the hub all resolve one set of strings.\n *\n * Activation, status, cancellation and recording reads are reachable from a browser. The `/agent/` and `/hub/` routes\n * each demand a host-issued bearer token and answer 404 without one; they are\n * declared here because they are this API's surface, not because a page calls\n * them.\n */\nconst routes = {\n artifact: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.artifact,\n query: ['artifactId', 'offset'],\n raw: true,\n },\n activationState: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.activate,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n cancelActivation: {\n method: 'DELETE',\n path: COMPUTER_USE_ROUTES.activate,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n activate: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.activate,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n agentState: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.agentState,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n /** Answers whatever the admitted Desktop provider returned, which is runtime-defined JSON. */\n agentObserve: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.agentObserve,\n response: undefined as unknown as ApiResponseOf<unknown>,\n },\n agentAction: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.agentAction,\n response: undefined as unknown as ApiResponseOf<unknown>,\n },\n agentStop: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.agentStop,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n hubState: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.hubState,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n /** Null until a reader has confirmed one; reading it moves the session to `activating`. */\n hubActivation: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.hubActivation,\n response: undefined as unknown as ApiResponseOf<ComputerUseActivationRequest | null>,\n },\n hubAuthorization: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.hubAuthorization,\n response: undefined as unknown as ApiResponseOf<{ readonly grantId: string; readonly expiresAt?: number } | null>,\n },\n hubNext: {\n method: 'GET',\n path: COMPUTER_USE_ROUTES.hubNext,\n response: undefined as unknown as ApiResponseOf<ComputerUseBrokerRequest | null>,\n },\n hubComplete: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.hubComplete,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n hubStop: {\n method: 'POST',\n path: COMPUTER_USE_ROUTES.hubStop,\n response: undefined as unknown as ApiResponseOf<ComputerUseSessionView>,\n },\n /** Desktop's macOS permission states, served by the hub's `desktop-permissions` mount. */\n desktopPermissions: {\n method: 'GET',\n path: DESKTOP_PERMISSIONS_PATH,\n response: undefined as unknown as ApiResponseOf<DesktopPermissionStates>,\n },\n /** Asks macOS for the body's permission on the Mac running Desktop; answers the states after. */\n requestDesktopPermission: {\n method: 'POST',\n path: DESKTOP_PERMISSIONS_PATH,\n response: undefined as unknown as ApiResponseOf<DesktopPermissionStates>,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { createApiClient, nativeApiTransport, sessionApiAddress } from '@agimon-ai/po-core/native';\n\nimport routes from '../src/types/apiRoutes';\n\n/** Scopes the tree mounts 'computer-use' at for the computer-use mount. */\nexport const computerUseScopes = ['session'] as const;\n\nexport const computerUse = createApiClient(routes, {\n scopes: computerUseScopes,\n basePath: 'computer-use',\n transport: nativeApiTransport,\n sessionAddress: sessionApiAddress,\n});\n\n/** Scopes the tree mounts 'desktop-permissions' at for the desktop-permissions mount. */\nexport const desktopPermissionsScopes = ['global', 'workspace', 'session'] as const;\n\nexport const desktopPermissions = createApiClient(routes, {\n scopes: desktopPermissionsScopes,\n basePath: 'desktop-permissions',\n transport: nativeApiTransport,\n sessionAddress: sessionApiAddress,\n});\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { Button, CheckIcon, fontOf } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react';\nimport { Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { computerUse as api } from '../../../../../../../generated/client.native';\nimport { COMPUTER_USE_DEFAULT_DURATION_MS, computerUseChannelType } from '../../../../../../types/computerUseApi';\nimport type { ComputerUseSessionView } from '../../../../../../types/computerUseApi';\nimport { computerUse, updateComputerUseState } from '../../_lib/computerUseStore.native';\n\nfunction remaining(ms: number): string {\n const seconds = Math.max(0, Math.ceil(ms / 1000));\n return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, '0')} left`;\n}\nexport function ComputerUseView({\n state,\n busy = false,\n error,\n submitting = false,\n onActivate,\n onCancel,\n onStop,\n}: {\n state: ComputerUseSessionView;\n busy?: boolean;\n error?: string;\n submitting?: boolean;\n onActivate: () => void;\n onCancel: () => void;\n onStop: () => void;\n}) {\n const pending = state.phase === 'awaiting_confirmation' || state.phase === 'activating';\n const active = state.phase === 'active' || state.phase === 'stopping';\n const failure = error ?? state.failure?.message;\n const expiresAt = state.phase === 'active' ? state.expiresAt : undefined;\n const [now, setNow] = useState(Date.now);\n useEffect(() => {\n if (expiresAt === undefined) return;\n const timer = setInterval(() => setNow(Date.now()), 1000);\n return () => clearInterval(timer);\n }, [expiresAt]);\n const left = expiresAt === undefined ? undefined : expiresAt - now;\n const total = state.durationMs ?? COMPUTER_USE_DEFAULT_DURATION_MS;\n const controlled =\n state.target?.scope === 'desktop'\n ? 'your whole desktop'\n : typeof state.target?.applicationName === 'string'\n ? state.target.applicationName\n : 'the chosen window';\n return (\n <View style={styles.panel}>\n <Text style={styles.title} accessibilityRole=\"header\">\n Computer use\n </Text>\n {busy ? <Text style={styles.detail}>Computer use is busy in another session.</Text> : null}\n {failure ? (\n <Text style={styles.error} accessibilityRole=\"alert\">\n {failure}\n </Text>\n ) : null}\n {state.artifact?.status === 'ready' ? (\n <View style={styles.row}>\n <View style={styles.check}>\n <CheckIcon size={12} color=\"rail\" />\n </View>\n <Text style={styles.text}>Recording saved to session artifacts.</Text>\n </View>\n ) : null}\n {state.artifact?.failure ? <Text style={styles.error}>{state.artifact.failure.message}</Text> : null}\n {pending ? (\n <>\n <Text style={styles.text}>Waiting for you on your Mac.</Text>\n <Text style={styles.detail}>Choose the whole desktop or one window, then confirm.</Text>\n <Button variant=\"outline\" disabled={submitting} onPress={onCancel}>\n Cancel activation\n </Button>\n </>\n ) : active ? (\n <>\n <View style={styles.row} accessibilityLiveRegion=\"polite\">\n <View style={styles.dot} />\n <Text style={styles.live}>\n {state.phase === 'stopping' ? 'Po is handing control back' : `Po is controlling ${controlled}`}\n </Text>\n </View>\n {left === undefined ? null : (\n <View style={styles.row}>\n <View\n style={styles.track}\n accessibilityRole=\"progressbar\"\n accessibilityLabel=\"Time left\"\n accessibilityValue={{ min: 0, max: total, now: Math.max(0, left) }}\n >\n <View style={[styles.fill, { width: `${Math.min(100, Math.max(0, (left / total) * 100))}%` }]} />\n </View>\n <Text style={styles.detail}>{remaining(left)}</Text>\n </View>\n )}\n <Button variant=\"outline\" disabled={submitting || state.phase === 'stopping'} onPress={onStop}>\n Stop computer use\n </Button>\n </>\n ) : (\n <>\n <Text style={styles.detail}>\n Po asks before it takes control. Choose the whole desktop or one window on your Mac. You can stop at any\n time.\n </Text>\n <Button variant=\"primary\" disabled={busy || submitting} onPress={onActivate}>\n Choose on Mac\n </Button>\n </>\n )}\n </View>\n );\n}\n\nfunction SessionPanel({ sessionId, sendSessionFrame }: WebPluginSlotProps & { sessionId: string }) {\n const subscribe = useCallback((listener: () => void) => {\n const subscription = computerUse.store.subscribe(listener);\n return () => subscription.unsubscribe();\n }, []);\n // Native plugins may not import @tanstack/react-store; it is not a native host module.\n const session = useSyncExternalStore(subscribe, () => computerUse.select(computerUse.store.state, sessionId));\n const [error, setError] = useState<string>();\n const [submitting, setSubmitting] = useState(false);\n const requests = useRef<AbortController | null>(null);\n\n useEffect(() => {\n const controller = new AbortController();\n requests.current = controller;\n let timer: ReturnType<typeof setTimeout> | undefined;\n sendSessionFrame(sessionId, { type: computerUseChannelType, payload: { action: 'status' } });\n const poll = async () => {\n try {\n const result = await api.session(sessionId).activationState({ signal: controller.signal });\n if (result.ok && !controller.signal.aborted) updateComputerUseState(sessionId, result.data);\n } catch {\n if (!controller.signal.aborted) setError('The session is unreachable.');\n }\n if (!controller.signal.aborted) timer = setTimeout(() => void poll(), 2000);\n };\n void poll();\n return () => {\n controller.abort();\n clearTimeout(timer);\n };\n }, [sessionId, sendSessionFrame]);\n\n const submit = async (action: 'activate' | 'cancel') => {\n const signal = requests.current?.signal;\n if (!signal || signal.aborted || submitting) return;\n setError(undefined);\n setSubmitting(true);\n try {\n const client = api.session(sessionId);\n const result =\n action === 'activate'\n ? await client.activate({ body: { durationMs: COMPUTER_USE_DEFAULT_DURATION_MS }, signal })\n : await client.cancelActivation({ signal });\n if (signal.aborted) return;\n if (result.ok) updateComputerUseState(sessionId, result.data);\n else\n setError(\n result.status === 0 ? 'The session is unreachable.' : result.error || 'The activation request failed.',\n );\n } catch {\n if (!signal.aborted) setError('The activation request is unavailable.');\n } finally {\n if (!signal.aborted) setSubmitting(false);\n }\n };\n\n return (\n <ComputerUseView\n state={session.state}\n busy={session.busy}\n error={error}\n submitting={submitting}\n onActivate={() => void submit('activate')}\n onCancel={() => void submit('cancel')}\n onStop={() => {\n setError(undefined);\n try {\n sendSessionFrame(sessionId, { type: computerUseChannelType, payload: { action: 'stop' } });\n } catch {\n setError('The stop request is unavailable.');\n }\n }}\n />\n );\n}\n\nexport function ComputerUsePanel(props: WebPluginSlotProps) {\n return props.sessionId === null ? (\n <Text style={styles.detail}>Select a session.</Text>\n ) : (\n <SessionPanel key={props.sessionId} {...props} sessionId={props.sessionId} />\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n panel: { gap: theme.spacing(3) },\n title: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n fontWeight: '600',\n color: theme.colors.hi,\n paddingBottom: theme.spacing(2),\n borderBottomWidth: 1,\n borderBottomColor: theme.colors['border-soft'],\n },\n row: { flexDirection: 'row', alignItems: 'center', gap: theme.spacing(2) },\n dot: { width: 8, height: 8, borderRadius: 4, backgroundColor: theme.colors.green },\n live: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeightRelaxed.base,\n color: theme.colors.green,\n },\n track: { flex: 1, height: 6, borderRadius: 3, overflow: 'hidden', backgroundColor: theme.colors['border-soft'] },\n fill: { height: '100%', borderRadius: 3, backgroundColor: theme.colors.green },\n check: {\n width: 20,\n height: 20,\n borderRadius: 10,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: theme.colors.green,\n },\n text: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeightRelaxed.base,\n color: theme.colors.text,\n },\n detail: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeightRelaxed.sm,\n color: theme.colors.dim,\n },\n error: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeightRelaxed.base,\n color: theme.colors.red,\n },\n}));\n","import { defineFill } from '@agimon-ai/po-core/native';\n\nimport { ComputerUsePanel } from './_components/ComputerUsePanel.native';\n\nexport default defineFill({ id: 'computer-use', slot: 'activity.computer-use', component: ComputerUsePanel });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineNativePlugin, type WebPluginContributions } from '@agimon-ai/po-core/native';\n\nimport activityGroupComputerUse from '../src/extensions/workspaces/sessions/(frontend)/activity-group/computer-use.native';\nimport channelComputerUse from '../src/extensions/workspaces/sessions/(frontend)/channel/computer-use.native';\nimport fillComputerUse from '../src/extensions/workspaces/sessions/(frontend)/fill/ComputerUse.activity.computer-use.native';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const nativePlugin = defineNativePlugin({\n id: 'computer-use',\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'computer-use' }, activityGroupComputerUse)]; },\n get channels(): WebPluginContributions['channels'] { return [via({ channel: 'computer_use' }, channelComputerUse)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'activity.computer-use', id: 'computer-use' }, fillComputerUse)]; },\n },\n});\n"],"mappings":"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"}
|
|
@@ -86,7 +86,7 @@ function modeState(state, enabled = false) {
|
|
|
86
86
|
const NOT_ACTIVE$1 = "Computer use is not active for this session.";
|
|
87
87
|
const DECLARATIONS = `declare const computer: {
|
|
88
88
|
/**
|
|
89
|
-
* Read-only. Observes the authorized window. A screenshot is shown to the model unless includeScreenshot is false.
|
|
89
|
+
* Read-only. Observes the authorized window or whole desktop. A screenshot is shown to the model unless includeScreenshot is false.
|
|
90
90
|
* save: true also keeps the screenshot in session artifacts and returns its path as screenshotArtifact.
|
|
91
91
|
*/
|
|
92
92
|
state(options?: { includeScreenshot?: boolean; save?: boolean }): Promise<Record<string, unknown>>;
|
|
@@ -128,7 +128,7 @@ function failureMessage(details) {
|
|
|
128
128
|
function createComputerNamespace(deps) {
|
|
129
129
|
return {
|
|
130
130
|
name: "computer",
|
|
131
|
-
summary: "Observe and act on the
|
|
131
|
+
summary: "Observe and act on the application window, or the whole desktop, the person authorized through Po Desktop: state, act, run an allowlisted script, stop. Exists only while that grant is active.",
|
|
132
132
|
declarations: DECLARATIONS,
|
|
133
133
|
bind(run) {
|
|
134
134
|
const guard = () => {
|
|
@@ -588,7 +588,8 @@ var ComputerUseRequestBroker = class ComputerUseRequestBroker {
|
|
|
588
588
|
const input = await body(request);
|
|
589
589
|
const target = record$1(input.target);
|
|
590
590
|
const durationMs = input.durationMs;
|
|
591
|
-
|
|
591
|
+
const desktopTarget = target?.scope === "desktop" && Object.keys(target).length === 1;
|
|
592
|
+
if (target === void 0 && (input.target !== void 0 || caller.locality !== "remote") || target !== void 0 && !desktopTarget && (typeof target.windowId !== "string" || typeof target.bundleId !== "string")) return jsonError("A Desktop window or the whole desktop is required, or a remote request must leave selection to the Mac.", 400);
|
|
592
593
|
if (typeof durationMs !== "number" || !Number.isInteger(durationMs) || durationMs < 1e3 || durationMs > 18e5) return jsonError("The requested duration is invalid.", 400);
|
|
593
594
|
try {
|
|
594
595
|
this.desktop.claim(request.headers);
|
|
@@ -979,7 +980,7 @@ function createComputerUseServer(host, apiContext) {
|
|
|
979
980
|
const applyState = (next) => {
|
|
980
981
|
state = next;
|
|
981
982
|
saveRecording(next?.artifact);
|
|
982
|
-
host.context.client.setStatus(COMPUTER_USE_STATUS_KEY, next === void 0 || next.phase === "inactive" && !modeSelected()
|
|
983
|
+
host.context.client.setStatus(COMPUTER_USE_STATUS_KEY, next === void 0 || next.phase === "inactive" && !modeSelected() ? void 0 : `computer use: ${next.phase}`);
|
|
983
984
|
publishMode();
|
|
984
985
|
for (const listener of restrictionListeners) listener();
|
|
985
986
|
};
|
|
@@ -1045,11 +1046,11 @@ function createComputerUseServer(host, apiContext) {
|
|
|
1045
1046
|
...mode,
|
|
1046
1047
|
condition: "blocked",
|
|
1047
1048
|
detail: "Enable computer use in global Desktop settings.",
|
|
1048
|
-
actions: mode.actions.map((action) =>
|
|
1049
|
+
actions: mode.actions.map((action) => action.id === "deactivate" ? action : {
|
|
1049
1050
|
...action,
|
|
1050
1051
|
enabled: false,
|
|
1051
1052
|
disabledReason: "Enable computer use in global Desktop settings."
|
|
1052
|
-
})
|
|
1053
|
+
})
|
|
1053
1054
|
} : mode;
|
|
1054
1055
|
},
|
|
1055
1056
|
async handleAction(_runtime, actionId, _argumentsValue, execution) {
|
|
@@ -1228,7 +1229,7 @@ function createComputerUseServer(host, apiContext) {
|
|
|
1228
1229
|
},
|
|
1229
1230
|
name: "computer_state",
|
|
1230
1231
|
label: "Computer State",
|
|
1231
|
-
description: "Observe the authorized application window and return semantic accessibility state. saveScreenshot:true also keeps the screenshot in session artifacts and returns its path.",
|
|
1232
|
+
description: "Observe the authorized application window or whole desktop and return semantic accessibility state. saveScreenshot:true also keeps the screenshot in session artifacts and returns its path.",
|
|
1232
1233
|
parameters: {
|
|
1233
1234
|
type: "object",
|
|
1234
1235
|
properties: {
|
|
@@ -1250,7 +1251,7 @@ function createComputerUseServer(host, apiContext) {
|
|
|
1250
1251
|
},
|
|
1251
1252
|
name: "computer_action",
|
|
1252
1253
|
label: "Computer Action",
|
|
1253
|
-
description: "Perform one constrained semantic action in the authorized application window.",
|
|
1254
|
+
description: "Perform one constrained semantic action in the authorized application window or desktop.",
|
|
1254
1255
|
parameters: {
|
|
1255
1256
|
type: "object",
|
|
1256
1257
|
properties: {
|
|
@@ -1760,7 +1761,7 @@ var session_shutdown_server_default = (0, _agimon_ai_po_core_extensionFile.defin
|
|
|
1760
1761
|
//#region src/extensions/workspaces/sessions/(backend)/resource/codemode-how-to-computer-use.server.ts
|
|
1761
1762
|
var codemode_how_to_computer_use_server_default = (0, _agimon_ai_po_core_extensionFile.defineResource)({
|
|
1762
1763
|
name: "codemode-how-to-computer-use",
|
|
1763
|
-
description: "Observe and act on the
|
|
1764
|
+
description: "Observe and act on the application window, or the whole desktop, the person authorized through Po Desktop, using the computer namespace in exec. Use when Computer Use is on and the task needs the screen state or a semantic press, focus, set_value or scroll.",
|
|
1764
1765
|
kind: "skill",
|
|
1765
1766
|
pinned: true,
|
|
1766
1767
|
when: {
|