@agimon-ai/doompi-computer-use 0.0.1-alpha.32 → 0.0.1-alpha.34
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/{computerUseMode-DTXNRobA.mjs → computerUseMode-C1r5mG7K.mjs} +2 -2
- package/dist/{computerUseMode-DTXNRobA.mjs.map → computerUseMode-C1r5mG7K.mjs.map} +1 -1
- package/dist/{computerUseMode-CHpbP7yo.cjs → computerUseMode-KnoOWve4.cjs} +2 -2
- package/dist/{computerUseMode-CHpbP7yo.cjs.map → computerUseMode-KnoOWve4.cjs.map} +1 -1
- package/dist/{dependencies-Dub2ybTN.cjs → dependencies-BQOsqM8Q.cjs} +3 -3
- package/dist/{dependencies-Dub2ybTN.cjs.map → dependencies-BQOsqM8Q.cjs.map} +1 -1
- package/dist/{dependencies-Y1TS7gGv.mjs → dependencies-ChuvtRxU.mjs} +3 -3
- package/dist/{dependencies-Y1TS7gGv.mjs.map → dependencies-ChuvtRxU.mjs.map} +1 -1
- package/dist/{extensionService-BJXeNc4R.mjs → extensionService-BSqhP2uB.mjs} +3 -3
- package/dist/extensionService-BSqhP2uB.mjs.map +1 -0
- package/dist/{extensionService-CZS-zDP0.cjs → extensionService-CIDyPyzP.cjs} +3 -3
- package/dist/extensionService-CIDyPyzP.cjs.map +1 -0
- package/dist/extensions/pi.cjs +7 -7
- package/dist/extensions/pi.cjs.map +1 -1
- package/dist/extensions/pi.d.mts +1 -1
- package/dist/extensions/pi.mjs +7 -7
- package/dist/extensions/pi.mjs.map +1 -1
- package/dist/extensions/server.cjs +2 -2
- package/dist/extensions/server.mjs +2 -2
- package/dist/{index-0S6V4EU9.d.mts → index-DoKasntC.d.mts} +4 -4
- package/dist/{index-0S6V4EU9.d.mts.map → index-DoKasntC.d.mts.map} +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -2
- package/package.json +8 -8
- package/dist/extensionService-BJXeNc4R.mjs.map +0 -1
- package/dist/extensionService-CZS-zDP0.cjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as ComputerScriptExecutionError, s as COMPUTER_USE_TOOL_NAMES } from "./extensionService-
|
|
1
|
+
import { n as ComputerScriptExecutionError, s as COMPUTER_USE_TOOL_NAMES } from "./extensionService-BSqhP2uB.mjs";
|
|
2
2
|
//#region src/types/computerUseApi.ts
|
|
3
3
|
const API_BASE_PATH = "computer-use";
|
|
4
4
|
const computerUseChannelType = "computer_use_state";
|
|
@@ -130,4 +130,4 @@ function computerUseRestriction(active) {
|
|
|
130
130
|
//#endregion
|
|
131
131
|
export { computerScriptOutput as a, COMPUTER_USE_MAX_DURATION_MS as c, COMPUTER_USE_ROUTES as d, COMPUTER_USE_STATUS_KEY as f, computerScriptFailure as i, COMPUTER_USE_MODE_ID as l, computerUseChannelType as m, modeState as n, API_BASE_PATH as o, COMPUTER_USE_WAKE_LIMIT as p, computerObservationOutput as r, COMPUTER_USE_CONFIRMATION_WINDOW_MS as s, computerUseRestriction as t, COMPUTER_USE_MODE_STATUS_KEY as u };
|
|
132
132
|
|
|
133
|
-
//# sourceMappingURL=computerUseMode-
|
|
133
|
+
//# sourceMappingURL=computerUseMode-C1r5mG7K.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computerUseMode-
|
|
1
|
+
{"version":3,"file":"computerUseMode-C1r5mG7K.mjs","names":[],"sources":["../src/types/computerUseApi.ts","../src/services/computerToolOutput/index.ts","../src/models/computerUseMode.ts"],"sourcesContent":["import type { DoomApiCaller } from '@agimon-ai/doompi-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 = 'doom-computer-use';\nexport const COMPUTER_USE_MODE_STATUS_KEY = 'doom-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 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 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: DoomApiCaller;\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 type { DoomHeadlessToolResult } from '@agimon-ai/doompi-core/headless';\n\nimport type { ComputerScriptExecutionResult } from '../../types/computerScript';\nimport type { ComputerUseObservation } from '../../types/computerUse';\nimport { ComputerScriptExecutionError } from '../computerScriptRunner';\n\nconst MAX_TEXT_BYTES = 256 * 1024;\nconst MAX_IMAGE_DATA_LENGTH = 8 * 1024 * 1024;\n\nfunction content(value: unknown, observation: ComputerUseObservation): DoomHeadlessToolResult['content'] {\n const text = JSON.stringify(value);\n if (Buffer.byteLength(text) > MAX_TEXT_BYTES) throw new Error('Computer-use text response exceeds the size limit.');\n const screenshot = observation.screenshot;\n if (screenshot && (screenshot.mimeType !== 'image/png' || screenshot.data.length > MAX_IMAGE_DATA_LENGTH)) {\n throw new Error('Computer-use screenshot exceeds the image limit.');\n }\n return [\n { type: 'text', text },\n ...(screenshot ? [{ type: 'image' as const, mimeType: screenshot.mimeType, data: screenshot.data }] : []),\n ];\n}\n\nexport function computerObservationOutput(observation: ComputerUseObservation) {\n return { content: content({ ...observation, screenshot: undefined }, observation), details: observation };\n}\n\nexport function computerScriptOutput(result: ComputerScriptExecutionResult) {\n try {\n return {\n content: content(\n { ...result, observation: { ...result.observation, screenshot: undefined } },\n result.observation,\n ),\n details: result,\n };\n } catch (error) {\n if (result.metrics === undefined) throw error;\n // Formatting happens after the actions complete. Preserve that progress so a caller does not replay them.\n throw new ComputerScriptExecutionError(\n error instanceof Error ? error.message : String(error),\n result.metrics.actions,\n false,\n );\n }\n}\n\nexport function computerScriptFailure(error: unknown) {\n const details = {\n error: (error instanceof Error ? error.message : String(error)).slice(0, 1024),\n ...(error instanceof ComputerScriptExecutionError\n ? {\n completedActions: error.completedActions,\n outcomeUncertain: error.outcomeUncertain,\n }\n : {}),\n };\n return { content: [{ type: 'text' as const, text: JSON.stringify(details) }], details, isError: true };\n}\n","import type { DoomToolRestriction } from '@agimon-ai/doompi-core/toolSurface';\nimport type { MinorModeState } from '@agimon-ai/doompi-minor-mode';\n\nimport { COMPUTER_USE_TOOL_NAMES } from '../constants/computerUse';\nimport type { ComputerUseSessionView } from '../types/computerUseApi';\nexport function modeState(state?: ComputerUseSessionView, enabled = false): MinorModeState {\n const phase = state?.phase ?? 'inactive';\n const running = phase !== 'inactive' && phase !== 'failed';\n const modeEnabled = enabled || running;\n const activation = modeEnabled\n ? phase === 'stopping'\n ? 'deactivating'\n : phase === 'awaiting_confirmation' || phase === 'activating'\n ? 'activating'\n : 'active'\n : 'inactive';\n return {\n activation,\n condition:\n phase === 'awaiting_confirmation'\n ? 'blocked'\n : phase === 'failed'\n ? 'failed'\n : phase === 'activating' || phase === 'stopping'\n ? 'queued'\n : 'ready',\n ...(modeEnabled && phase === 'inactive' ? { detail: 'configure computer use in Activity' } : {}),\n ...(phase === 'awaiting_confirmation' ? { detail: 'awaiting confirmation in Activity' } : {}),\n actions: [\n {\n id: 'activate',\n enabled: !modeEnabled,\n ...(!modeEnabled ? {} : { disabledReason: 'Computer use is already enabled.' }),\n },\n {\n id: 'deactivate',\n enabled: modeEnabled,\n ...(modeEnabled ? {} : { disabledReason: 'Computer use is not enabled.' }),\n },\n { id: 'doctor', enabled: true },\n ],\n };\n}\n\n/**\n * Hides the computer-use tools while the mode is off.\n *\n * The arbiter starts from every registered tool, so an active mode only has to\n * return the list untouched: nothing has to add the tools back.\n */\nexport function computerUseRestriction(active: boolean): DoomToolRestriction {\n const owned = new Set<string>(COMPUTER_USE_TOOL_NAMES);\n return (incoming) => (active ? incoming : incoming.filter((name) => !owned.has(name)));\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_extensionService = require("./extensionService-
|
|
1
|
+
const require_extensionService = require("./extensionService-CIDyPyzP.cjs");
|
|
2
2
|
//#region src/types/computerUseApi.ts
|
|
3
3
|
const API_BASE_PATH = "computer-use";
|
|
4
4
|
const computerUseChannelType = "computer_use_state";
|
|
@@ -213,4 +213,4 @@ Object.defineProperty(exports, "modeState", {
|
|
|
213
213
|
}
|
|
214
214
|
});
|
|
215
215
|
|
|
216
|
-
//# sourceMappingURL=computerUseMode-
|
|
216
|
+
//# sourceMappingURL=computerUseMode-KnoOWve4.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computerUseMode-
|
|
1
|
+
{"version":3,"file":"computerUseMode-KnoOWve4.cjs","names":["ComputerScriptExecutionError","COMPUTER_USE_TOOL_NAMES"],"sources":["../src/types/computerUseApi.ts","../src/services/computerToolOutput/index.ts","../src/models/computerUseMode.ts"],"sourcesContent":["import type { DoomApiCaller } from '@agimon-ai/doompi-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 = 'doom-computer-use';\nexport const COMPUTER_USE_MODE_STATUS_KEY = 'doom-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 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 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: DoomApiCaller;\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 type { DoomHeadlessToolResult } from '@agimon-ai/doompi-core/headless';\n\nimport type { ComputerScriptExecutionResult } from '../../types/computerScript';\nimport type { ComputerUseObservation } from '../../types/computerUse';\nimport { ComputerScriptExecutionError } from '../computerScriptRunner';\n\nconst MAX_TEXT_BYTES = 256 * 1024;\nconst MAX_IMAGE_DATA_LENGTH = 8 * 1024 * 1024;\n\nfunction content(value: unknown, observation: ComputerUseObservation): DoomHeadlessToolResult['content'] {\n const text = JSON.stringify(value);\n if (Buffer.byteLength(text) > MAX_TEXT_BYTES) throw new Error('Computer-use text response exceeds the size limit.');\n const screenshot = observation.screenshot;\n if (screenshot && (screenshot.mimeType !== 'image/png' || screenshot.data.length > MAX_IMAGE_DATA_LENGTH)) {\n throw new Error('Computer-use screenshot exceeds the image limit.');\n }\n return [\n { type: 'text', text },\n ...(screenshot ? [{ type: 'image' as const, mimeType: screenshot.mimeType, data: screenshot.data }] : []),\n ];\n}\n\nexport function computerObservationOutput(observation: ComputerUseObservation) {\n return { content: content({ ...observation, screenshot: undefined }, observation), details: observation };\n}\n\nexport function computerScriptOutput(result: ComputerScriptExecutionResult) {\n try {\n return {\n content: content(\n { ...result, observation: { ...result.observation, screenshot: undefined } },\n result.observation,\n ),\n details: result,\n };\n } catch (error) {\n if (result.metrics === undefined) throw error;\n // Formatting happens after the actions complete. Preserve that progress so a caller does not replay them.\n throw new ComputerScriptExecutionError(\n error instanceof Error ? error.message : String(error),\n result.metrics.actions,\n false,\n );\n }\n}\n\nexport function computerScriptFailure(error: unknown) {\n const details = {\n error: (error instanceof Error ? error.message : String(error)).slice(0, 1024),\n ...(error instanceof ComputerScriptExecutionError\n ? {\n completedActions: error.completedActions,\n outcomeUncertain: error.outcomeUncertain,\n }\n : {}),\n };\n return { content: [{ type: 'text' as const, text: JSON.stringify(details) }], details, isError: true };\n}\n","import type { DoomToolRestriction } from '@agimon-ai/doompi-core/toolSurface';\nimport type { MinorModeState } from '@agimon-ai/doompi-minor-mode';\n\nimport { COMPUTER_USE_TOOL_NAMES } from '../constants/computerUse';\nimport type { ComputerUseSessionView } from '../types/computerUseApi';\nexport function modeState(state?: ComputerUseSessionView, enabled = false): MinorModeState {\n const phase = state?.phase ?? 'inactive';\n const running = phase !== 'inactive' && phase !== 'failed';\n const modeEnabled = enabled || running;\n const activation = modeEnabled\n ? phase === 'stopping'\n ? 'deactivating'\n : phase === 'awaiting_confirmation' || phase === 'activating'\n ? 'activating'\n : 'active'\n : 'inactive';\n return {\n activation,\n condition:\n phase === 'awaiting_confirmation'\n ? 'blocked'\n : phase === 'failed'\n ? 'failed'\n : phase === 'activating' || phase === 'stopping'\n ? 'queued'\n : 'ready',\n ...(modeEnabled && phase === 'inactive' ? { detail: 'configure computer use in Activity' } : {}),\n ...(phase === 'awaiting_confirmation' ? { detail: 'awaiting confirmation in Activity' } : {}),\n actions: [\n {\n id: 'activate',\n enabled: !modeEnabled,\n ...(!modeEnabled ? {} : { disabledReason: 'Computer use is already enabled.' }),\n },\n {\n id: 'deactivate',\n enabled: modeEnabled,\n ...(modeEnabled ? {} : { disabledReason: 'Computer use is not enabled.' }),\n },\n { id: 'doctor', enabled: true },\n ],\n };\n}\n\n/**\n * Hides the computer-use tools while the mode is off.\n *\n * The arbiter starts from every registered tool, so an active mode only has to\n * return the list untouched: nothing has to add the tools back.\n */\nexport function computerUseRestriction(active: boolean): DoomToolRestriction {\n const owned = new Set<string>(COMPUTER_USE_TOOL_NAMES);\n return (incoming) => (active ? incoming : incoming.filter((name) => !owned.has(name)));\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_extensionService = require("./extensionService-
|
|
1
|
+
const require_extensionService = require("./extensionService-CIDyPyzP.cjs");
|
|
2
2
|
let node_path = require("node:path");
|
|
3
3
|
node_path = require_extensionService.__toESM(node_path, 1);
|
|
4
4
|
let _agimon_ai_doompi_config = require("@agimon-ai/doompi-config");
|
|
@@ -15,7 +15,7 @@ function createComputerUseDependencies(overrides = {}) {
|
|
|
15
15
|
const allowedScriptPaths = (process.env["DOOMPI_COMPUTER_USE_SCRIPT_PATHS"] ?? "").split(node_path.default.delimiter).filter((entry) => entry.length > 0);
|
|
16
16
|
return {
|
|
17
17
|
service: overrides.service ?? new require_extensionService.DefaultComputerUseExtensionService(client),
|
|
18
|
-
enabled: overrides.enabled ?? (() => (0, _agimon_ai_doompi_config.loadDoomConfig)(process.env.PI_PROJECT_ROOT ?? process.cwd()).computerUse?.enabled === true),
|
|
18
|
+
enabled: overrides.enabled ?? ((cwd) => (0, _agimon_ai_doompi_config.loadDoomConfig)(cwd ?? process.env.PI_PROJECT_ROOT ?? process.cwd()).computerUse?.enabled === true),
|
|
19
19
|
...client === void 0 ? {} : { client },
|
|
20
20
|
...overrides.scriptRunner !== void 0 ? { scriptRunner: overrides.scriptRunner } : client === void 0 ? {} : { scriptRunner: new require_extensionService.ComputerScriptRunner({
|
|
21
21
|
client,
|
|
@@ -43,4 +43,4 @@ Object.defineProperty(exports, "createComputerUseSessionClient", {
|
|
|
43
43
|
}
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
//# sourceMappingURL=dependencies-
|
|
46
|
+
//# sourceMappingURL=dependencies-BQOsqM8Q.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependencies-
|
|
1
|
+
{"version":3,"file":"dependencies-BQOsqM8Q.cjs","names":["path","DefaultComputerUseExtensionService","loadDoomConfig","ComputerScriptRunner"],"sources":["../src/services/sessionApiClient/index.ts","../src/services/dependencies/index.ts"],"sourcesContent":["import type { ComputerUseSessionClient } from '../../types/computerUse';\n\nexport type { ComputerUseSessionClient } from '../../types/computerUse';\n\n/** Uses the injected host-owned service. Absence never triggers transport or credential discovery. */\nexport function createComputerUseSessionClient(host?: ComputerUseSessionClient): ComputerUseSessionClient | undefined {\n return host;\n}\n","import path from 'node:path';\n\nimport { loadDoomConfig } from '@agimon-ai/doompi-config';\n\nimport type { ComputerUseExtensionDependencies } from '../../types/extension';\nimport { ComputerScriptRunner } from '../computerScriptRunner';\nimport { DefaultComputerUseExtensionService } from '../extensionService';\nimport { createComputerUseSessionClient } from '../sessionApiClient';\n\nexport const COMPUTER_USE_SCRIPT_PATHS_ENV = 'DOOMPI_COMPUTER_USE_SCRIPT_PATHS';\nexport function createComputerUseDependencies(\n overrides: Partial<ComputerUseExtensionDependencies> = {},\n): ComputerUseExtensionDependencies {\n const client = overrides.client ?? createComputerUseSessionClient();\n const allowedScriptPaths = (process.env[COMPUTER_USE_SCRIPT_PATHS_ENV] ?? '')\n .split(path.delimiter)\n .filter((entry) => entry.length > 0);\n return {\n service: overrides.service ?? new DefaultComputerUseExtensionService(client),\n enabled:\n overrides.enabled ??\n ((cwd) => loadDoomConfig(cwd ?? process.env.PI_PROJECT_ROOT ?? process.cwd()).computerUse?.enabled === true),\n ...(client === undefined ? {} : { client }),\n ...(overrides.scriptRunner !== undefined\n ? { scriptRunner: overrides.scriptRunner }\n : client === undefined\n ? {}\n : { scriptRunner: new ComputerScriptRunner({ client, allowedScriptPaths }) }),\n };\n}\n"],"mappings":";;;;;;AAKA,SAAgB,+BAA+B,MAAuE;CACpH,OAAO;AACT;;;ACEA,MAAa,gCAAgC;AAC7C,SAAgB,8BACd,YAAuD,CAAC,GACtB;CAClC,MAAM,SAAS,UAAU,UAAU,+BAA+B;CAClE,MAAM,sBAAsB,QAAQ,IAAA,uCAAsC,GAAA,CACvE,MAAMA,UAAAA,QAAK,SAAS,CAAC,CACrB,QAAQ,UAAU,MAAM,SAAS,CAAC;CACrC,OAAO;EACL,SAAS,UAAU,WAAW,IAAIC,yBAAAA,mCAAmC,MAAM;EAC3E,SACE,UAAU,aACR,SAAA,GAAQC,yBAAAA,eAAAA,CAAe,OAAO,QAAQ,IAAI,mBAAmB,QAAQ,IAAI,CAAC,CAAC,CAAC,aAAa,YAAY;EACzG,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EACzC,GAAI,UAAU,iBAAiB,KAAA,IAC3B,EAAE,cAAc,UAAU,aAAa,IACvC,WAAW,KAAA,IACT,CAAC,IACD,EAAE,cAAc,IAAIC,yBAAAA,qBAAqB;GAAE;GAAQ;EAAmB,CAAC,EAAE;CACjF;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as ComputerScriptRunner, t as DefaultComputerUseExtensionService } from "./extensionService-
|
|
1
|
+
import { r as ComputerScriptRunner, t as DefaultComputerUseExtensionService } from "./extensionService-BSqhP2uB.mjs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { loadDoomConfig } from "@agimon-ai/doompi-config";
|
|
4
4
|
//#region src/services/sessionApiClient/index.ts
|
|
@@ -14,7 +14,7 @@ function createComputerUseDependencies(overrides = {}) {
|
|
|
14
14
|
const allowedScriptPaths = (process.env["DOOMPI_COMPUTER_USE_SCRIPT_PATHS"] ?? "").split(path.delimiter).filter((entry) => entry.length > 0);
|
|
15
15
|
return {
|
|
16
16
|
service: overrides.service ?? new DefaultComputerUseExtensionService(client),
|
|
17
|
-
enabled: overrides.enabled ?? (() => loadDoomConfig(process.env.PI_PROJECT_ROOT ?? process.cwd()).computerUse?.enabled === true),
|
|
17
|
+
enabled: overrides.enabled ?? ((cwd) => loadDoomConfig(cwd ?? process.env.PI_PROJECT_ROOT ?? process.cwd()).computerUse?.enabled === true),
|
|
18
18
|
...client === void 0 ? {} : { client },
|
|
19
19
|
...overrides.scriptRunner !== void 0 ? { scriptRunner: overrides.scriptRunner } : client === void 0 ? {} : { scriptRunner: new ComputerScriptRunner({
|
|
20
20
|
client,
|
|
@@ -25,4 +25,4 @@ function createComputerUseDependencies(overrides = {}) {
|
|
|
25
25
|
//#endregion
|
|
26
26
|
export { createComputerUseDependencies as n, createComputerUseSessionClient as r, COMPUTER_USE_SCRIPT_PATHS_ENV as t };
|
|
27
27
|
|
|
28
|
-
//# sourceMappingURL=dependencies-
|
|
28
|
+
//# sourceMappingURL=dependencies-ChuvtRxU.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependencies-
|
|
1
|
+
{"version":3,"file":"dependencies-ChuvtRxU.mjs","names":[],"sources":["../src/services/sessionApiClient/index.ts","../src/services/dependencies/index.ts"],"sourcesContent":["import type { ComputerUseSessionClient } from '../../types/computerUse';\n\nexport type { ComputerUseSessionClient } from '../../types/computerUse';\n\n/** Uses the injected host-owned service. Absence never triggers transport or credential discovery. */\nexport function createComputerUseSessionClient(host?: ComputerUseSessionClient): ComputerUseSessionClient | undefined {\n return host;\n}\n","import path from 'node:path';\n\nimport { loadDoomConfig } from '@agimon-ai/doompi-config';\n\nimport type { ComputerUseExtensionDependencies } from '../../types/extension';\nimport { ComputerScriptRunner } from '../computerScriptRunner';\nimport { DefaultComputerUseExtensionService } from '../extensionService';\nimport { createComputerUseSessionClient } from '../sessionApiClient';\n\nexport const COMPUTER_USE_SCRIPT_PATHS_ENV = 'DOOMPI_COMPUTER_USE_SCRIPT_PATHS';\nexport function createComputerUseDependencies(\n overrides: Partial<ComputerUseExtensionDependencies> = {},\n): ComputerUseExtensionDependencies {\n const client = overrides.client ?? createComputerUseSessionClient();\n const allowedScriptPaths = (process.env[COMPUTER_USE_SCRIPT_PATHS_ENV] ?? '')\n .split(path.delimiter)\n .filter((entry) => entry.length > 0);\n return {\n service: overrides.service ?? new DefaultComputerUseExtensionService(client),\n enabled:\n overrides.enabled ??\n ((cwd) => loadDoomConfig(cwd ?? process.env.PI_PROJECT_ROOT ?? process.cwd()).computerUse?.enabled === true),\n ...(client === undefined ? {} : { client }),\n ...(overrides.scriptRunner !== undefined\n ? { scriptRunner: overrides.scriptRunner }\n : client === undefined\n ? {}\n : { scriptRunner: new ComputerScriptRunner({ client, allowedScriptPaths }) }),\n };\n}\n"],"mappings":";;;;;AAKA,SAAgB,+BAA+B,MAAuE;CACpH,OAAO;AACT;;;ACEA,MAAa,gCAAgC;AAC7C,SAAgB,8BACd,YAAuD,CAAC,GACtB;CAClC,MAAM,SAAS,UAAU,UAAU,+BAA+B;CAClE,MAAM,sBAAsB,QAAQ,IAAA,uCAAsC,GAAA,CACvE,MAAM,KAAK,SAAS,CAAC,CACrB,QAAQ,UAAU,MAAM,SAAS,CAAC;CACrC,OAAO;EACL,SAAS,UAAU,WAAW,IAAI,mCAAmC,MAAM;EAC3E,SACE,UAAU,aACR,QAAQ,eAAe,OAAO,QAAQ,IAAI,mBAAmB,QAAQ,IAAI,CAAC,CAAC,CAAC,aAAa,YAAY;EACzG,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EACzC,GAAI,UAAU,iBAAiB,KAAA,IAC3B,EAAE,cAAc,UAAU,aAAa,IACvC,WAAW,KAAA,IACT,CAAC,IACD,EAAE,cAAc,IAAI,qBAAqB;GAAE;GAAQ;EAAmB,CAAC,EAAE;CACjF;AACF"}
|
|
@@ -226,9 +226,9 @@ var ComputerScriptRunner = class {
|
|
|
226
226
|
this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
227
227
|
this.maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
|
|
228
228
|
}
|
|
229
|
-
async execute(scriptPath, input, signal, options = {}) {
|
|
229
|
+
async execute(scriptPath, input, signal, options = {}, cwd) {
|
|
230
230
|
signal?.throwIfAborted();
|
|
231
|
-
const resolvedPath = await realpath(path.resolve(this.scriptRoot ?? process.cwd(), scriptPath));
|
|
231
|
+
const resolvedPath = await realpath(path.resolve(this.scriptRoot ?? cwd ?? process.cwd(), scriptPath));
|
|
232
232
|
const allowedPaths = await Promise.all(this.allowedScriptPaths.map(async (candidate) => realpath(candidate).catch(() => "")));
|
|
233
233
|
const trusted = options.trusted === true;
|
|
234
234
|
if ((trusted || this.scriptRoot === void 0) && !allowedPaths.includes(resolvedPath)) throw new Error("Computer script path is not explicitly allowed.");
|
|
@@ -431,4 +431,4 @@ var DefaultComputerUseExtensionService = class {
|
|
|
431
431
|
//#endregion
|
|
432
432
|
export { COMMAND_NAME as a, COMMAND_DESCRIPTION as i, ComputerScriptExecutionError as n, COMPUTER_USE_GUIDANCE as o, ComputerScriptRunner as r, COMPUTER_USE_TOOL_NAMES as s, DefaultComputerUseExtensionService as t };
|
|
433
433
|
|
|
434
|
-
//# sourceMappingURL=extensionService-
|
|
434
|
+
//# sourceMappingURL=extensionService-BSqhP2uB.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensionService-BSqhP2uB.mjs","names":[],"sources":["../src/constants/computerUse.ts","../src/services/computerScriptWorker/index.ts","../src/services/computerScriptRunner/index.ts","../src/services/extensionService/index.ts"],"sourcesContent":["export const COMPUTER_USE_GUIDANCE = `[COMPUTER USE ACTIVE]\nUse computer_state before acting and after any action that may change the interface. Use only element refs and snapshot ids returned by computer_state. Use computer_action for one semantic press, focus, set_value, or scroll at a time. Use computer_exec only for a trusted, explicitly allowed local TypeScript script. Never infer coordinates, inspect another application, bypass secure elements, or retry an uncertain outcome. Stop computer use when the task is complete.`;\nexport const COMMAND_NAME = 'computer-use';\nexport const COMMAND_DESCRIPTION = 'Inspect or manage the session computer use mode';\n\nexport const COMPUTER_USE_TOOL_NAMES = ['computer_state', 'computer_action', 'computer_exec'] as const;\n","/** Source for an isolated child process. Restricted modules execute in QuickJS, not in Node's realm. */\nexport const COMPUTER_SCRIPT_WORKER_SOURCE = String.raw`\nimport { readFileSync, realpathSync, statSync } from 'node:fs';\nimport path from 'node:path';\nimport { stripTypeScriptTypes } from 'node:module';\nimport { pathToFileURL } from 'node:url';\n\nlet nextRequestId = 0;\nlet started = false;\nconst pending = new Map();\nconst controller = new AbortController();\nprocess.once('SIGTERM', () => controller.abort());\nconst send = (message) => {\n if (process.connected) process.send(message, () => {});\n};\nconst call = (operation, payload) => new Promise((resolve, reject) => {\n if (controller.signal.aborted) return reject(new Error('Computer script was cancelled.'));\n if (pending.size >= 64) return reject(new Error('Too many outstanding program operations.'));\n const id = String(++nextRequestId);\n pending.set(id, { resolve, reject });\n send({ type: 'program', id, operation, payload });\n});\n\nasync function restricted(message) {\n const { getQuickJS } = await import(pathToFileURL(message.quickjsPath).href);\n const QuickJS = await getQuickJS();\n const runtime = QuickJS.newRuntime();\n runtime.setMemoryLimit(32 * 1024 * 1024);\n runtime.setMaxStackSize(512 * 1024);\n const deadline = Date.now() + message.timeoutMs;\n runtime.setInterruptHandler(() => controller.signal.aborted || Date.now() >= deadline);\n const root = realpathSync(message.scriptRoot);\n const sources = new Map();\n let sourceBytes = 0;\n let moduleFailure;\n const modulePath = (candidate) => {\n const filename = realpathSync(candidate);\n const relative = path.relative(root, filename);\n if (relative === '..' || relative.startsWith('..' + path.sep) || path.isAbsolute(relative)) {\n throw new Error('Computer helper escapes the admitted script root.');\n }\n if (!/\\.(ts|js|mjs)$/.test(filename)) throw new Error('Computer helpers must be JavaScript or erasable TypeScript.');\n return filename;\n };\n const entry = modulePath(message.scriptPath);\n runtime.setModuleLoader((filename) => {\n // Preserve a rejected normalization even if the engine subsequently asks to load an empty name.\n if (moduleFailure) throw moduleFailure;\n if (sources.has(filename)) return sources.get(filename);\n if (sources.size >= 32 || statSync(filename).size > 256 * 1024) throw new Error('Computer script module limit exceeded.');\n const source = readFileSync(filename, 'utf8');\n sourceBytes += Buffer.byteLength(source);\n if (sourceBytes > 512 * 1024) throw new Error('Computer script source limit exceeded.');\n const compiled = filename.endsWith('.ts') ? stripTypeScriptTypes(source, { mode: 'strip' }) : source;\n sources.set(filename, compiled);\n return compiled;\n }, (base, name) => {\n try {\n if (name === '__entry__') return entry;\n if (!name.startsWith('./') && !name.startsWith('../')) {\n throw new Error('Restricted computer functions cannot import host or package modules.');\n }\n return modulePath(path.resolve(path.dirname(base), name));\n } catch (error) {\n moduleFailure = error;\n throw error;\n }\n });\n const vm = runtime.newContext();\n let disposed = false;\n const deferreds = new Set();\n const pump = () => {\n if (disposed) return;\n const jobs = runtime.executePendingJobs();\n if (jobs.error) {\n const detail = vm.dump(jobs.error);\n jobs.error.dispose();\n throw new Error(detail?.message ?? String(detail));\n }\n };\n const set = (name, value) => {\n vm.setProp(vm.global, name, value);\n value.dispose();\n };\n set('__input', vm.newString(JSON.stringify(message.input)));\n set('__aborted', vm.newFunction('__aborted', () => controller.signal.aborted ? vm.true : vm.false));\n set('__log', vm.newFunction('__log', (level, text) => {\n send({ type: 'log', level: vm.getString(level), message: vm.getString(text) });\n }));\n set('__call', vm.newFunction('__call', (operationHandle, payloadHandle) => {\n const operation = vm.getString(operationHandle);\n const serialized = vm.getString(payloadHandle);\n if (serialized.length > message.maxOutputBytes) throw new Error('Computer action exceeds the size limit.');\n if (operation !== 'observe' && operation !== 'act') throw new Error('Unsupported program operation.');\n const deferred = vm.newPromise();\n deferreds.add(deferred);\n call(operation, JSON.parse(serialized)).then((value) => {\n if (disposed) return;\n const handle = vm.newString(JSON.stringify(value));\n deferred.resolve(handle);\n handle.dispose();\n }, (error) => {\n if (disposed) return;\n const handle = vm.newError(error.message);\n deferred.reject(handle);\n handle.dispose();\n }).then(() => {\n if (disposed) return;\n deferred.dispose();\n deferreds.delete(deferred);\n pump();\n }).catch((error) => send({ type: 'failed', error: error.message }));\n return deferred.handle.dup();\n }));\n let evaluation;\n try {\n evaluation = vm.unwrapResult(vm.evalCode(\n 'import { run } from \"__entry__\";\\n' +\n 'const invoke = __call; const log = __log; const isAborted = __aborted;\\n' +\n 'const program = Object.freeze({\\n' +\n ' observe: async (options = {}) => JSON.parse(await invoke(\"observe\", JSON.stringify(options))),\\n' +\n ' act: async (action) => JSON.parse(await invoke(\"act\", JSON.stringify(action)))\\n' +\n '});\\n' +\n 'const logger = Object.freeze(Object.fromEntries([\"debug\",\"info\",\"warn\",\"error\"].map(level => [level, value => log(level, String(value))])));\\n' +\n 'const signal = Object.freeze({ get aborted() { return isAborted(); }, throwIfAborted() { if (isAborted()) throw new Error(\"Computer script was cancelled.\"); } });\\n' +\n 'const result = await run({ context: { program }, input: JSON.parse(__input), logger, signal });\\n' +\n 'globalThis.__result = result === undefined ? undefined : JSON.stringify(result);',\n path.join(root, '__computer_entry__.mjs'), { type: 'module' },\n ));\n const completion = vm.resolvePromise(evaluation);\n pump();\n const completed = vm.unwrapResult(await completion);\n completed.dispose();\n const result = vm.getProp(vm.global, '__result');\n const resultJson = vm.dump(result);\n result.dispose();\n return resultJson;\n } finally {\n disposed = true;\n for (const deferred of deferreds) deferred.dispose();\n evaluation?.dispose();\n vm.dispose();\n runtime.dispose();\n }\n}\n\nprocess.on('message', async (message) => {\n if (message?.type === 'response') {\n const request = pending.get(message.id);\n if (!request) return;\n pending.delete(message.id);\n if (message.error) request.reject(new Error(message.error));\n else request.resolve(message.value);\n return;\n }\n if (message?.type !== 'start' || started) return;\n started = true;\n try {\n let resultJson;\n if (message.trusted) {\n const loaded = await import(pathToFileURL(message.scriptPath).href);\n if (typeof loaded.run !== 'function') throw new Error('Computer script must export a named run function.');\n const program = {\n observe: (options = {}) => call('observe', options),\n act: (action) => call('act', action),\n };\n const logger = Object.fromEntries(['debug','info','warn','error'].map(level => [level, value => {\n send({ type: 'log', level, message: String(value) });\n }]));\n const result = await loaded.run({ context: { program }, input: message.input, logger, signal: controller.signal });\n resultJson = result === undefined ? undefined : JSON.stringify(result);\n } else {\n resultJson = await restricted(message);\n }\n if (typeof resultJson === 'string' && Buffer.byteLength(resultJson) > message.maxOutputBytes) {\n throw new Error('Computer script result exceeded the size limit.');\n }\n send({ type: 'complete', resultJson });\n } catch (error) {\n send({ type: 'failed', error: String(error?.message ?? error).slice(0, 1024) });\n }\n});\n`;\n","import { spawn } from 'node:child_process';\nimport { realpath } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport type {\n ComputerScriptExecutionOptions,\n ComputerScriptExecutionResult,\n ComputerScriptRunnerOptions,\n} from '../../types/computerScript';\nimport type { ComputerUseAction, ComputerUseObservation, ComputerUseSessionClient } from '../../types/computerUse';\nimport { COMPUTER_SCRIPT_WORKER_SOURCE } from '../computerScriptWorker';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_OUTPUT_BYTES = 256 * 1024;\nconst MAX_IMAGE_BYTES = 6 * 1024 * 1024;\nconst MAX_PENDING_OPERATIONS = 64;\n\nexport class ComputerScriptExecutionError extends Error {\n constructor(\n message: string,\n readonly completedActions: number,\n readonly outcomeUncertain: boolean,\n ) {\n super(message);\n this.name = 'ComputerScriptExecutionError';\n }\n}\n\ninterface WorkerMessage {\n readonly type?: unknown;\n readonly id?: unknown;\n readonly operation?: unknown;\n readonly payload?: unknown;\n readonly level?: unknown;\n readonly message?: unknown;\n readonly resultJson?: unknown;\n readonly error?: unknown;\n}\n\nexport class ComputerScriptRunner {\n private readonly client: ComputerUseSessionClient;\n private readonly allowedScriptPaths: readonly string[];\n private readonly scriptRoot?: string;\n private readonly timeoutMs: number;\n private readonly maxOutputBytes: number;\n\n constructor(options: ComputerScriptRunnerOptions) {\n this.client = options.client;\n this.allowedScriptPaths = options.allowedScriptPaths;\n this.scriptRoot = options.scriptRoot;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;\n }\n\n async execute(\n scriptPath: string,\n input: unknown,\n signal?: AbortSignal,\n options: ComputerScriptExecutionOptions = {},\n cwd?: string,\n ): Promise<ComputerScriptExecutionResult> {\n signal?.throwIfAborted();\n const resolvedPath = await realpath(path.resolve(this.scriptRoot ?? cwd ?? process.cwd(), scriptPath));\n const allowedPaths = await Promise.all(\n this.allowedScriptPaths.map(async (candidate) => realpath(candidate).catch(() => '')),\n );\n const trusted = options.trusted === true;\n if ((trusted || this.scriptRoot === undefined) && !allowedPaths.includes(resolvedPath)) {\n throw new Error('Computer script path is not explicitly allowed.');\n }\n if (!/\\.(ts|js|mjs)$/u.test(resolvedPath))\n throw new Error('Computer scripts must be JavaScript or erasable TypeScript files.');\n const root = await realpath(this.scriptRoot ?? path.dirname(resolvedPath));\n const relative = path.relative(root, resolvedPath);\n if (!trusted && (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative))) {\n throw new Error('Computer script escapes the admitted script root.');\n }\n const serializedInput = JSON.stringify(input);\n if (serializedInput === undefined) throw new Error('Computer script input must be JSON serializable.');\n if (Buffer.byteLength(serializedInput) > this.maxOutputBytes)\n throw new Error('Computer script input exceeds the size limit.');\n const quickjsPath = trusted ? undefined : createRequire(import.meta.url).resolve('quickjs-emscripten');\n signal?.throwIfAborted();\n const started = performance.now();\n\n return new Promise((resolve, reject) => {\n const child = spawn(process.execPath, ['--input-type=module', '--eval', COMPUTER_SCRIPT_WORKER_SOURCE], {\n stdio: ['ignore', 'pipe', 'pipe', 'ipc'],\n // Preserve Electron's Node mode, but no host credentials, for restricted workers.\n env: trusted ? process.env : { ELECTRON_RUN_AS_NODE: '1' },\n });\n const controller = new AbortController();\n const logs: string[] = [];\n let outputBytes = 0;\n let completedActions = 0;\n let observations = 0;\n let actionInFlight = false;\n let settled = false;\n let completing = false;\n let outstanding = 0;\n let operation: Promise<void> = Promise.resolve();\n const finish = (error?: Error, value?: ComputerScriptExecutionResult): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timeout);\n signal?.removeEventListener('abort', onAbort);\n controller.abort();\n child.kill('SIGTERM');\n const killTimer = setTimeout(() => child.kill('SIGKILL'), 250);\n killTimer.unref();\n if (error) reject(new ComputerScriptExecutionError(error.message, completedActions, actionInFlight));\n else resolve(value!);\n };\n const addOutput = (value: string): boolean => {\n outputBytes += Buffer.byteLength(value);\n if (outputBytes <= this.maxOutputBytes) return true;\n finish(new Error('Computer script output exceeded the size limit.'));\n return false;\n };\n const send = (value: object): void => {\n if (settled || !child.connected) return;\n child.send(value, (error) => {\n if (error && !settled) finish(error);\n });\n };\n const onAbort = (): void => finish(new Error('Computer script execution was cancelled.'));\n const timeout = setTimeout(() => finish(new Error('Computer script execution timed out.')), this.timeoutMs);\n timeout.unref();\n signal?.addEventListener('abort', onAbort, { once: true });\n if (signal?.aborted) return onAbort();\n child.stdout?.on('data', (chunk: Buffer) => addOutput(chunk.toString('utf8')));\n child.stderr?.on('data', (chunk: Buffer) => addOutput(chunk.toString('utf8')));\n child.on('error', (error) => finish(error));\n child.on('exit', (code, exitSignal) => {\n if (!settled)\n finish(new Error(`Computer script worker exited before completion (${exitSignal ?? code ?? 'unknown'}).`));\n });\n\n const observe = async (includeScreenshot: boolean): Promise<ComputerUseObservation> => {\n const value = await this.client.observe(controller.signal, { includeScreenshot });\n observations += 1;\n const { screenshot, ...semantic } = value;\n if (Buffer.byteLength(JSON.stringify(semantic)) > this.maxOutputBytes)\n throw new Error('Computer observation exceeds the size limit.');\n if (includeScreenshot && screenshot) {\n if (screenshot.mimeType !== 'image/png' || screenshot.data.length > Math.ceil(MAX_IMAGE_BYTES / 3) * 4) {\n throw new Error('Computer screenshot exceeds the image limit.');\n }\n return { ...semantic, screenshot };\n }\n return semantic;\n };\n\n child.on('message', (raw: WorkerMessage) => {\n if (settled) return;\n if (!raw || typeof raw !== 'object' || Buffer.byteLength(JSON.stringify(raw)) > this.maxOutputBytes + 4096) {\n finish(new Error('Computer worker message exceeds the size limit.'));\n return;\n }\n if (raw.type === 'log' && typeof raw.message === 'string') {\n const line = `[${String(raw.level)}] ${raw.message}`;\n if (addOutput(line)) logs.push(line);\n return;\n }\n if (raw.type === 'program') {\n if (\n completing ||\n typeof raw.id !== 'string' ||\n raw.id.length > 128 ||\n (raw.operation !== 'observe' && raw.operation !== 'act') ||\n outstanding >= MAX_PENDING_OPERATIONS\n ) {\n finish(new Error('Invalid or excessive computer program operations.'));\n return;\n }\n outstanding += 1;\n operation = operation\n .then(async () => {\n if (settled || controller.signal.aborted) return;\n try {\n let value: unknown;\n if (raw.operation === 'observe') {\n const settings = raw.payload;\n if (\n !settings ||\n typeof settings !== 'object' ||\n Array.isArray(settings) ||\n Object.keys(settings).some((key) => key !== 'includeScreenshot') ||\n ('includeScreenshot' in settings && typeof settings.includeScreenshot !== 'boolean')\n ) {\n throw new Error('Invalid observation options.');\n }\n value = await observe('includeScreenshot' in settings && settings.includeScreenshot === true);\n } else {\n actionInFlight = true;\n value = await this.client.act(raw.payload as ComputerUseAction, controller.signal);\n completedActions += 1;\n actionInFlight = false;\n }\n send({ type: 'response', id: raw.id, value });\n } catch (error) {\n // An action can have taken effect before its transport failed. Never run the remaining chain.\n if (actionInFlight) finish(error instanceof Error ? error : new Error(String(error)));\n else\n send({ type: 'response', id: raw.id, error: error instanceof Error ? error.message : String(error) });\n } finally {\n outstanding -= 1;\n }\n })\n .catch((error: unknown) => finish(error instanceof Error ? error : new Error(String(error))));\n return;\n }\n if (raw.type === 'failed' && typeof raw.error === 'string') {\n finish(new Error(raw.error));\n return;\n }\n if (raw.type === 'complete') {\n if (completing) {\n finish(new Error('Computer worker completed twice.'));\n return;\n }\n completing = true;\n operation = operation\n .then(async () => {\n if (settled) return;\n const resultJson = raw.resultJson;\n if (resultJson !== undefined && typeof resultJson !== 'string')\n throw new Error('Computer script returned an invalid result.');\n if (typeof resultJson === 'string' && !addOutput(resultJson)) return;\n const observation = await observe(options.includeScreenshot === true);\n if (settled || !addOutput(JSON.stringify({ ...observation, screenshot: undefined }))) return;\n finish(undefined, {\n ...(typeof resultJson === 'string' ? { result: JSON.parse(resultJson) as unknown } : {}),\n observation,\n logs,\n metrics: {\n actions: completedActions,\n observations,\n durationMs: Math.round(performance.now() - started),\n outputBytes,\n },\n });\n })\n .catch((error: unknown) => finish(error instanceof Error ? error : new Error(String(error))));\n }\n });\n send({\n type: 'start',\n scriptPath: resolvedPath,\n scriptRoot: root,\n input: JSON.parse(serializedInput) as unknown,\n trusted,\n quickjsPath,\n timeoutMs: this.timeoutMs,\n maxOutputBytes: this.maxOutputBytes,\n });\n });\n }\n}\n","import type { ComputerUseExtensionResult, ComputerUseExtensionService } from '../../types/extension';\nimport type { ComputerUseSessionClient } from '../sessionApiClient';\n\nexport class DefaultComputerUseExtensionService implements ComputerUseExtensionService {\n public constructor(private readonly client?: ComputerUseSessionClient) {}\n\n public async execute(): Promise<ComputerUseExtensionResult> {\n if (this.client === undefined)\n return { message: 'Computer use requires a DoomPi Desktop session.', level: 'error' };\n const state = await this.client.state();\n return { message: `Computer use is ${state.phase.replaceAll('_', ' ')}.`, level: 'info' };\n }\n}\n"],"mappings":"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"}
|
|
@@ -249,9 +249,9 @@ var ComputerScriptRunner = class {
|
|
|
249
249
|
this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
250
250
|
this.maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
|
|
251
251
|
}
|
|
252
|
-
async execute(scriptPath, input, signal, options = {}) {
|
|
252
|
+
async execute(scriptPath, input, signal, options = {}, cwd) {
|
|
253
253
|
signal?.throwIfAborted();
|
|
254
|
-
const resolvedPath = await (0, node_fs_promises.realpath)(node_path.default.resolve(this.scriptRoot ?? process.cwd(), scriptPath));
|
|
254
|
+
const resolvedPath = await (0, node_fs_promises.realpath)(node_path.default.resolve(this.scriptRoot ?? cwd ?? process.cwd(), scriptPath));
|
|
255
255
|
const allowedPaths = await Promise.all(this.allowedScriptPaths.map(async (candidate) => (0, node_fs_promises.realpath)(candidate).catch(() => "")));
|
|
256
256
|
const trusted = options.trusted === true;
|
|
257
257
|
if ((trusted || this.scriptRoot === void 0) && !allowedPaths.includes(resolvedPath)) throw new Error("Computer script path is not explicitly allowed.");
|
|
@@ -501,4 +501,4 @@ Object.defineProperty(exports, "__toESM", {
|
|
|
501
501
|
}
|
|
502
502
|
});
|
|
503
503
|
|
|
504
|
-
//# sourceMappingURL=extensionService-
|
|
504
|
+
//# sourceMappingURL=extensionService-CIDyPyzP.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensionService-CIDyPyzP.cjs","names":["realpath","path","createRequire","spawn"],"sources":["../src/constants/computerUse.ts","../src/services/computerScriptWorker/index.ts","../src/services/computerScriptRunner/index.ts","../src/services/extensionService/index.ts"],"sourcesContent":["export const COMPUTER_USE_GUIDANCE = `[COMPUTER USE ACTIVE]\nUse computer_state before acting and after any action that may change the interface. Use only element refs and snapshot ids returned by computer_state. Use computer_action for one semantic press, focus, set_value, or scroll at a time. Use computer_exec only for a trusted, explicitly allowed local TypeScript script. Never infer coordinates, inspect another application, bypass secure elements, or retry an uncertain outcome. Stop computer use when the task is complete.`;\nexport const COMMAND_NAME = 'computer-use';\nexport const COMMAND_DESCRIPTION = 'Inspect or manage the session computer use mode';\n\nexport const COMPUTER_USE_TOOL_NAMES = ['computer_state', 'computer_action', 'computer_exec'] as const;\n","/** Source for an isolated child process. Restricted modules execute in QuickJS, not in Node's realm. */\nexport const COMPUTER_SCRIPT_WORKER_SOURCE = String.raw`\nimport { readFileSync, realpathSync, statSync } from 'node:fs';\nimport path from 'node:path';\nimport { stripTypeScriptTypes } from 'node:module';\nimport { pathToFileURL } from 'node:url';\n\nlet nextRequestId = 0;\nlet started = false;\nconst pending = new Map();\nconst controller = new AbortController();\nprocess.once('SIGTERM', () => controller.abort());\nconst send = (message) => {\n if (process.connected) process.send(message, () => {});\n};\nconst call = (operation, payload) => new Promise((resolve, reject) => {\n if (controller.signal.aborted) return reject(new Error('Computer script was cancelled.'));\n if (pending.size >= 64) return reject(new Error('Too many outstanding program operations.'));\n const id = String(++nextRequestId);\n pending.set(id, { resolve, reject });\n send({ type: 'program', id, operation, payload });\n});\n\nasync function restricted(message) {\n const { getQuickJS } = await import(pathToFileURL(message.quickjsPath).href);\n const QuickJS = await getQuickJS();\n const runtime = QuickJS.newRuntime();\n runtime.setMemoryLimit(32 * 1024 * 1024);\n runtime.setMaxStackSize(512 * 1024);\n const deadline = Date.now() + message.timeoutMs;\n runtime.setInterruptHandler(() => controller.signal.aborted || Date.now() >= deadline);\n const root = realpathSync(message.scriptRoot);\n const sources = new Map();\n let sourceBytes = 0;\n let moduleFailure;\n const modulePath = (candidate) => {\n const filename = realpathSync(candidate);\n const relative = path.relative(root, filename);\n if (relative === '..' || relative.startsWith('..' + path.sep) || path.isAbsolute(relative)) {\n throw new Error('Computer helper escapes the admitted script root.');\n }\n if (!/\\.(ts|js|mjs)$/.test(filename)) throw new Error('Computer helpers must be JavaScript or erasable TypeScript.');\n return filename;\n };\n const entry = modulePath(message.scriptPath);\n runtime.setModuleLoader((filename) => {\n // Preserve a rejected normalization even if the engine subsequently asks to load an empty name.\n if (moduleFailure) throw moduleFailure;\n if (sources.has(filename)) return sources.get(filename);\n if (sources.size >= 32 || statSync(filename).size > 256 * 1024) throw new Error('Computer script module limit exceeded.');\n const source = readFileSync(filename, 'utf8');\n sourceBytes += Buffer.byteLength(source);\n if (sourceBytes > 512 * 1024) throw new Error('Computer script source limit exceeded.');\n const compiled = filename.endsWith('.ts') ? stripTypeScriptTypes(source, { mode: 'strip' }) : source;\n sources.set(filename, compiled);\n return compiled;\n }, (base, name) => {\n try {\n if (name === '__entry__') return entry;\n if (!name.startsWith('./') && !name.startsWith('../')) {\n throw new Error('Restricted computer functions cannot import host or package modules.');\n }\n return modulePath(path.resolve(path.dirname(base), name));\n } catch (error) {\n moduleFailure = error;\n throw error;\n }\n });\n const vm = runtime.newContext();\n let disposed = false;\n const deferreds = new Set();\n const pump = () => {\n if (disposed) return;\n const jobs = runtime.executePendingJobs();\n if (jobs.error) {\n const detail = vm.dump(jobs.error);\n jobs.error.dispose();\n throw new Error(detail?.message ?? String(detail));\n }\n };\n const set = (name, value) => {\n vm.setProp(vm.global, name, value);\n value.dispose();\n };\n set('__input', vm.newString(JSON.stringify(message.input)));\n set('__aborted', vm.newFunction('__aborted', () => controller.signal.aborted ? vm.true : vm.false));\n set('__log', vm.newFunction('__log', (level, text) => {\n send({ type: 'log', level: vm.getString(level), message: vm.getString(text) });\n }));\n set('__call', vm.newFunction('__call', (operationHandle, payloadHandle) => {\n const operation = vm.getString(operationHandle);\n const serialized = vm.getString(payloadHandle);\n if (serialized.length > message.maxOutputBytes) throw new Error('Computer action exceeds the size limit.');\n if (operation !== 'observe' && operation !== 'act') throw new Error('Unsupported program operation.');\n const deferred = vm.newPromise();\n deferreds.add(deferred);\n call(operation, JSON.parse(serialized)).then((value) => {\n if (disposed) return;\n const handle = vm.newString(JSON.stringify(value));\n deferred.resolve(handle);\n handle.dispose();\n }, (error) => {\n if (disposed) return;\n const handle = vm.newError(error.message);\n deferred.reject(handle);\n handle.dispose();\n }).then(() => {\n if (disposed) return;\n deferred.dispose();\n deferreds.delete(deferred);\n pump();\n }).catch((error) => send({ type: 'failed', error: error.message }));\n return deferred.handle.dup();\n }));\n let evaluation;\n try {\n evaluation = vm.unwrapResult(vm.evalCode(\n 'import { run } from \"__entry__\";\\n' +\n 'const invoke = __call; const log = __log; const isAborted = __aborted;\\n' +\n 'const program = Object.freeze({\\n' +\n ' observe: async (options = {}) => JSON.parse(await invoke(\"observe\", JSON.stringify(options))),\\n' +\n ' act: async (action) => JSON.parse(await invoke(\"act\", JSON.stringify(action)))\\n' +\n '});\\n' +\n 'const logger = Object.freeze(Object.fromEntries([\"debug\",\"info\",\"warn\",\"error\"].map(level => [level, value => log(level, String(value))])));\\n' +\n 'const signal = Object.freeze({ get aborted() { return isAborted(); }, throwIfAborted() { if (isAborted()) throw new Error(\"Computer script was cancelled.\"); } });\\n' +\n 'const result = await run({ context: { program }, input: JSON.parse(__input), logger, signal });\\n' +\n 'globalThis.__result = result === undefined ? undefined : JSON.stringify(result);',\n path.join(root, '__computer_entry__.mjs'), { type: 'module' },\n ));\n const completion = vm.resolvePromise(evaluation);\n pump();\n const completed = vm.unwrapResult(await completion);\n completed.dispose();\n const result = vm.getProp(vm.global, '__result');\n const resultJson = vm.dump(result);\n result.dispose();\n return resultJson;\n } finally {\n disposed = true;\n for (const deferred of deferreds) deferred.dispose();\n evaluation?.dispose();\n vm.dispose();\n runtime.dispose();\n }\n}\n\nprocess.on('message', async (message) => {\n if (message?.type === 'response') {\n const request = pending.get(message.id);\n if (!request) return;\n pending.delete(message.id);\n if (message.error) request.reject(new Error(message.error));\n else request.resolve(message.value);\n return;\n }\n if (message?.type !== 'start' || started) return;\n started = true;\n try {\n let resultJson;\n if (message.trusted) {\n const loaded = await import(pathToFileURL(message.scriptPath).href);\n if (typeof loaded.run !== 'function') throw new Error('Computer script must export a named run function.');\n const program = {\n observe: (options = {}) => call('observe', options),\n act: (action) => call('act', action),\n };\n const logger = Object.fromEntries(['debug','info','warn','error'].map(level => [level, value => {\n send({ type: 'log', level, message: String(value) });\n }]));\n const result = await loaded.run({ context: { program }, input: message.input, logger, signal: controller.signal });\n resultJson = result === undefined ? undefined : JSON.stringify(result);\n } else {\n resultJson = await restricted(message);\n }\n if (typeof resultJson === 'string' && Buffer.byteLength(resultJson) > message.maxOutputBytes) {\n throw new Error('Computer script result exceeded the size limit.');\n }\n send({ type: 'complete', resultJson });\n } catch (error) {\n send({ type: 'failed', error: String(error?.message ?? error).slice(0, 1024) });\n }\n});\n`;\n","import { spawn } from 'node:child_process';\nimport { realpath } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport type {\n ComputerScriptExecutionOptions,\n ComputerScriptExecutionResult,\n ComputerScriptRunnerOptions,\n} from '../../types/computerScript';\nimport type { ComputerUseAction, ComputerUseObservation, ComputerUseSessionClient } from '../../types/computerUse';\nimport { COMPUTER_SCRIPT_WORKER_SOURCE } from '../computerScriptWorker';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_OUTPUT_BYTES = 256 * 1024;\nconst MAX_IMAGE_BYTES = 6 * 1024 * 1024;\nconst MAX_PENDING_OPERATIONS = 64;\n\nexport class ComputerScriptExecutionError extends Error {\n constructor(\n message: string,\n readonly completedActions: number,\n readonly outcomeUncertain: boolean,\n ) {\n super(message);\n this.name = 'ComputerScriptExecutionError';\n }\n}\n\ninterface WorkerMessage {\n readonly type?: unknown;\n readonly id?: unknown;\n readonly operation?: unknown;\n readonly payload?: unknown;\n readonly level?: unknown;\n readonly message?: unknown;\n readonly resultJson?: unknown;\n readonly error?: unknown;\n}\n\nexport class ComputerScriptRunner {\n private readonly client: ComputerUseSessionClient;\n private readonly allowedScriptPaths: readonly string[];\n private readonly scriptRoot?: string;\n private readonly timeoutMs: number;\n private readonly maxOutputBytes: number;\n\n constructor(options: ComputerScriptRunnerOptions) {\n this.client = options.client;\n this.allowedScriptPaths = options.allowedScriptPaths;\n this.scriptRoot = options.scriptRoot;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;\n }\n\n async execute(\n scriptPath: string,\n input: unknown,\n signal?: AbortSignal,\n options: ComputerScriptExecutionOptions = {},\n cwd?: string,\n ): Promise<ComputerScriptExecutionResult> {\n signal?.throwIfAborted();\n const resolvedPath = await realpath(path.resolve(this.scriptRoot ?? cwd ?? process.cwd(), scriptPath));\n const allowedPaths = await Promise.all(\n this.allowedScriptPaths.map(async (candidate) => realpath(candidate).catch(() => '')),\n );\n const trusted = options.trusted === true;\n if ((trusted || this.scriptRoot === undefined) && !allowedPaths.includes(resolvedPath)) {\n throw new Error('Computer script path is not explicitly allowed.');\n }\n if (!/\\.(ts|js|mjs)$/u.test(resolvedPath))\n throw new Error('Computer scripts must be JavaScript or erasable TypeScript files.');\n const root = await realpath(this.scriptRoot ?? path.dirname(resolvedPath));\n const relative = path.relative(root, resolvedPath);\n if (!trusted && (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative))) {\n throw new Error('Computer script escapes the admitted script root.');\n }\n const serializedInput = JSON.stringify(input);\n if (serializedInput === undefined) throw new Error('Computer script input must be JSON serializable.');\n if (Buffer.byteLength(serializedInput) > this.maxOutputBytes)\n throw new Error('Computer script input exceeds the size limit.');\n const quickjsPath = trusted ? undefined : createRequire(import.meta.url).resolve('quickjs-emscripten');\n signal?.throwIfAborted();\n const started = performance.now();\n\n return new Promise((resolve, reject) => {\n const child = spawn(process.execPath, ['--input-type=module', '--eval', COMPUTER_SCRIPT_WORKER_SOURCE], {\n stdio: ['ignore', 'pipe', 'pipe', 'ipc'],\n // Preserve Electron's Node mode, but no host credentials, for restricted workers.\n env: trusted ? process.env : { ELECTRON_RUN_AS_NODE: '1' },\n });\n const controller = new AbortController();\n const logs: string[] = [];\n let outputBytes = 0;\n let completedActions = 0;\n let observations = 0;\n let actionInFlight = false;\n let settled = false;\n let completing = false;\n let outstanding = 0;\n let operation: Promise<void> = Promise.resolve();\n const finish = (error?: Error, value?: ComputerScriptExecutionResult): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timeout);\n signal?.removeEventListener('abort', onAbort);\n controller.abort();\n child.kill('SIGTERM');\n const killTimer = setTimeout(() => child.kill('SIGKILL'), 250);\n killTimer.unref();\n if (error) reject(new ComputerScriptExecutionError(error.message, completedActions, actionInFlight));\n else resolve(value!);\n };\n const addOutput = (value: string): boolean => {\n outputBytes += Buffer.byteLength(value);\n if (outputBytes <= this.maxOutputBytes) return true;\n finish(new Error('Computer script output exceeded the size limit.'));\n return false;\n };\n const send = (value: object): void => {\n if (settled || !child.connected) return;\n child.send(value, (error) => {\n if (error && !settled) finish(error);\n });\n };\n const onAbort = (): void => finish(new Error('Computer script execution was cancelled.'));\n const timeout = setTimeout(() => finish(new Error('Computer script execution timed out.')), this.timeoutMs);\n timeout.unref();\n signal?.addEventListener('abort', onAbort, { once: true });\n if (signal?.aborted) return onAbort();\n child.stdout?.on('data', (chunk: Buffer) => addOutput(chunk.toString('utf8')));\n child.stderr?.on('data', (chunk: Buffer) => addOutput(chunk.toString('utf8')));\n child.on('error', (error) => finish(error));\n child.on('exit', (code, exitSignal) => {\n if (!settled)\n finish(new Error(`Computer script worker exited before completion (${exitSignal ?? code ?? 'unknown'}).`));\n });\n\n const observe = async (includeScreenshot: boolean): Promise<ComputerUseObservation> => {\n const value = await this.client.observe(controller.signal, { includeScreenshot });\n observations += 1;\n const { screenshot, ...semantic } = value;\n if (Buffer.byteLength(JSON.stringify(semantic)) > this.maxOutputBytes)\n throw new Error('Computer observation exceeds the size limit.');\n if (includeScreenshot && screenshot) {\n if (screenshot.mimeType !== 'image/png' || screenshot.data.length > Math.ceil(MAX_IMAGE_BYTES / 3) * 4) {\n throw new Error('Computer screenshot exceeds the image limit.');\n }\n return { ...semantic, screenshot };\n }\n return semantic;\n };\n\n child.on('message', (raw: WorkerMessage) => {\n if (settled) return;\n if (!raw || typeof raw !== 'object' || Buffer.byteLength(JSON.stringify(raw)) > this.maxOutputBytes + 4096) {\n finish(new Error('Computer worker message exceeds the size limit.'));\n return;\n }\n if (raw.type === 'log' && typeof raw.message === 'string') {\n const line = `[${String(raw.level)}] ${raw.message}`;\n if (addOutput(line)) logs.push(line);\n return;\n }\n if (raw.type === 'program') {\n if (\n completing ||\n typeof raw.id !== 'string' ||\n raw.id.length > 128 ||\n (raw.operation !== 'observe' && raw.operation !== 'act') ||\n outstanding >= MAX_PENDING_OPERATIONS\n ) {\n finish(new Error('Invalid or excessive computer program operations.'));\n return;\n }\n outstanding += 1;\n operation = operation\n .then(async () => {\n if (settled || controller.signal.aborted) return;\n try {\n let value: unknown;\n if (raw.operation === 'observe') {\n const settings = raw.payload;\n if (\n !settings ||\n typeof settings !== 'object' ||\n Array.isArray(settings) ||\n Object.keys(settings).some((key) => key !== 'includeScreenshot') ||\n ('includeScreenshot' in settings && typeof settings.includeScreenshot !== 'boolean')\n ) {\n throw new Error('Invalid observation options.');\n }\n value = await observe('includeScreenshot' in settings && settings.includeScreenshot === true);\n } else {\n actionInFlight = true;\n value = await this.client.act(raw.payload as ComputerUseAction, controller.signal);\n completedActions += 1;\n actionInFlight = false;\n }\n send({ type: 'response', id: raw.id, value });\n } catch (error) {\n // An action can have taken effect before its transport failed. Never run the remaining chain.\n if (actionInFlight) finish(error instanceof Error ? error : new Error(String(error)));\n else\n send({ type: 'response', id: raw.id, error: error instanceof Error ? error.message : String(error) });\n } finally {\n outstanding -= 1;\n }\n })\n .catch((error: unknown) => finish(error instanceof Error ? error : new Error(String(error))));\n return;\n }\n if (raw.type === 'failed' && typeof raw.error === 'string') {\n finish(new Error(raw.error));\n return;\n }\n if (raw.type === 'complete') {\n if (completing) {\n finish(new Error('Computer worker completed twice.'));\n return;\n }\n completing = true;\n operation = operation\n .then(async () => {\n if (settled) return;\n const resultJson = raw.resultJson;\n if (resultJson !== undefined && typeof resultJson !== 'string')\n throw new Error('Computer script returned an invalid result.');\n if (typeof resultJson === 'string' && !addOutput(resultJson)) return;\n const observation = await observe(options.includeScreenshot === true);\n if (settled || !addOutput(JSON.stringify({ ...observation, screenshot: undefined }))) return;\n finish(undefined, {\n ...(typeof resultJson === 'string' ? { result: JSON.parse(resultJson) as unknown } : {}),\n observation,\n logs,\n metrics: {\n actions: completedActions,\n observations,\n durationMs: Math.round(performance.now() - started),\n outputBytes,\n },\n });\n })\n .catch((error: unknown) => finish(error instanceof Error ? error : new Error(String(error))));\n }\n });\n send({\n type: 'start',\n scriptPath: resolvedPath,\n scriptRoot: root,\n input: JSON.parse(serializedInput) as unknown,\n trusted,\n quickjsPath,\n timeoutMs: this.timeoutMs,\n maxOutputBytes: this.maxOutputBytes,\n });\n });\n }\n}\n","import type { ComputerUseExtensionResult, ComputerUseExtensionService } from '../../types/extension';\nimport type { ComputerUseSessionClient } from '../sessionApiClient';\n\nexport class DefaultComputerUseExtensionService implements ComputerUseExtensionService {\n public constructor(private readonly client?: ComputerUseSessionClient) {}\n\n public async execute(): Promise<ComputerUseExtensionResult> {\n if (this.client === undefined)\n return { message: 'Computer use requires a DoomPi Desktop session.', level: 'error' };\n const state = await this.client.state();\n return { message: `Computer use is ${state.phase.replaceAll('_', ' ')}.`, level: 'info' };\n }\n}\n"],"mappings":"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"}
|
package/dist/extensions/pi.cjs
CHANGED
|
@@ -2,9 +2,9 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_extensionService = require("../extensionService-
|
|
6
|
-
const require_dependencies = require("../dependencies-
|
|
7
|
-
const require_computerUseMode = require("../computerUseMode-
|
|
5
|
+
const require_extensionService = require("../extensionService-CIDyPyzP.cjs");
|
|
6
|
+
const require_dependencies = require("../dependencies-BQOsqM8Q.cjs");
|
|
7
|
+
const require_computerUseMode = require("../computerUseMode-KnoOWve4.cjs");
|
|
8
8
|
let _agimon_ai_doompi_core_piExtension = require("@agimon-ai/doompi-core/piExtension");
|
|
9
9
|
let _agimon_ai_doompi_core_extensionFile = require("@agimon-ai/doompi-core/extensionFile");
|
|
10
10
|
let _agimon_ai_doompi_minor_mode = require("@agimon-ai/doompi-minor-mode");
|
|
@@ -61,7 +61,7 @@ function createComputerUseRuntime(dependencies, signal) {
|
|
|
61
61
|
if (signal.aborted) return;
|
|
62
62
|
let nextGloballyEnabled = false;
|
|
63
63
|
try {
|
|
64
|
-
nextGloballyEnabled = await dependencies.enabled?.() === true;
|
|
64
|
+
nextGloballyEnabled = await dependencies.enabled?.(activeContext?.cwd) === true;
|
|
65
65
|
} catch {
|
|
66
66
|
nextGloballyEnabled = false;
|
|
67
67
|
}
|
|
@@ -132,7 +132,7 @@ function createComputerUseRuntime(dependencies, signal) {
|
|
|
132
132
|
async handleAction(_runtime, actionId, _argumentsValue, execution) {
|
|
133
133
|
activeContext = execution.context;
|
|
134
134
|
if (actionId === "activate") {
|
|
135
|
-
if (await dependencies.enabled?.() !== true) {
|
|
135
|
+
if (await dependencies.enabled?.(execution.context.cwd) !== true) {
|
|
136
136
|
await refresh();
|
|
137
137
|
throw new Error("Enable computer use in global settings first.");
|
|
138
138
|
}
|
|
@@ -245,12 +245,12 @@ function createComputerUseRuntime(dependencies, signal) {
|
|
|
245
245
|
required: ["scriptPath", "input"],
|
|
246
246
|
additionalProperties: false
|
|
247
247
|
},
|
|
248
|
-
async execute(_toolCallId, params, signal) {
|
|
248
|
+
async execute(_toolCallId, params, signal, _onUpdate, context) {
|
|
249
249
|
if (!globallyEnabled || client === void 0 || state?.phase !== "active") throw new Error("Computer use is not active for this session.");
|
|
250
250
|
if (dependencies.scriptRunner === void 0) throw new Error("Computer script execution is unavailable.");
|
|
251
251
|
const input = params;
|
|
252
252
|
try {
|
|
253
|
-
return require_computerUseMode.computerScriptOutput(await dependencies.scriptRunner.execute(input.scriptPath, input.input, signal, input));
|
|
253
|
+
return require_computerUseMode.computerScriptOutput(await dependencies.scriptRunner.execute(input.scriptPath, input.input, signal, input, context.cwd));
|
|
254
254
|
} catch (error) {
|
|
255
255
|
return require_computerUseMode.computerScriptFailure(error);
|
|
256
256
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.cjs","names":["COMMAND_NAME","COMMAND_DESCRIPTION","computerUseRestriction","COMPUTER_USE_MODE_STATUS_KEY","COMPUTER_USE_STATUS_KEY","defineMinorMode","COMPUTER_USE_MODE_ID","modeState","computerObservationOutput","computerScriptOutput","computerScriptFailure","piMinorModes","COMPUTER_USE_GUIDANCE","createComputerUseDependencies","defineRoot","runtime","defineCliCommand","defineCliHook","defineCliHook","defineToolRestriction","defineCliTool","defineCliTool","defineCliTool","definePiExtension","rootSession","composeRootHooks","commandComputerUse","hookBeforeAgentStart","hookSessionStart","toolRestrictionComputerUse","piToolContributions","tool00ComputerState","tool10ComputerAction","tool20ComputerExec"],"sources":["../../src/services/computerUseCommand/index.ts","../../src/services/computerUseRuntime/index.ts","../../src/extensions/workspaces/sessions/(backend)/_runtime/index.cli.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/computer-use.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool-restriction/computer-use.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/00-computer-state.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/10-computer-action.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/20-computer-exec.cli.ts","../../generated/pi.ts"],"sourcesContent":["// @scaffold-generated\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../constants/computerUse';\nimport type { ComputerUseExtensionService } from '../../types/extension';\n\nexport function createComputerUseCommand(\n service: ComputerUseExtensionService,\n): Parameters<ExtensionAPI['registerCommand']> {\n return [\n COMMAND_NAME,\n {\n description: COMMAND_DESCRIPTION,\n handler: async (_args, ctx) => {\n const result = await service.execute();\n if (ctx.hasUI) ctx.ui.notify(result.message, result.level);\n },\n },\n ];\n}\n\nexport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../constants/computerUse';\n","import { type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { type DoomToolRestriction } from '@agimon-ai/doompi-core/toolSurface';\nimport { piMinorModes } from '@agimon-ai/doompi-minor-mode';\nimport { defineMinorMode, type MinorModeOwner, type MinorModeOwnerActionContext } from '@agimon-ai/doompi-minor-mode';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport { COMPUTER_USE_GUIDANCE } from '../../constants/computerUse';\nimport type { ComputerScriptExecutionOptions } from '../../types/computerScript';\nimport type { ComputerUseAction } from '../../types/computerUse';\nimport {\n COMPUTER_USE_MODE_ID,\n COMPUTER_USE_MODE_STATUS_KEY,\n COMPUTER_USE_STATUS_KEY,\n type ComputerUseSessionView,\n} from '../../types/computerUseApi';\nimport type { ComputerUseExtensionDependencies } from '../../types/extension';\nimport { computerObservationOutput, computerScriptOutput, computerScriptFailure } from '../computerToolOutput';\nimport { createComputerUseCommand } from '../computerUseCommand';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-computer-use';\nexport { COMPUTER_USE_MODE_ID };\nimport { modeState, computerUseRestriction } from '../../models/computerUseMode';\n\nexport function createComputerUseRuntime(\n dependencies: ComputerUseExtensionDependencies,\n signal: AbortSignal,\n): PiPluginContributions<ComputerUseExtensionDependencies> & {\n tools: readonly Parameters<ExtensionAPI['registerTool']>[0][];\n} {\n const client = dependencies.client;\n let state: ComputerUseSessionView | undefined;\n let enabled = false;\n let restriction: DoomToolRestriction = computerUseRestriction(false);\n const restrictionListeners = new Set<() => void>();\n const reconcileTools = (active: boolean): void => {\n restriction = computerUseRestriction(active);\n for (const listener of restrictionListeners) listener();\n };\n let globallyEnabled = false;\n let mode: MinorModeOwner<MinorModeOwnerActionContext<ExtensionContext>>;\n const modeListeners = new Set<() => void>();\n let timer: ReturnType<typeof setInterval> | undefined;\n let activeContext: ExtensionContext | undefined;\n let publishedMode = '';\n let publishedModeStatus: string | undefined;\n let publishedActivityStatus: string | undefined;\n const publish = (): void => {\n const phase = state?.phase ?? 'inactive';\n const projection = `${enabled}:${phase}:${state?.revision ?? 'none'}`;\n if (mode !== undefined && projection !== publishedMode) {\n mode.publish();\n publishedMode = projection;\n }\n const modeStatus = state === undefined ? undefined : enabled || phase !== 'inactive' ? phase : '';\n if (activeContext !== undefined && modeStatus !== publishedModeStatus) {\n activeContext.ui.setStatus(COMPUTER_USE_MODE_STATUS_KEY, modeStatus);\n publishedModeStatus = modeStatus;\n }\n const activityStatus = enabled || phase !== 'inactive' ? `computer use: ${phase}` : undefined;\n if (activeContext !== undefined && activityStatus !== publishedActivityStatus) {\n activeContext.ui.setStatus(COMPUTER_USE_STATUS_KEY, activityStatus);\n publishedActivityStatus = activityStatus;\n }\n };\n const refresh = async (): Promise<void> => {\n if (signal.aborted) return;\n let nextGloballyEnabled = false;\n try {\n nextGloballyEnabled = (await dependencies.enabled?.()) === true;\n } catch {\n nextGloballyEnabled = false;\n }\n if (signal.aborted) return;\n if (nextGloballyEnabled !== globallyEnabled) {\n globallyEnabled = nextGloballyEnabled;\n if (!globallyEnabled) {\n if (client !== undefined && state !== undefined && state.phase !== 'inactive' && state.phase !== 'failed') {\n try {\n await client.stop();\n } catch {\n // The global opt-in is still authoritative even when remote cleanup fails.\n }\n }\n enabled = false;\n state = undefined;\n reconcileTools(false);\n }\n publishedMode = '';\n for (const listener of modeListeners) listener();\n }\n if (!globallyEnabled || client === undefined) {\n state = undefined;\n reconcileTools(false);\n publish();\n return;\n }\n try {\n const nextState = await client.state(signal);\n if (signal.aborted) return;\n state = nextState;\n reconcileTools(state.phase === 'active');\n publish();\n } catch {\n state = undefined;\n reconcileTools(false);\n publish();\n }\n };\n mode = defineMinorMode<undefined, MinorModeOwnerActionContext<ExtensionContext>>({\n descriptor: {\n source: PACKAGE_SOURCE,\n id: COMPUTER_USE_MODE_ID,\n label: 'Computer Use',\n description: 'Session-scoped semantic control through DoomPi Desktop.',\n order: 450,\n actions: [\n {\n id: 'activate',\n label: 'Activate',\n description: 'Open the cockpit activation workflow and native confirmation.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n {\n id: 'deactivate',\n label: 'Deactivate',\n description: 'Stop this session computer-use run.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n {\n id: 'doctor',\n label: 'Doctor',\n description: 'Report Desktop availability and session state.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n ],\n },\n state: () => modeState(state, enabled),\n async handleAction(_runtime, actionId, _argumentsValue, execution) {\n activeContext = execution.context;\n if (actionId === 'activate') {\n if ((await dependencies.enabled?.()) !== true) {\n await refresh();\n throw new Error('Enable computer use in global settings first.');\n }\n if (client === undefined) throw new Error('DoomPi Desktop computer use is unavailable.');\n enabled = true;\n await refresh();\n publish();\n return { message: 'Computer use is ready to configure in Activity.' };\n }\n if (actionId === 'doctor') {\n await refresh();\n return {\n message:\n client === undefined\n ? 'DoomPi Desktop session API is unavailable.'\n : `Computer use is ${state?.phase.replaceAll('_', ' ') ?? 'unavailable'}.`,\n };\n }\n if (actionId === 'deactivate') {\n if (client === undefined) throw new Error('DoomPi Desktop computer use is unavailable.');\n if (state !== undefined && state.phase !== 'inactive' && state.phase !== 'failed')\n await client.stop(execution.signal);\n enabled = false;\n await refresh();\n publish();\n return { message: 'Computer use is off.' };\n }\n throw new Error(`Unknown computer-use action: ${actionId}`);\n },\n }).createOwner(undefined);\n return {\n commands: [createComputerUseCommand(dependencies.service)],\n tools: [\n {\n name: 'computer_state',\n label: 'Computer State',\n description: 'Observe the authorized application window and return its semantic accessibility state.',\n promptSnippet: 'Observe the authorized application before choosing a semantic action',\n parameters: {\n type: 'object',\n properties: { includeScreenshot: { type: 'boolean' } },\n additionalProperties: false,\n },\n async execute(_toolCallId, _params, signal) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n const observation = await client.observe(signal, {\n includeScreenshot: (_params as { includeScreenshot?: boolean }).includeScreenshot !== false,\n });\n return computerObservationOutput(observation);\n },\n },\n {\n name: 'computer_action',\n label: 'Computer Action',\n description: 'Perform one constrained semantic action in the authorized application window.',\n promptSnippet: 'Perform one action using a current computer_state snapshot and element ref',\n parameters: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: ['press', 'focus', 'set_value', 'scroll'] },\n snapshotId: { type: 'string' },\n elementRef: { type: 'string' },\n value: { type: 'string' },\n direction: { type: 'string', enum: ['up', 'down', 'left', 'right'] },\n amount: { type: 'string', enum: ['line', 'page'] },\n },\n required: ['kind', 'snapshotId', 'elementRef'],\n additionalProperties: false,\n },\n async execute(_toolCallId, params, signal) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n const result = await client.act(params as unknown as ComputerUseAction, signal);\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], details: result };\n },\n },\n {\n name: 'computer_exec',\n label: 'Computer Script',\n description:\n 'Run a reusable function with the authorized program API. Full Node requires trusted:true and an explicitly allowlisted path.',\n promptSnippet:\n 'Compose small computer functions using fresh semantic observations; request screenshots only when needed',\n parameters: {\n type: 'object',\n properties: {\n scriptPath: { type: 'string' },\n input: {},\n trusted: { type: 'boolean' },\n includeScreenshot: { type: 'boolean' },\n },\n required: ['scriptPath', 'input'],\n additionalProperties: false,\n },\n async execute(_toolCallId, params, signal) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n if (dependencies.scriptRunner === undefined) throw new Error('Computer script execution is unavailable.');\n const input = params as { scriptPath: string; input: unknown } & ComputerScriptExecutionOptions;\n try {\n return computerScriptOutput(\n await dependencies.scriptRunner.execute(input.scriptPath, input.input, signal, input),\n );\n } catch (error) {\n return computerScriptFailure(error);\n }\n },\n },\n ],\n services: [\n piMinorModes({\n snapshot: () => (globallyEnabled && client !== undefined ? [mode] : []),\n subscribe(listener) {\n modeListeners.add(listener);\n return () => {\n modeListeners.delete(listener);\n };\n },\n }),\n ],\n toolRestrictions: [\n {\n source: PACKAGE_SOURCE,\n restrict: (incoming, available) => restriction(incoming, available),\n subscribe(listener) {\n restrictionListeners.add(listener);\n return () => {\n restrictionListeners.delete(listener);\n };\n },\n },\n ],\n events: {\n before_agent_start: (event) =>\n globallyEnabled && state?.phase === 'active'\n ? { systemPrompt: `${event.systemPrompt}\\n\\n${COMPUTER_USE_GUIDANCE}` }\n : undefined,\n session_start: (_event, context) => {\n if (signal.aborted) return;\n activeContext = context;\n reconcileTools(false);\n if (client === undefined) {\n publish();\n return;\n }\n void refresh();\n if (timer) clearInterval(timer);\n timer = setInterval(() => void refresh(), 250);\n timer.unref?.();\n },\n },\n onStop() {\n if (timer) clearInterval(timer);\n timer = undefined;\n },\n onDispose() {\n if (timer) clearInterval(timer);\n timer = undefined;\n reconcileTools(false);\n activeContext?.ui.setStatus(COMPUTER_USE_MODE_STATUS_KEY, undefined);\n activeContext?.ui.setStatus(COMPUTER_USE_STATUS_KEY, undefined);\n activeContext = undefined;\n },\n };\n}\n","import type { PiPluginContext, PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createComputerUseRuntime } from '../../../../../services/computerUseRuntime';\nimport { createComputerUseDependencies } from '../../../../../services/dependencies';\nimport type { ComputerUseExtensionDependencies } from '../../../../../types/extension';\n\nexport default (({ options, signal }) =>\n createComputerUseRuntime(options ?? createComputerUseDependencies(), signal)) satisfies (\n context: PiPluginContext<ComputerUseExtensionDependencies>,\n) => PiPluginContributions<ComputerUseExtensionDependencies>;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport runtime from './_runtime/index.cli';\n\nexport default defineRoot((context: Parameters<typeof runtime>[0]) => {\n const value = runtime(context);\n return {\n value,\n services: value.services,\n\n onStop: value.onStop,\n onDispose: value.onDispose,\n };\n});\n","import { defineCliCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliCommand((context: Context) => context.root.commands![0]!);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliHook((context: Context) => context.root.events!['before_agent_start']!);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliHook((context: Context) => context.root.events!['session_start']!);\n","import { defineToolRestriction, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineToolRestriction((context: Context) => context.root.toolRestrictions![0]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![0]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![1]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![2]!);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, piToolContributions, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandComputerUse from '../src/extensions/workspaces/sessions/(backend)/command/computer-use.cli';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli';\nimport toolRestrictionComputerUse from '../src/extensions/workspaces/sessions/(backend)/tool-restriction/computer-use.cli';\nimport tool00ComputerState from '../src/extensions/workspaces/sessions/(backend)/tool/00-computer-state.cli';\nimport tool10ComputerAction from '../src/extensions/workspaces/sessions/(backend)/tool/10-computer-action.cli';\nimport tool20ComputerExec from '../src/extensions/workspaces/sessions/(backend)/tool/20-computer-exec.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandComputerUse> | OptionsOf<typeof hookBeforeAgentStart> | OptionsOf<typeof hookSessionStart> | OptionsOf<typeof toolRestrictionComputerUse> | OptionsOf<typeof tool00ComputerState> | OptionsOf<typeof tool10ComputerAction> | OptionsOf<typeof tool20ComputerExec>, undefined>;\ntype Intersect<Union> =\n (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-computer-use', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): PiPluginContributions['commands'] { return [at(commandComputerUse, contextSession)]; },\n events: {\n before_agent_start: at(hookBeforeAgentStart, contextSession) as NonNullable<PiPluginContributions['events']>['before_agent_start'],\n session_start: at(hookSessionStart, contextSession) as NonNullable<PiPluginContributions['events']>['session_start'],\n },\n get toolRestrictions(): PiPluginContributions['toolRestrictions'] { return [at(toolRestrictionComputerUse, contextSession)]; },\n ...piToolContributions('@agimon-ai/doompi-computer-use', [via({ name: '00_computer_state' }, at(tool00ComputerState, contextSession)), via({ name: '10_computer_action' }, at(tool10ComputerAction, contextSession)), via({ name: '20_computer_exec' }, at(tool20ComputerExec, contextSession))]),\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pi.cjs","names":["COMMAND_NAME","COMMAND_DESCRIPTION","computerUseRestriction","COMPUTER_USE_MODE_STATUS_KEY","COMPUTER_USE_STATUS_KEY","defineMinorMode","COMPUTER_USE_MODE_ID","modeState","computerObservationOutput","computerScriptOutput","computerScriptFailure","piMinorModes","COMPUTER_USE_GUIDANCE","createComputerUseDependencies","defineRoot","runtime","defineCliCommand","defineCliHook","defineCliHook","defineToolRestriction","defineCliTool","defineCliTool","defineCliTool","definePiExtension","rootSession","composeRootHooks","commandComputerUse","hookBeforeAgentStart","hookSessionStart","toolRestrictionComputerUse","piToolContributions","tool00ComputerState","tool10ComputerAction","tool20ComputerExec"],"sources":["../../src/services/computerUseCommand/index.ts","../../src/services/computerUseRuntime/index.ts","../../src/extensions/workspaces/sessions/(backend)/_runtime/index.cli.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/computer-use.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool-restriction/computer-use.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/00-computer-state.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/10-computer-action.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/20-computer-exec.cli.ts","../../generated/pi.ts"],"sourcesContent":["// @scaffold-generated\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../constants/computerUse';\nimport type { ComputerUseExtensionService } from '../../types/extension';\n\nexport function createComputerUseCommand(\n service: ComputerUseExtensionService,\n): Parameters<ExtensionAPI['registerCommand']> {\n return [\n COMMAND_NAME,\n {\n description: COMMAND_DESCRIPTION,\n handler: async (_args, ctx) => {\n const result = await service.execute();\n if (ctx.hasUI) ctx.ui.notify(result.message, result.level);\n },\n },\n ];\n}\n\nexport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../constants/computerUse';\n","import { type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { type DoomToolRestriction } from '@agimon-ai/doompi-core/toolSurface';\nimport { piMinorModes } from '@agimon-ai/doompi-minor-mode';\nimport { defineMinorMode, type MinorModeOwner, type MinorModeOwnerActionContext } from '@agimon-ai/doompi-minor-mode';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport { COMPUTER_USE_GUIDANCE } from '../../constants/computerUse';\nimport type { ComputerScriptExecutionOptions } from '../../types/computerScript';\nimport type { ComputerUseAction } from '../../types/computerUse';\nimport {\n COMPUTER_USE_MODE_ID,\n COMPUTER_USE_MODE_STATUS_KEY,\n COMPUTER_USE_STATUS_KEY,\n type ComputerUseSessionView,\n} from '../../types/computerUseApi';\nimport type { ComputerUseExtensionDependencies } from '../../types/extension';\nimport { computerObservationOutput, computerScriptOutput, computerScriptFailure } from '../computerToolOutput';\nimport { createComputerUseCommand } from '../computerUseCommand';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-computer-use';\nexport { COMPUTER_USE_MODE_ID };\nimport { modeState, computerUseRestriction } from '../../models/computerUseMode';\n\nexport function createComputerUseRuntime(\n dependencies: ComputerUseExtensionDependencies,\n signal: AbortSignal,\n): PiPluginContributions<ComputerUseExtensionDependencies> & {\n tools: readonly Parameters<ExtensionAPI['registerTool']>[0][];\n} {\n const client = dependencies.client;\n let state: ComputerUseSessionView | undefined;\n let enabled = false;\n let restriction: DoomToolRestriction = computerUseRestriction(false);\n const restrictionListeners = new Set<() => void>();\n const reconcileTools = (active: boolean): void => {\n restriction = computerUseRestriction(active);\n for (const listener of restrictionListeners) listener();\n };\n let globallyEnabled = false;\n let mode: MinorModeOwner<MinorModeOwnerActionContext<ExtensionContext>>;\n const modeListeners = new Set<() => void>();\n let timer: ReturnType<typeof setInterval> | undefined;\n let activeContext: ExtensionContext | undefined;\n let publishedMode = '';\n let publishedModeStatus: string | undefined;\n let publishedActivityStatus: string | undefined;\n const publish = (): void => {\n const phase = state?.phase ?? 'inactive';\n const projection = `${enabled}:${phase}:${state?.revision ?? 'none'}`;\n if (mode !== undefined && projection !== publishedMode) {\n mode.publish();\n publishedMode = projection;\n }\n const modeStatus = state === undefined ? undefined : enabled || phase !== 'inactive' ? phase : '';\n if (activeContext !== undefined && modeStatus !== publishedModeStatus) {\n activeContext.ui.setStatus(COMPUTER_USE_MODE_STATUS_KEY, modeStatus);\n publishedModeStatus = modeStatus;\n }\n const activityStatus = enabled || phase !== 'inactive' ? `computer use: ${phase}` : undefined;\n if (activeContext !== undefined && activityStatus !== publishedActivityStatus) {\n activeContext.ui.setStatus(COMPUTER_USE_STATUS_KEY, activityStatus);\n publishedActivityStatus = activityStatus;\n }\n };\n const refresh = async (): Promise<void> => {\n if (signal.aborted) return;\n let nextGloballyEnabled = false;\n try {\n nextGloballyEnabled = (await dependencies.enabled?.(activeContext?.cwd)) === true;\n } catch {\n nextGloballyEnabled = false;\n }\n if (signal.aborted) return;\n if (nextGloballyEnabled !== globallyEnabled) {\n globallyEnabled = nextGloballyEnabled;\n if (!globallyEnabled) {\n if (client !== undefined && state !== undefined && state.phase !== 'inactive' && state.phase !== 'failed') {\n try {\n await client.stop();\n } catch {\n // The global opt-in is still authoritative even when remote cleanup fails.\n }\n }\n enabled = false;\n state = undefined;\n reconcileTools(false);\n }\n publishedMode = '';\n for (const listener of modeListeners) listener();\n }\n if (!globallyEnabled || client === undefined) {\n state = undefined;\n reconcileTools(false);\n publish();\n return;\n }\n try {\n const nextState = await client.state(signal);\n if (signal.aborted) return;\n state = nextState;\n reconcileTools(state.phase === 'active');\n publish();\n } catch {\n state = undefined;\n reconcileTools(false);\n publish();\n }\n };\n mode = defineMinorMode<undefined, MinorModeOwnerActionContext<ExtensionContext>>({\n descriptor: {\n source: PACKAGE_SOURCE,\n id: COMPUTER_USE_MODE_ID,\n label: 'Computer Use',\n description: 'Session-scoped semantic control through DoomPi Desktop.',\n order: 450,\n actions: [\n {\n id: 'activate',\n label: 'Activate',\n description: 'Open the cockpit activation workflow and native confirmation.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n {\n id: 'deactivate',\n label: 'Deactivate',\n description: 'Stop this session computer-use run.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n {\n id: 'doctor',\n label: 'Doctor',\n description: 'Report Desktop availability and session state.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n ],\n },\n state: () => modeState(state, enabled),\n async handleAction(_runtime, actionId, _argumentsValue, execution) {\n activeContext = execution.context;\n if (actionId === 'activate') {\n if ((await dependencies.enabled?.(execution.context.cwd)) !== true) {\n await refresh();\n throw new Error('Enable computer use in global settings first.');\n }\n if (client === undefined) throw new Error('DoomPi Desktop computer use is unavailable.');\n enabled = true;\n await refresh();\n publish();\n return { message: 'Computer use is ready to configure in Activity.' };\n }\n if (actionId === 'doctor') {\n await refresh();\n return {\n message:\n client === undefined\n ? 'DoomPi Desktop session API is unavailable.'\n : `Computer use is ${state?.phase.replaceAll('_', ' ') ?? 'unavailable'}.`,\n };\n }\n if (actionId === 'deactivate') {\n if (client === undefined) throw new Error('DoomPi Desktop computer use is unavailable.');\n if (state !== undefined && state.phase !== 'inactive' && state.phase !== 'failed')\n await client.stop(execution.signal);\n enabled = false;\n await refresh();\n publish();\n return { message: 'Computer use is off.' };\n }\n throw new Error(`Unknown computer-use action: ${actionId}`);\n },\n }).createOwner(undefined);\n return {\n commands: [createComputerUseCommand(dependencies.service)],\n tools: [\n {\n name: 'computer_state',\n label: 'Computer State',\n description: 'Observe the authorized application window and return its semantic accessibility state.',\n promptSnippet: 'Observe the authorized application before choosing a semantic action',\n parameters: {\n type: 'object',\n properties: { includeScreenshot: { type: 'boolean' } },\n additionalProperties: false,\n },\n async execute(_toolCallId, _params, signal) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n const observation = await client.observe(signal, {\n includeScreenshot: (_params as { includeScreenshot?: boolean }).includeScreenshot !== false,\n });\n return computerObservationOutput(observation);\n },\n },\n {\n name: 'computer_action',\n label: 'Computer Action',\n description: 'Perform one constrained semantic action in the authorized application window.',\n promptSnippet: 'Perform one action using a current computer_state snapshot and element ref',\n parameters: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: ['press', 'focus', 'set_value', 'scroll'] },\n snapshotId: { type: 'string' },\n elementRef: { type: 'string' },\n value: { type: 'string' },\n direction: { type: 'string', enum: ['up', 'down', 'left', 'right'] },\n amount: { type: 'string', enum: ['line', 'page'] },\n },\n required: ['kind', 'snapshotId', 'elementRef'],\n additionalProperties: false,\n },\n async execute(_toolCallId, params, signal) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n const result = await client.act(params as unknown as ComputerUseAction, signal);\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], details: result };\n },\n },\n {\n name: 'computer_exec',\n label: 'Computer Script',\n description:\n 'Run a reusable function with the authorized program API. Full Node requires trusted:true and an explicitly allowlisted path.',\n promptSnippet:\n 'Compose small computer functions using fresh semantic observations; request screenshots only when needed',\n parameters: {\n type: 'object',\n properties: {\n scriptPath: { type: 'string' },\n input: {},\n trusted: { type: 'boolean' },\n includeScreenshot: { type: 'boolean' },\n },\n required: ['scriptPath', 'input'],\n additionalProperties: false,\n },\n async execute(_toolCallId, params, signal, _onUpdate, context) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n if (dependencies.scriptRunner === undefined) throw new Error('Computer script execution is unavailable.');\n const input = params as { scriptPath: string; input: unknown } & ComputerScriptExecutionOptions;\n try {\n return computerScriptOutput(\n await dependencies.scriptRunner.execute(input.scriptPath, input.input, signal, input, context.cwd),\n );\n } catch (error) {\n return computerScriptFailure(error);\n }\n },\n },\n ],\n services: [\n piMinorModes({\n snapshot: () => (globallyEnabled && client !== undefined ? [mode] : []),\n subscribe(listener) {\n modeListeners.add(listener);\n return () => {\n modeListeners.delete(listener);\n };\n },\n }),\n ],\n toolRestrictions: [\n {\n source: PACKAGE_SOURCE,\n restrict: (incoming, available) => restriction(incoming, available),\n subscribe(listener) {\n restrictionListeners.add(listener);\n return () => {\n restrictionListeners.delete(listener);\n };\n },\n },\n ],\n events: {\n before_agent_start: (event) =>\n globallyEnabled && state?.phase === 'active'\n ? { systemPrompt: `${event.systemPrompt}\\n\\n${COMPUTER_USE_GUIDANCE}` }\n : undefined,\n session_start: (_event, context) => {\n if (signal.aborted) return;\n activeContext = context;\n reconcileTools(false);\n if (client === undefined) {\n publish();\n return;\n }\n void refresh();\n if (timer) clearInterval(timer);\n timer = setInterval(() => void refresh(), 250);\n timer.unref?.();\n },\n },\n onStop() {\n if (timer) clearInterval(timer);\n timer = undefined;\n },\n onDispose() {\n if (timer) clearInterval(timer);\n timer = undefined;\n reconcileTools(false);\n activeContext?.ui.setStatus(COMPUTER_USE_MODE_STATUS_KEY, undefined);\n activeContext?.ui.setStatus(COMPUTER_USE_STATUS_KEY, undefined);\n activeContext = undefined;\n },\n };\n}\n","import type { PiPluginContext, PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createComputerUseRuntime } from '../../../../../services/computerUseRuntime';\nimport { createComputerUseDependencies } from '../../../../../services/dependencies';\nimport type { ComputerUseExtensionDependencies } from '../../../../../types/extension';\n\nexport default (({ options, signal }) =>\n createComputerUseRuntime(options ?? createComputerUseDependencies(), signal)) satisfies (\n context: PiPluginContext<ComputerUseExtensionDependencies>,\n) => PiPluginContributions<ComputerUseExtensionDependencies>;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport runtime from './_runtime/index.cli';\n\nexport default defineRoot((context: Parameters<typeof runtime>[0]) => {\n const value = runtime(context);\n return {\n value,\n services: value.services,\n\n onStop: value.onStop,\n onDispose: value.onDispose,\n };\n});\n","import { defineCliCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliCommand((context: Context) => context.root.commands![0]!);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliHook((context: Context) => context.root.events!['before_agent_start']!);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliHook((context: Context) => context.root.events!['session_start']!);\n","import { defineToolRestriction, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineToolRestriction((context: Context) => context.root.toolRestrictions![0]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![0]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![1]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![2]!);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, piToolContributions, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandComputerUse from '../src/extensions/workspaces/sessions/(backend)/command/computer-use.cli';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli';\nimport toolRestrictionComputerUse from '../src/extensions/workspaces/sessions/(backend)/tool-restriction/computer-use.cli';\nimport tool00ComputerState from '../src/extensions/workspaces/sessions/(backend)/tool/00-computer-state.cli';\nimport tool10ComputerAction from '../src/extensions/workspaces/sessions/(backend)/tool/10-computer-action.cli';\nimport tool20ComputerExec from '../src/extensions/workspaces/sessions/(backend)/tool/20-computer-exec.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandComputerUse> | OptionsOf<typeof hookBeforeAgentStart> | OptionsOf<typeof hookSessionStart> | OptionsOf<typeof toolRestrictionComputerUse> | OptionsOf<typeof tool00ComputerState> | OptionsOf<typeof tool10ComputerAction> | OptionsOf<typeof tool20ComputerExec>, undefined>;\ntype Intersect<Union> =\n (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-computer-use', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): PiPluginContributions['commands'] { return [at(commandComputerUse, contextSession)]; },\n events: {\n before_agent_start: at(hookBeforeAgentStart, contextSession) as NonNullable<PiPluginContributions['events']>['before_agent_start'],\n session_start: at(hookSessionStart, contextSession) as NonNullable<PiPluginContributions['events']>['session_start'],\n },\n get toolRestrictions(): PiPluginContributions['toolRestrictions'] { return [at(toolRestrictionComputerUse, contextSession)]; },\n ...piToolContributions('@agimon-ai/doompi-computer-use', [via({ name: '00_computer_state' }, at(tool00ComputerState, contextSession)), via({ name: '10_computer_action' }, at(tool10ComputerAction, contextSession)), via({ name: '20_computer_exec' }, at(tool20ComputerExec, contextSession))]),\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":"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"}
|
package/dist/extensions/pi.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as ComputerUseExtensionDependencies } from "../index-
|
|
1
|
+
import { c as ComputerUseExtensionDependencies } from "../index-DoKasntC.mjs";
|
|
2
2
|
//#region generated/pi.d.ts
|
|
3
3
|
export declare const extension: import("@agimon-ai/doompi-core/runtimePiExtension").DefinedPiExtension<ComputerUseExtensionDependencies>;
|
|
4
4
|
//#endregion
|
package/dist/extensions/pi.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as COMMAND_NAME, i as COMMAND_DESCRIPTION, o as COMPUTER_USE_GUIDANCE } from "../extensionService-
|
|
2
|
-
import { n as createComputerUseDependencies } from "../dependencies-
|
|
3
|
-
import { a as computerScriptOutput, f as COMPUTER_USE_STATUS_KEY, i as computerScriptFailure, l as COMPUTER_USE_MODE_ID, n as modeState, r as computerObservationOutput, t as computerUseRestriction, u as COMPUTER_USE_MODE_STATUS_KEY } from "../computerUseMode-
|
|
1
|
+
import { a as COMMAND_NAME, i as COMMAND_DESCRIPTION, o as COMPUTER_USE_GUIDANCE } from "../extensionService-BSqhP2uB.mjs";
|
|
2
|
+
import { n as createComputerUseDependencies } from "../dependencies-ChuvtRxU.mjs";
|
|
3
|
+
import { a as computerScriptOutput, f as COMPUTER_USE_STATUS_KEY, i as computerScriptFailure, l as COMPUTER_USE_MODE_ID, n as modeState, r as computerObservationOutput, t as computerUseRestriction, u as COMPUTER_USE_MODE_STATUS_KEY } from "../computerUseMode-C1r5mG7K.mjs";
|
|
4
4
|
import { definePiExtension, piToolContributions } from "@agimon-ai/doompi-core/piExtension";
|
|
5
5
|
import { composeRootHooks, defineCliCommand, defineCliHook, defineCliTool, defineRoot, defineToolRestriction } from "@agimon-ai/doompi-core/extensionFile";
|
|
6
6
|
import { defineMinorMode, piMinorModes } from "@agimon-ai/doompi-minor-mode";
|
|
@@ -57,7 +57,7 @@ function createComputerUseRuntime(dependencies, signal) {
|
|
|
57
57
|
if (signal.aborted) return;
|
|
58
58
|
let nextGloballyEnabled = false;
|
|
59
59
|
try {
|
|
60
|
-
nextGloballyEnabled = await dependencies.enabled?.() === true;
|
|
60
|
+
nextGloballyEnabled = await dependencies.enabled?.(activeContext?.cwd) === true;
|
|
61
61
|
} catch {
|
|
62
62
|
nextGloballyEnabled = false;
|
|
63
63
|
}
|
|
@@ -128,7 +128,7 @@ function createComputerUseRuntime(dependencies, signal) {
|
|
|
128
128
|
async handleAction(_runtime, actionId, _argumentsValue, execution) {
|
|
129
129
|
activeContext = execution.context;
|
|
130
130
|
if (actionId === "activate") {
|
|
131
|
-
if (await dependencies.enabled?.() !== true) {
|
|
131
|
+
if (await dependencies.enabled?.(execution.context.cwd) !== true) {
|
|
132
132
|
await refresh();
|
|
133
133
|
throw new Error("Enable computer use in global settings first.");
|
|
134
134
|
}
|
|
@@ -241,12 +241,12 @@ function createComputerUseRuntime(dependencies, signal) {
|
|
|
241
241
|
required: ["scriptPath", "input"],
|
|
242
242
|
additionalProperties: false
|
|
243
243
|
},
|
|
244
|
-
async execute(_toolCallId, params, signal) {
|
|
244
|
+
async execute(_toolCallId, params, signal, _onUpdate, context) {
|
|
245
245
|
if (!globallyEnabled || client === void 0 || state?.phase !== "active") throw new Error("Computer use is not active for this session.");
|
|
246
246
|
if (dependencies.scriptRunner === void 0) throw new Error("Computer script execution is unavailable.");
|
|
247
247
|
const input = params;
|
|
248
248
|
try {
|
|
249
|
-
return computerScriptOutput(await dependencies.scriptRunner.execute(input.scriptPath, input.input, signal, input));
|
|
249
|
+
return computerScriptOutput(await dependencies.scriptRunner.execute(input.scriptPath, input.input, signal, input, context.cwd));
|
|
250
250
|
} catch (error) {
|
|
251
251
|
return computerScriptFailure(error);
|
|
252
252
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.mjs","names":["runtime","rootSession","commandComputerUse","hookBeforeAgentStart","hookSessionStart","toolRestrictionComputerUse","tool00ComputerState","tool10ComputerAction","tool20ComputerExec"],"sources":["../../src/services/computerUseCommand/index.ts","../../src/services/computerUseRuntime/index.ts","../../src/extensions/workspaces/sessions/(backend)/_runtime/index.cli.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/computer-use.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool-restriction/computer-use.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/00-computer-state.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/10-computer-action.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/20-computer-exec.cli.ts","../../generated/pi.ts"],"sourcesContent":["// @scaffold-generated\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../constants/computerUse';\nimport type { ComputerUseExtensionService } from '../../types/extension';\n\nexport function createComputerUseCommand(\n service: ComputerUseExtensionService,\n): Parameters<ExtensionAPI['registerCommand']> {\n return [\n COMMAND_NAME,\n {\n description: COMMAND_DESCRIPTION,\n handler: async (_args, ctx) => {\n const result = await service.execute();\n if (ctx.hasUI) ctx.ui.notify(result.message, result.level);\n },\n },\n ];\n}\n\nexport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../constants/computerUse';\n","import { type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { type DoomToolRestriction } from '@agimon-ai/doompi-core/toolSurface';\nimport { piMinorModes } from '@agimon-ai/doompi-minor-mode';\nimport { defineMinorMode, type MinorModeOwner, type MinorModeOwnerActionContext } from '@agimon-ai/doompi-minor-mode';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport { COMPUTER_USE_GUIDANCE } from '../../constants/computerUse';\nimport type { ComputerScriptExecutionOptions } from '../../types/computerScript';\nimport type { ComputerUseAction } from '../../types/computerUse';\nimport {\n COMPUTER_USE_MODE_ID,\n COMPUTER_USE_MODE_STATUS_KEY,\n COMPUTER_USE_STATUS_KEY,\n type ComputerUseSessionView,\n} from '../../types/computerUseApi';\nimport type { ComputerUseExtensionDependencies } from '../../types/extension';\nimport { computerObservationOutput, computerScriptOutput, computerScriptFailure } from '../computerToolOutput';\nimport { createComputerUseCommand } from '../computerUseCommand';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-computer-use';\nexport { COMPUTER_USE_MODE_ID };\nimport { modeState, computerUseRestriction } from '../../models/computerUseMode';\n\nexport function createComputerUseRuntime(\n dependencies: ComputerUseExtensionDependencies,\n signal: AbortSignal,\n): PiPluginContributions<ComputerUseExtensionDependencies> & {\n tools: readonly Parameters<ExtensionAPI['registerTool']>[0][];\n} {\n const client = dependencies.client;\n let state: ComputerUseSessionView | undefined;\n let enabled = false;\n let restriction: DoomToolRestriction = computerUseRestriction(false);\n const restrictionListeners = new Set<() => void>();\n const reconcileTools = (active: boolean): void => {\n restriction = computerUseRestriction(active);\n for (const listener of restrictionListeners) listener();\n };\n let globallyEnabled = false;\n let mode: MinorModeOwner<MinorModeOwnerActionContext<ExtensionContext>>;\n const modeListeners = new Set<() => void>();\n let timer: ReturnType<typeof setInterval> | undefined;\n let activeContext: ExtensionContext | undefined;\n let publishedMode = '';\n let publishedModeStatus: string | undefined;\n let publishedActivityStatus: string | undefined;\n const publish = (): void => {\n const phase = state?.phase ?? 'inactive';\n const projection = `${enabled}:${phase}:${state?.revision ?? 'none'}`;\n if (mode !== undefined && projection !== publishedMode) {\n mode.publish();\n publishedMode = projection;\n }\n const modeStatus = state === undefined ? undefined : enabled || phase !== 'inactive' ? phase : '';\n if (activeContext !== undefined && modeStatus !== publishedModeStatus) {\n activeContext.ui.setStatus(COMPUTER_USE_MODE_STATUS_KEY, modeStatus);\n publishedModeStatus = modeStatus;\n }\n const activityStatus = enabled || phase !== 'inactive' ? `computer use: ${phase}` : undefined;\n if (activeContext !== undefined && activityStatus !== publishedActivityStatus) {\n activeContext.ui.setStatus(COMPUTER_USE_STATUS_KEY, activityStatus);\n publishedActivityStatus = activityStatus;\n }\n };\n const refresh = async (): Promise<void> => {\n if (signal.aborted) return;\n let nextGloballyEnabled = false;\n try {\n nextGloballyEnabled = (await dependencies.enabled?.()) === true;\n } catch {\n nextGloballyEnabled = false;\n }\n if (signal.aborted) return;\n if (nextGloballyEnabled !== globallyEnabled) {\n globallyEnabled = nextGloballyEnabled;\n if (!globallyEnabled) {\n if (client !== undefined && state !== undefined && state.phase !== 'inactive' && state.phase !== 'failed') {\n try {\n await client.stop();\n } catch {\n // The global opt-in is still authoritative even when remote cleanup fails.\n }\n }\n enabled = false;\n state = undefined;\n reconcileTools(false);\n }\n publishedMode = '';\n for (const listener of modeListeners) listener();\n }\n if (!globallyEnabled || client === undefined) {\n state = undefined;\n reconcileTools(false);\n publish();\n return;\n }\n try {\n const nextState = await client.state(signal);\n if (signal.aborted) return;\n state = nextState;\n reconcileTools(state.phase === 'active');\n publish();\n } catch {\n state = undefined;\n reconcileTools(false);\n publish();\n }\n };\n mode = defineMinorMode<undefined, MinorModeOwnerActionContext<ExtensionContext>>({\n descriptor: {\n source: PACKAGE_SOURCE,\n id: COMPUTER_USE_MODE_ID,\n label: 'Computer Use',\n description: 'Session-scoped semantic control through DoomPi Desktop.',\n order: 450,\n actions: [\n {\n id: 'activate',\n label: 'Activate',\n description: 'Open the cockpit activation workflow and native confirmation.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n {\n id: 'deactivate',\n label: 'Deactivate',\n description: 'Stop this session computer-use run.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n {\n id: 'doctor',\n label: 'Doctor',\n description: 'Report Desktop availability and session state.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n ],\n },\n state: () => modeState(state, enabled),\n async handleAction(_runtime, actionId, _argumentsValue, execution) {\n activeContext = execution.context;\n if (actionId === 'activate') {\n if ((await dependencies.enabled?.()) !== true) {\n await refresh();\n throw new Error('Enable computer use in global settings first.');\n }\n if (client === undefined) throw new Error('DoomPi Desktop computer use is unavailable.');\n enabled = true;\n await refresh();\n publish();\n return { message: 'Computer use is ready to configure in Activity.' };\n }\n if (actionId === 'doctor') {\n await refresh();\n return {\n message:\n client === undefined\n ? 'DoomPi Desktop session API is unavailable.'\n : `Computer use is ${state?.phase.replaceAll('_', ' ') ?? 'unavailable'}.`,\n };\n }\n if (actionId === 'deactivate') {\n if (client === undefined) throw new Error('DoomPi Desktop computer use is unavailable.');\n if (state !== undefined && state.phase !== 'inactive' && state.phase !== 'failed')\n await client.stop(execution.signal);\n enabled = false;\n await refresh();\n publish();\n return { message: 'Computer use is off.' };\n }\n throw new Error(`Unknown computer-use action: ${actionId}`);\n },\n }).createOwner(undefined);\n return {\n commands: [createComputerUseCommand(dependencies.service)],\n tools: [\n {\n name: 'computer_state',\n label: 'Computer State',\n description: 'Observe the authorized application window and return its semantic accessibility state.',\n promptSnippet: 'Observe the authorized application before choosing a semantic action',\n parameters: {\n type: 'object',\n properties: { includeScreenshot: { type: 'boolean' } },\n additionalProperties: false,\n },\n async execute(_toolCallId, _params, signal) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n const observation = await client.observe(signal, {\n includeScreenshot: (_params as { includeScreenshot?: boolean }).includeScreenshot !== false,\n });\n return computerObservationOutput(observation);\n },\n },\n {\n name: 'computer_action',\n label: 'Computer Action',\n description: 'Perform one constrained semantic action in the authorized application window.',\n promptSnippet: 'Perform one action using a current computer_state snapshot and element ref',\n parameters: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: ['press', 'focus', 'set_value', 'scroll'] },\n snapshotId: { type: 'string' },\n elementRef: { type: 'string' },\n value: { type: 'string' },\n direction: { type: 'string', enum: ['up', 'down', 'left', 'right'] },\n amount: { type: 'string', enum: ['line', 'page'] },\n },\n required: ['kind', 'snapshotId', 'elementRef'],\n additionalProperties: false,\n },\n async execute(_toolCallId, params, signal) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n const result = await client.act(params as unknown as ComputerUseAction, signal);\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], details: result };\n },\n },\n {\n name: 'computer_exec',\n label: 'Computer Script',\n description:\n 'Run a reusable function with the authorized program API. Full Node requires trusted:true and an explicitly allowlisted path.',\n promptSnippet:\n 'Compose small computer functions using fresh semantic observations; request screenshots only when needed',\n parameters: {\n type: 'object',\n properties: {\n scriptPath: { type: 'string' },\n input: {},\n trusted: { type: 'boolean' },\n includeScreenshot: { type: 'boolean' },\n },\n required: ['scriptPath', 'input'],\n additionalProperties: false,\n },\n async execute(_toolCallId, params, signal) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n if (dependencies.scriptRunner === undefined) throw new Error('Computer script execution is unavailable.');\n const input = params as { scriptPath: string; input: unknown } & ComputerScriptExecutionOptions;\n try {\n return computerScriptOutput(\n await dependencies.scriptRunner.execute(input.scriptPath, input.input, signal, input),\n );\n } catch (error) {\n return computerScriptFailure(error);\n }\n },\n },\n ],\n services: [\n piMinorModes({\n snapshot: () => (globallyEnabled && client !== undefined ? [mode] : []),\n subscribe(listener) {\n modeListeners.add(listener);\n return () => {\n modeListeners.delete(listener);\n };\n },\n }),\n ],\n toolRestrictions: [\n {\n source: PACKAGE_SOURCE,\n restrict: (incoming, available) => restriction(incoming, available),\n subscribe(listener) {\n restrictionListeners.add(listener);\n return () => {\n restrictionListeners.delete(listener);\n };\n },\n },\n ],\n events: {\n before_agent_start: (event) =>\n globallyEnabled && state?.phase === 'active'\n ? { systemPrompt: `${event.systemPrompt}\\n\\n${COMPUTER_USE_GUIDANCE}` }\n : undefined,\n session_start: (_event, context) => {\n if (signal.aborted) return;\n activeContext = context;\n reconcileTools(false);\n if (client === undefined) {\n publish();\n return;\n }\n void refresh();\n if (timer) clearInterval(timer);\n timer = setInterval(() => void refresh(), 250);\n timer.unref?.();\n },\n },\n onStop() {\n if (timer) clearInterval(timer);\n timer = undefined;\n },\n onDispose() {\n if (timer) clearInterval(timer);\n timer = undefined;\n reconcileTools(false);\n activeContext?.ui.setStatus(COMPUTER_USE_MODE_STATUS_KEY, undefined);\n activeContext?.ui.setStatus(COMPUTER_USE_STATUS_KEY, undefined);\n activeContext = undefined;\n },\n };\n}\n","import type { PiPluginContext, PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createComputerUseRuntime } from '../../../../../services/computerUseRuntime';\nimport { createComputerUseDependencies } from '../../../../../services/dependencies';\nimport type { ComputerUseExtensionDependencies } from '../../../../../types/extension';\n\nexport default (({ options, signal }) =>\n createComputerUseRuntime(options ?? createComputerUseDependencies(), signal)) satisfies (\n context: PiPluginContext<ComputerUseExtensionDependencies>,\n) => PiPluginContributions<ComputerUseExtensionDependencies>;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport runtime from './_runtime/index.cli';\n\nexport default defineRoot((context: Parameters<typeof runtime>[0]) => {\n const value = runtime(context);\n return {\n value,\n services: value.services,\n\n onStop: value.onStop,\n onDispose: value.onDispose,\n };\n});\n","import { defineCliCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliCommand((context: Context) => context.root.commands![0]!);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliHook((context: Context) => context.root.events!['before_agent_start']!);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliHook((context: Context) => context.root.events!['session_start']!);\n","import { defineToolRestriction, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineToolRestriction((context: Context) => context.root.toolRestrictions![0]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![0]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![1]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![2]!);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, piToolContributions, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandComputerUse from '../src/extensions/workspaces/sessions/(backend)/command/computer-use.cli';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli';\nimport toolRestrictionComputerUse from '../src/extensions/workspaces/sessions/(backend)/tool-restriction/computer-use.cli';\nimport tool00ComputerState from '../src/extensions/workspaces/sessions/(backend)/tool/00-computer-state.cli';\nimport tool10ComputerAction from '../src/extensions/workspaces/sessions/(backend)/tool/10-computer-action.cli';\nimport tool20ComputerExec from '../src/extensions/workspaces/sessions/(backend)/tool/20-computer-exec.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandComputerUse> | OptionsOf<typeof hookBeforeAgentStart> | OptionsOf<typeof hookSessionStart> | OptionsOf<typeof toolRestrictionComputerUse> | OptionsOf<typeof tool00ComputerState> | OptionsOf<typeof tool10ComputerAction> | OptionsOf<typeof tool20ComputerExec>, undefined>;\ntype Intersect<Union> =\n (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-computer-use', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): PiPluginContributions['commands'] { return [at(commandComputerUse, contextSession)]; },\n events: {\n before_agent_start: at(hookBeforeAgentStart, contextSession) as NonNullable<PiPluginContributions['events']>['before_agent_start'],\n session_start: at(hookSessionStart, contextSession) as NonNullable<PiPluginContributions['events']>['session_start'],\n },\n get toolRestrictions(): PiPluginContributions['toolRestrictions'] { return [at(toolRestrictionComputerUse, contextSession)]; },\n ...piToolContributions('@agimon-ai/doompi-computer-use', [via({ name: '00_computer_state' }, at(tool00ComputerState, contextSession)), via({ name: '10_computer_action' }, at(tool10ComputerAction, contextSession)), via({ name: '20_computer_exec' }, at(tool20ComputerExec, contextSession))]),\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":";;;;;;;AAMA,SAAgB,yBACd,SAC6C;CAC7C,OAAO,CACL,cACA;EACE,aAAa;EACb,SAAS,OAAO,OAAO,QAAQ;GAC7B,MAAM,SAAS,MAAM,QAAQ,QAAQ;GACrC,IAAI,IAAI,OAAO,IAAI,GAAG,OAAO,OAAO,SAAS,OAAO,KAAK;EAC3D;CACF,CACF;AACF;;;ACAA,MAAM,iBAAiB;AAIvB,SAAgB,yBACd,cACA,QAGA;CACA,MAAM,SAAS,aAAa;CAC5B,IAAI;CACJ,IAAI,UAAU;CACd,IAAI,cAAmC,uBAAuB,KAAK;CACnE,MAAM,uCAAuB,IAAI,IAAgB;CACjD,MAAM,kBAAkB,WAA0B;EAChD,cAAc,uBAAuB,MAAM;EAC3C,KAAK,MAAM,YAAY,sBAAsB,SAAS;CACxD;CACA,IAAI,kBAAkB;CACtB,IAAI;CACJ,MAAM,gCAAgB,IAAI,IAAgB;CAC1C,IAAI;CACJ,IAAI;CACJ,IAAI,gBAAgB;CACpB,IAAI;CACJ,IAAI;CACJ,MAAM,gBAAsB;EAC1B,MAAM,QAAQ,OAAO,SAAS;EAC9B,MAAM,aAAa,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,YAAY;EAC7D,IAAI,SAAS,KAAA,KAAa,eAAe,eAAe;GACtD,KAAK,QAAQ;GACb,gBAAgB;EAClB;EACA,MAAM,aAAa,UAAU,KAAA,IAAY,KAAA,IAAY,WAAW,UAAU,aAAa,QAAQ;EAC/F,IAAI,kBAAkB,KAAA,KAAa,eAAe,qBAAqB;GACrE,cAAc,GAAG,UAAU,8BAA8B,UAAU;GACnE,sBAAsB;EACxB;EACA,MAAM,iBAAiB,WAAW,UAAU,aAAa,iBAAiB,UAAU,KAAA;EACpF,IAAI,kBAAkB,KAAA,KAAa,mBAAmB,yBAAyB;GAC7E,cAAc,GAAG,UAAU,yBAAyB,cAAc;GAClE,0BAA0B;EAC5B;CACF;CACA,MAAM,UAAU,YAA2B;EACzC,IAAI,OAAO,SAAS;EACpB,IAAI,sBAAsB;EAC1B,IAAI;GACF,sBAAuB,MAAM,aAAa,UAAU,MAAO;EAC7D,QAAQ;GACN,sBAAsB;EACxB;EACA,IAAI,OAAO,SAAS;EACpB,IAAI,wBAAwB,iBAAiB;GAC3C,kBAAkB;GAClB,IAAI,CAAC,iBAAiB;IACpB,IAAI,WAAW,KAAA,KAAa,UAAU,KAAA,KAAa,MAAM,UAAU,cAAc,MAAM,UAAU,UAC/F,IAAI;KACF,MAAM,OAAO,KAAK;IACpB,QAAQ,CAER;IAEF,UAAU;IACV,QAAQ,KAAA;IACR,eAAe,KAAK;GACtB;GACA,gBAAgB;GAChB,KAAK,MAAM,YAAY,eAAe,SAAS;EACjD;EACA,IAAI,CAAC,mBAAmB,WAAW,KAAA,GAAW;GAC5C,QAAQ,KAAA;GACR,eAAe,KAAK;GACpB,QAAQ;GACR;EACF;EACA,IAAI;GACF,MAAM,YAAY,MAAM,OAAO,MAAM,MAAM;GAC3C,IAAI,OAAO,SAAS;GACpB,QAAQ;GACR,eAAe,MAAM,UAAU,QAAQ;GACvC,QAAQ;EACV,QAAQ;GACN,QAAQ,KAAA;GACR,eAAe,KAAK;GACpB,QAAQ;EACV;CACF;CACA,OAAO,gBAA0E;EAC/E,YAAY;GACV,QAAQ;GACR,IAAI;GACJ,OAAO;GACP,aAAa;GACb,OAAO;GACP,SAAS;IACP;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,UAAU,CAAC,OAAO,UAAU;KAC5B,YAAY,CAAC;IACf;IACA;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,UAAU,CAAC,OAAO,UAAU;KAC5B,YAAY,CAAC;IACf;IACA;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,UAAU,CAAC,OAAO,UAAU;KAC5B,YAAY,CAAC;IACf;GACF;EACF;EACA,aAAa,UAAU,OAAO,OAAO;EACrC,MAAM,aAAa,UAAU,UAAU,iBAAiB,WAAW;GACjE,gBAAgB,UAAU;GAC1B,IAAI,aAAa,YAAY;IAC3B,IAAK,MAAM,aAAa,UAAU,MAAO,MAAM;KAC7C,MAAM,QAAQ;KACd,MAAM,IAAI,MAAM,+CAA+C;IACjE;IACA,IAAI,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,6CAA6C;IACvF,UAAU;IACV,MAAM,QAAQ;IACd,QAAQ;IACR,OAAO,EAAE,SAAS,kDAAkD;GACtE;GACA,IAAI,aAAa,UAAU;IACzB,MAAM,QAAQ;IACd,OAAO,EACL,SACE,WAAW,KAAA,IACP,+CACA,mBAAmB,OAAO,MAAM,WAAW,KAAK,GAAG,KAAK,cAAc,GAC9E;GACF;GACA,IAAI,aAAa,cAAc;IAC7B,IAAI,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,6CAA6C;IACvF,IAAI,UAAU,KAAA,KAAa,MAAM,UAAU,cAAc,MAAM,UAAU,UACvE,MAAM,OAAO,KAAK,UAAU,MAAM;IACpC,UAAU;IACV,MAAM,QAAQ;IACd,QAAQ;IACR,OAAO,EAAE,SAAS,uBAAuB;GAC3C;GACA,MAAM,IAAI,MAAM,gCAAgC,UAAU;EAC5D;CACF,CAAC,CAAC,CAAC,YAAY,KAAA,CAAS;CACxB,OAAO;EACL,UAAU,CAAC,yBAAyB,aAAa,OAAO,CAAC;EACzD,OAAO;GACL;IACE,MAAM;IACN,OAAO;IACP,aAAa;IACb,eAAe;IACf,YAAY;KACV,MAAM;KACN,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,EAAE;KACrD,sBAAsB;IACxB;IACA,MAAM,QAAQ,aAAa,SAAS,QAAQ;KAC1C,IAAI,CAAC,mBAAmB,WAAW,KAAA,KAAa,OAAO,UAAU,UAC/D,MAAM,IAAI,MAAM,8CAA8C;KAChE,MAAM,cAAc,MAAM,OAAO,QAAQ,QAAQ,EAC/C,mBAAoB,QAA4C,sBAAsB,MACxF,CAAC;KACD,OAAO,0BAA0B,WAAW;IAC9C;GACF;GACA;IACE,MAAM;IACN,OAAO;IACP,aAAa;IACb,eAAe;IACf,YAAY;KACV,MAAM;KACN,YAAY;MACV,MAAM;OAAE,MAAM;OAAU,MAAM;QAAC;QAAS;QAAS;QAAa;OAAQ;MAAE;MACxE,YAAY,EAAE,MAAM,SAAS;MAC7B,YAAY,EAAE,MAAM,SAAS;MAC7B,OAAO,EAAE,MAAM,SAAS;MACxB,WAAW;OAAE,MAAM;OAAU,MAAM;QAAC;QAAM;QAAQ;QAAQ;OAAO;MAAE;MACnE,QAAQ;OAAE,MAAM;OAAU,MAAM,CAAC,QAAQ,MAAM;MAAE;KACnD;KACA,UAAU;MAAC;MAAQ;MAAc;KAAY;KAC7C,sBAAsB;IACxB;IACA,MAAM,QAAQ,aAAa,QAAQ,QAAQ;KACzC,IAAI,CAAC,mBAAmB,WAAW,KAAA,KAAa,OAAO,UAAU,UAC/D,MAAM,IAAI,MAAM,8CAA8C;KAChE,MAAM,SAAS,MAAM,OAAO,IAAI,QAAwC,MAAM;KAC9E,OAAO;MAAE,SAAS,CAAC;OAAE,MAAM;OAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC;MAAE,CAAC;MAAG,SAAS;KAAO;IAC/F;GACF;GACA;IACE,MAAM;IACN,OAAO;IACP,aACE;IACF,eACE;IACF,YAAY;KACV,MAAM;KACN,YAAY;MACV,YAAY,EAAE,MAAM,SAAS;MAC7B,OAAO,CAAC;MACR,SAAS,EAAE,MAAM,UAAU;MAC3B,mBAAmB,EAAE,MAAM,UAAU;KACvC;KACA,UAAU,CAAC,cAAc,OAAO;KAChC,sBAAsB;IACxB;IACA,MAAM,QAAQ,aAAa,QAAQ,QAAQ;KACzC,IAAI,CAAC,mBAAmB,WAAW,KAAA,KAAa,OAAO,UAAU,UAC/D,MAAM,IAAI,MAAM,8CAA8C;KAChE,IAAI,aAAa,iBAAiB,KAAA,GAAW,MAAM,IAAI,MAAM,2CAA2C;KACxG,MAAM,QAAQ;KACd,IAAI;MACF,OAAO,qBACL,MAAM,aAAa,aAAa,QAAQ,MAAM,YAAY,MAAM,OAAO,QAAQ,KAAK,CACtF;KACF,SAAS,OAAO;MACd,OAAO,sBAAsB,KAAK;KACpC;IACF;GACF;EACF;EACA,UAAU,CACR,aAAa;GACX,gBAAiB,mBAAmB,WAAW,KAAA,IAAY,CAAC,IAAI,IAAI,CAAC;GACrE,UAAU,UAAU;IAClB,cAAc,IAAI,QAAQ;IAC1B,aAAa;KACX,cAAc,OAAO,QAAQ;IAC/B;GACF;EACF,CAAC,CACH;EACA,kBAAkB,CAChB;GACE,QAAQ;GACR,WAAW,UAAU,cAAc,YAAY,UAAU,SAAS;GAClE,UAAU,UAAU;IAClB,qBAAqB,IAAI,QAAQ;IACjC,aAAa;KACX,qBAAqB,OAAO,QAAQ;IACtC;GACF;EACF,CACF;EACA,QAAQ;GACN,qBAAqB,UACnB,mBAAmB,OAAO,UAAU,WAChC,EAAE,cAAc,GAAG,MAAM,aAAa,MAAM,wBAAwB,IACpE,KAAA;GACN,gBAAgB,QAAQ,YAAY;IAClC,IAAI,OAAO,SAAS;IACpB,gBAAgB;IAChB,eAAe,KAAK;IACpB,IAAI,WAAW,KAAA,GAAW;KACxB,QAAQ;KACR;IACF;IACA,QAAa;IACb,IAAI,OAAO,cAAc,KAAK;IAC9B,QAAQ,kBAAkB,KAAK,QAAQ,GAAG,GAAG;IAC7C,MAAM,QAAQ;GAChB;EACF;EACA,SAAS;GACP,IAAI,OAAO,cAAc,KAAK;GAC9B,QAAQ,KAAA;EACV;EACA,YAAY;GACV,IAAI,OAAO,cAAc,KAAK;GAC9B,QAAQ,KAAA;GACR,eAAe,KAAK;GACpB,eAAe,GAAG,UAAU,8BAA8B,KAAA,CAAS;GACnE,eAAe,GAAG,UAAU,yBAAyB,KAAA,CAAS;GAC9D,gBAAgB,KAAA;EAClB;CACF;AACF;;;AC/SA,IAAA,sBAAiB,EAAE,SAAS,aAC1B,yBAAyB,WAAW,8BAA8B,GAAG,MAAM;;;ACH7E,IAAA,mBAAe,YAAY,YAA2C;CACpE,MAAM,QAAQA,kBAAQ,OAAO;CAC7B,OAAO;EACL;EACA,UAAU,MAAM;EAEhB,QAAQ,MAAM;EACd,WAAW,MAAM;CACnB;AACF,CAAC;;;ACTD,IAAA,6BAAe,kBAAkB,YAAqB,QAAQ,KAAK,SAAU,EAAG;;;ACAhF,IAAA,iCAAe,eAAe,YAAqB,QAAQ,KAAK,OAAQ,qBAAsB;;;ACA9F,IAAA,4BAAe,eAAe,YAAqB,QAAQ,KAAK,OAAQ,gBAAiB;;;ACAzF,IAAA,2BAAe,uBAAuB,YAAqB,QAAQ,KAAK,iBAAkB,EAAG;;;ACC7F,IAAA,iCAAe,eAAe,YAAyC,QAAQ,KAAK,MAAO,EAAG;;;ACA9F,IAAA,kCAAe,eAAe,YAAyC,QAAQ,KAAK,MAAO,EAAG;;;ACA9F,IAAA,gCAAe,eAAe,YAAyC,QAAQ,KAAK,MAAO,EAAG;;;ACe9F,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AACpE,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,YAAY,kBAAoC,kCAAkC,OAAO,YAAY;CAChH,MAAM,eAAe,MAAMC,iBAAY,OAAO;CAC9C,MAAM,iBAAiB;EAAE,GAAG;EAAS,MAAM,aAAa;CAAM;CAC9D,OAAO;EACL,GAAG,iBAAiB,YAAY;EAChC,IAAI,WAA8C;GAAE,OAAO,CAAC,GAAGC,4BAAoB,cAAc,CAAC;EAAG;EACrG,QAAQ;GACN,oBAAoB,GAAGC,gCAAsB,cAAc;GAC3D,eAAe,GAAGC,2BAAkB,cAAc;EACpD;EACA,IAAI,mBAA8D;GAAE,OAAO,CAAC,GAAGC,0BAA4B,cAAc,CAAC;EAAG;EAC7H,GAAG,oBAAoB,kCAAkC;GAAC,IAAI,EAAE,MAAM,oBAAoB,GAAG,GAAGC,gCAAqB,cAAc,CAAC;GAAG,IAAI,EAAE,MAAM,qBAAqB,GAAG,GAAGC,iCAAsB,cAAc,CAAC;GAAG,IAAI,EAAE,MAAM,mBAAmB,GAAG,GAAGC,+BAAoB,cAAc,CAAC;EAAC,CAAC;EAChS,UAAU,CAAC,GAAI,aAAa,YAAY,CAAC,CAAE;CAC7C;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"pi.mjs","names":["runtime","rootSession","commandComputerUse","hookBeforeAgentStart","hookSessionStart","toolRestrictionComputerUse","tool00ComputerState","tool10ComputerAction","tool20ComputerExec"],"sources":["../../src/services/computerUseCommand/index.ts","../../src/services/computerUseRuntime/index.ts","../../src/extensions/workspaces/sessions/(backend)/_runtime/index.cli.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/computer-use.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool-restriction/computer-use.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/00-computer-state.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/10-computer-action.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/20-computer-exec.cli.ts","../../generated/pi.ts"],"sourcesContent":["// @scaffold-generated\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../constants/computerUse';\nimport type { ComputerUseExtensionService } from '../../types/extension';\n\nexport function createComputerUseCommand(\n service: ComputerUseExtensionService,\n): Parameters<ExtensionAPI['registerCommand']> {\n return [\n COMMAND_NAME,\n {\n description: COMMAND_DESCRIPTION,\n handler: async (_args, ctx) => {\n const result = await service.execute();\n if (ctx.hasUI) ctx.ui.notify(result.message, result.level);\n },\n },\n ];\n}\n\nexport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../constants/computerUse';\n","import { type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { type DoomToolRestriction } from '@agimon-ai/doompi-core/toolSurface';\nimport { piMinorModes } from '@agimon-ai/doompi-minor-mode';\nimport { defineMinorMode, type MinorModeOwner, type MinorModeOwnerActionContext } from '@agimon-ai/doompi-minor-mode';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport { COMPUTER_USE_GUIDANCE } from '../../constants/computerUse';\nimport type { ComputerScriptExecutionOptions } from '../../types/computerScript';\nimport type { ComputerUseAction } from '../../types/computerUse';\nimport {\n COMPUTER_USE_MODE_ID,\n COMPUTER_USE_MODE_STATUS_KEY,\n COMPUTER_USE_STATUS_KEY,\n type ComputerUseSessionView,\n} from '../../types/computerUseApi';\nimport type { ComputerUseExtensionDependencies } from '../../types/extension';\nimport { computerObservationOutput, computerScriptOutput, computerScriptFailure } from '../computerToolOutput';\nimport { createComputerUseCommand } from '../computerUseCommand';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-computer-use';\nexport { COMPUTER_USE_MODE_ID };\nimport { modeState, computerUseRestriction } from '../../models/computerUseMode';\n\nexport function createComputerUseRuntime(\n dependencies: ComputerUseExtensionDependencies,\n signal: AbortSignal,\n): PiPluginContributions<ComputerUseExtensionDependencies> & {\n tools: readonly Parameters<ExtensionAPI['registerTool']>[0][];\n} {\n const client = dependencies.client;\n let state: ComputerUseSessionView | undefined;\n let enabled = false;\n let restriction: DoomToolRestriction = computerUseRestriction(false);\n const restrictionListeners = new Set<() => void>();\n const reconcileTools = (active: boolean): void => {\n restriction = computerUseRestriction(active);\n for (const listener of restrictionListeners) listener();\n };\n let globallyEnabled = false;\n let mode: MinorModeOwner<MinorModeOwnerActionContext<ExtensionContext>>;\n const modeListeners = new Set<() => void>();\n let timer: ReturnType<typeof setInterval> | undefined;\n let activeContext: ExtensionContext | undefined;\n let publishedMode = '';\n let publishedModeStatus: string | undefined;\n let publishedActivityStatus: string | undefined;\n const publish = (): void => {\n const phase = state?.phase ?? 'inactive';\n const projection = `${enabled}:${phase}:${state?.revision ?? 'none'}`;\n if (mode !== undefined && projection !== publishedMode) {\n mode.publish();\n publishedMode = projection;\n }\n const modeStatus = state === undefined ? undefined : enabled || phase !== 'inactive' ? phase : '';\n if (activeContext !== undefined && modeStatus !== publishedModeStatus) {\n activeContext.ui.setStatus(COMPUTER_USE_MODE_STATUS_KEY, modeStatus);\n publishedModeStatus = modeStatus;\n }\n const activityStatus = enabled || phase !== 'inactive' ? `computer use: ${phase}` : undefined;\n if (activeContext !== undefined && activityStatus !== publishedActivityStatus) {\n activeContext.ui.setStatus(COMPUTER_USE_STATUS_KEY, activityStatus);\n publishedActivityStatus = activityStatus;\n }\n };\n const refresh = async (): Promise<void> => {\n if (signal.aborted) return;\n let nextGloballyEnabled = false;\n try {\n nextGloballyEnabled = (await dependencies.enabled?.(activeContext?.cwd)) === true;\n } catch {\n nextGloballyEnabled = false;\n }\n if (signal.aborted) return;\n if (nextGloballyEnabled !== globallyEnabled) {\n globallyEnabled = nextGloballyEnabled;\n if (!globallyEnabled) {\n if (client !== undefined && state !== undefined && state.phase !== 'inactive' && state.phase !== 'failed') {\n try {\n await client.stop();\n } catch {\n // The global opt-in is still authoritative even when remote cleanup fails.\n }\n }\n enabled = false;\n state = undefined;\n reconcileTools(false);\n }\n publishedMode = '';\n for (const listener of modeListeners) listener();\n }\n if (!globallyEnabled || client === undefined) {\n state = undefined;\n reconcileTools(false);\n publish();\n return;\n }\n try {\n const nextState = await client.state(signal);\n if (signal.aborted) return;\n state = nextState;\n reconcileTools(state.phase === 'active');\n publish();\n } catch {\n state = undefined;\n reconcileTools(false);\n publish();\n }\n };\n mode = defineMinorMode<undefined, MinorModeOwnerActionContext<ExtensionContext>>({\n descriptor: {\n source: PACKAGE_SOURCE,\n id: COMPUTER_USE_MODE_ID,\n label: 'Computer Use',\n description: 'Session-scoped semantic control through DoomPi Desktop.',\n order: 450,\n actions: [\n {\n id: 'activate',\n label: 'Activate',\n description: 'Open the cockpit activation workflow and native confirmation.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n {\n id: 'deactivate',\n label: 'Deactivate',\n description: 'Stop this session computer-use run.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n {\n id: 'doctor',\n label: 'Doctor',\n description: 'Report Desktop availability and session state.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n ],\n },\n state: () => modeState(state, enabled),\n async handleAction(_runtime, actionId, _argumentsValue, execution) {\n activeContext = execution.context;\n if (actionId === 'activate') {\n if ((await dependencies.enabled?.(execution.context.cwd)) !== true) {\n await refresh();\n throw new Error('Enable computer use in global settings first.');\n }\n if (client === undefined) throw new Error('DoomPi Desktop computer use is unavailable.');\n enabled = true;\n await refresh();\n publish();\n return { message: 'Computer use is ready to configure in Activity.' };\n }\n if (actionId === 'doctor') {\n await refresh();\n return {\n message:\n client === undefined\n ? 'DoomPi Desktop session API is unavailable.'\n : `Computer use is ${state?.phase.replaceAll('_', ' ') ?? 'unavailable'}.`,\n };\n }\n if (actionId === 'deactivate') {\n if (client === undefined) throw new Error('DoomPi Desktop computer use is unavailable.');\n if (state !== undefined && state.phase !== 'inactive' && state.phase !== 'failed')\n await client.stop(execution.signal);\n enabled = false;\n await refresh();\n publish();\n return { message: 'Computer use is off.' };\n }\n throw new Error(`Unknown computer-use action: ${actionId}`);\n },\n }).createOwner(undefined);\n return {\n commands: [createComputerUseCommand(dependencies.service)],\n tools: [\n {\n name: 'computer_state',\n label: 'Computer State',\n description: 'Observe the authorized application window and return its semantic accessibility state.',\n promptSnippet: 'Observe the authorized application before choosing a semantic action',\n parameters: {\n type: 'object',\n properties: { includeScreenshot: { type: 'boolean' } },\n additionalProperties: false,\n },\n async execute(_toolCallId, _params, signal) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n const observation = await client.observe(signal, {\n includeScreenshot: (_params as { includeScreenshot?: boolean }).includeScreenshot !== false,\n });\n return computerObservationOutput(observation);\n },\n },\n {\n name: 'computer_action',\n label: 'Computer Action',\n description: 'Perform one constrained semantic action in the authorized application window.',\n promptSnippet: 'Perform one action using a current computer_state snapshot and element ref',\n parameters: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: ['press', 'focus', 'set_value', 'scroll'] },\n snapshotId: { type: 'string' },\n elementRef: { type: 'string' },\n value: { type: 'string' },\n direction: { type: 'string', enum: ['up', 'down', 'left', 'right'] },\n amount: { type: 'string', enum: ['line', 'page'] },\n },\n required: ['kind', 'snapshotId', 'elementRef'],\n additionalProperties: false,\n },\n async execute(_toolCallId, params, signal) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n const result = await client.act(params as unknown as ComputerUseAction, signal);\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], details: result };\n },\n },\n {\n name: 'computer_exec',\n label: 'Computer Script',\n description:\n 'Run a reusable function with the authorized program API. Full Node requires trusted:true and an explicitly allowlisted path.',\n promptSnippet:\n 'Compose small computer functions using fresh semantic observations; request screenshots only when needed',\n parameters: {\n type: 'object',\n properties: {\n scriptPath: { type: 'string' },\n input: {},\n trusted: { type: 'boolean' },\n includeScreenshot: { type: 'boolean' },\n },\n required: ['scriptPath', 'input'],\n additionalProperties: false,\n },\n async execute(_toolCallId, params, signal, _onUpdate, context) {\n if (!globallyEnabled || client === undefined || state?.phase !== 'active')\n throw new Error('Computer use is not active for this session.');\n if (dependencies.scriptRunner === undefined) throw new Error('Computer script execution is unavailable.');\n const input = params as { scriptPath: string; input: unknown } & ComputerScriptExecutionOptions;\n try {\n return computerScriptOutput(\n await dependencies.scriptRunner.execute(input.scriptPath, input.input, signal, input, context.cwd),\n );\n } catch (error) {\n return computerScriptFailure(error);\n }\n },\n },\n ],\n services: [\n piMinorModes({\n snapshot: () => (globallyEnabled && client !== undefined ? [mode] : []),\n subscribe(listener) {\n modeListeners.add(listener);\n return () => {\n modeListeners.delete(listener);\n };\n },\n }),\n ],\n toolRestrictions: [\n {\n source: PACKAGE_SOURCE,\n restrict: (incoming, available) => restriction(incoming, available),\n subscribe(listener) {\n restrictionListeners.add(listener);\n return () => {\n restrictionListeners.delete(listener);\n };\n },\n },\n ],\n events: {\n before_agent_start: (event) =>\n globallyEnabled && state?.phase === 'active'\n ? { systemPrompt: `${event.systemPrompt}\\n\\n${COMPUTER_USE_GUIDANCE}` }\n : undefined,\n session_start: (_event, context) => {\n if (signal.aborted) return;\n activeContext = context;\n reconcileTools(false);\n if (client === undefined) {\n publish();\n return;\n }\n void refresh();\n if (timer) clearInterval(timer);\n timer = setInterval(() => void refresh(), 250);\n timer.unref?.();\n },\n },\n onStop() {\n if (timer) clearInterval(timer);\n timer = undefined;\n },\n onDispose() {\n if (timer) clearInterval(timer);\n timer = undefined;\n reconcileTools(false);\n activeContext?.ui.setStatus(COMPUTER_USE_MODE_STATUS_KEY, undefined);\n activeContext?.ui.setStatus(COMPUTER_USE_STATUS_KEY, undefined);\n activeContext = undefined;\n },\n };\n}\n","import type { PiPluginContext, PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createComputerUseRuntime } from '../../../../../services/computerUseRuntime';\nimport { createComputerUseDependencies } from '../../../../../services/dependencies';\nimport type { ComputerUseExtensionDependencies } from '../../../../../types/extension';\n\nexport default (({ options, signal }) =>\n createComputerUseRuntime(options ?? createComputerUseDependencies(), signal)) satisfies (\n context: PiPluginContext<ComputerUseExtensionDependencies>,\n) => PiPluginContributions<ComputerUseExtensionDependencies>;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport runtime from './_runtime/index.cli';\n\nexport default defineRoot((context: Parameters<typeof runtime>[0]) => {\n const value = runtime(context);\n return {\n value,\n services: value.services,\n\n onStop: value.onStop,\n onDispose: value.onDispose,\n };\n});\n","import { defineCliCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliCommand((context: Context) => context.root.commands![0]!);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliHook((context: Context) => context.root.events!['before_agent_start']!);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliHook((context: Context) => context.root.events!['session_start']!);\n","import { defineToolRestriction, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineToolRestriction((context: Context) => context.root.toolRestrictions![0]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![0]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![1]!);\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiToolContribution } from '@agimon-ai/doompi-core/piExtension';\ntype Runtime = Awaited<ReturnType<typeof import('../root.cli').default>>['value'];\n\ntype Context = WithRoot<unknown, Runtime>;\nexport default defineCliTool((context: Context): PiToolContribution => context.root.tools![2]!);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, piToolContributions, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandComputerUse from '../src/extensions/workspaces/sessions/(backend)/command/computer-use.cli';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli';\nimport toolRestrictionComputerUse from '../src/extensions/workspaces/sessions/(backend)/tool-restriction/computer-use.cli';\nimport tool00ComputerState from '../src/extensions/workspaces/sessions/(backend)/tool/00-computer-state.cli';\nimport tool10ComputerAction from '../src/extensions/workspaces/sessions/(backend)/tool/10-computer-action.cli';\nimport tool20ComputerExec from '../src/extensions/workspaces/sessions/(backend)/tool/20-computer-exec.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandComputerUse> | OptionsOf<typeof hookBeforeAgentStart> | OptionsOf<typeof hookSessionStart> | OptionsOf<typeof toolRestrictionComputerUse> | OptionsOf<typeof tool00ComputerState> | OptionsOf<typeof tool10ComputerAction> | OptionsOf<typeof tool20ComputerExec>, undefined>;\ntype Intersect<Union> =\n (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-computer-use', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): PiPluginContributions['commands'] { return [at(commandComputerUse, contextSession)]; },\n events: {\n before_agent_start: at(hookBeforeAgentStart, contextSession) as NonNullable<PiPluginContributions['events']>['before_agent_start'],\n session_start: at(hookSessionStart, contextSession) as NonNullable<PiPluginContributions['events']>['session_start'],\n },\n get toolRestrictions(): PiPluginContributions['toolRestrictions'] { return [at(toolRestrictionComputerUse, contextSession)]; },\n ...piToolContributions('@agimon-ai/doompi-computer-use', [via({ name: '00_computer_state' }, at(tool00ComputerState, contextSession)), via({ name: '10_computer_action' }, at(tool10ComputerAction, contextSession)), via({ name: '20_computer_exec' }, at(tool20ComputerExec, contextSession))]),\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":";;;;;;;AAMA,SAAgB,yBACd,SAC6C;CAC7C,OAAO,CACL,cACA;EACE,aAAa;EACb,SAAS,OAAO,OAAO,QAAQ;GAC7B,MAAM,SAAS,MAAM,QAAQ,QAAQ;GACrC,IAAI,IAAI,OAAO,IAAI,GAAG,OAAO,OAAO,SAAS,OAAO,KAAK;EAC3D;CACF,CACF;AACF;;;ACAA,MAAM,iBAAiB;AAIvB,SAAgB,yBACd,cACA,QAGA;CACA,MAAM,SAAS,aAAa;CAC5B,IAAI;CACJ,IAAI,UAAU;CACd,IAAI,cAAmC,uBAAuB,KAAK;CACnE,MAAM,uCAAuB,IAAI,IAAgB;CACjD,MAAM,kBAAkB,WAA0B;EAChD,cAAc,uBAAuB,MAAM;EAC3C,KAAK,MAAM,YAAY,sBAAsB,SAAS;CACxD;CACA,IAAI,kBAAkB;CACtB,IAAI;CACJ,MAAM,gCAAgB,IAAI,IAAgB;CAC1C,IAAI;CACJ,IAAI;CACJ,IAAI,gBAAgB;CACpB,IAAI;CACJ,IAAI;CACJ,MAAM,gBAAsB;EAC1B,MAAM,QAAQ,OAAO,SAAS;EAC9B,MAAM,aAAa,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,YAAY;EAC7D,IAAI,SAAS,KAAA,KAAa,eAAe,eAAe;GACtD,KAAK,QAAQ;GACb,gBAAgB;EAClB;EACA,MAAM,aAAa,UAAU,KAAA,IAAY,KAAA,IAAY,WAAW,UAAU,aAAa,QAAQ;EAC/F,IAAI,kBAAkB,KAAA,KAAa,eAAe,qBAAqB;GACrE,cAAc,GAAG,UAAU,8BAA8B,UAAU;GACnE,sBAAsB;EACxB;EACA,MAAM,iBAAiB,WAAW,UAAU,aAAa,iBAAiB,UAAU,KAAA;EACpF,IAAI,kBAAkB,KAAA,KAAa,mBAAmB,yBAAyB;GAC7E,cAAc,GAAG,UAAU,yBAAyB,cAAc;GAClE,0BAA0B;EAC5B;CACF;CACA,MAAM,UAAU,YAA2B;EACzC,IAAI,OAAO,SAAS;EACpB,IAAI,sBAAsB;EAC1B,IAAI;GACF,sBAAuB,MAAM,aAAa,UAAU,eAAe,GAAG,MAAO;EAC/E,QAAQ;GACN,sBAAsB;EACxB;EACA,IAAI,OAAO,SAAS;EACpB,IAAI,wBAAwB,iBAAiB;GAC3C,kBAAkB;GAClB,IAAI,CAAC,iBAAiB;IACpB,IAAI,WAAW,KAAA,KAAa,UAAU,KAAA,KAAa,MAAM,UAAU,cAAc,MAAM,UAAU,UAC/F,IAAI;KACF,MAAM,OAAO,KAAK;IACpB,QAAQ,CAER;IAEF,UAAU;IACV,QAAQ,KAAA;IACR,eAAe,KAAK;GACtB;GACA,gBAAgB;GAChB,KAAK,MAAM,YAAY,eAAe,SAAS;EACjD;EACA,IAAI,CAAC,mBAAmB,WAAW,KAAA,GAAW;GAC5C,QAAQ,KAAA;GACR,eAAe,KAAK;GACpB,QAAQ;GACR;EACF;EACA,IAAI;GACF,MAAM,YAAY,MAAM,OAAO,MAAM,MAAM;GAC3C,IAAI,OAAO,SAAS;GACpB,QAAQ;GACR,eAAe,MAAM,UAAU,QAAQ;GACvC,QAAQ;EACV,QAAQ;GACN,QAAQ,KAAA;GACR,eAAe,KAAK;GACpB,QAAQ;EACV;CACF;CACA,OAAO,gBAA0E;EAC/E,YAAY;GACV,QAAQ;GACR,IAAI;GACJ,OAAO;GACP,aAAa;GACb,OAAO;GACP,SAAS;IACP;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,UAAU,CAAC,OAAO,UAAU;KAC5B,YAAY,CAAC;IACf;IACA;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,UAAU,CAAC,OAAO,UAAU;KAC5B,YAAY,CAAC;IACf;IACA;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,UAAU,CAAC,OAAO,UAAU;KAC5B,YAAY,CAAC;IACf;GACF;EACF;EACA,aAAa,UAAU,OAAO,OAAO;EACrC,MAAM,aAAa,UAAU,UAAU,iBAAiB,WAAW;GACjE,gBAAgB,UAAU;GAC1B,IAAI,aAAa,YAAY;IAC3B,IAAK,MAAM,aAAa,UAAU,UAAU,QAAQ,GAAG,MAAO,MAAM;KAClE,MAAM,QAAQ;KACd,MAAM,IAAI,MAAM,+CAA+C;IACjE;IACA,IAAI,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,6CAA6C;IACvF,UAAU;IACV,MAAM,QAAQ;IACd,QAAQ;IACR,OAAO,EAAE,SAAS,kDAAkD;GACtE;GACA,IAAI,aAAa,UAAU;IACzB,MAAM,QAAQ;IACd,OAAO,EACL,SACE,WAAW,KAAA,IACP,+CACA,mBAAmB,OAAO,MAAM,WAAW,KAAK,GAAG,KAAK,cAAc,GAC9E;GACF;GACA,IAAI,aAAa,cAAc;IAC7B,IAAI,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,6CAA6C;IACvF,IAAI,UAAU,KAAA,KAAa,MAAM,UAAU,cAAc,MAAM,UAAU,UACvE,MAAM,OAAO,KAAK,UAAU,MAAM;IACpC,UAAU;IACV,MAAM,QAAQ;IACd,QAAQ;IACR,OAAO,EAAE,SAAS,uBAAuB;GAC3C;GACA,MAAM,IAAI,MAAM,gCAAgC,UAAU;EAC5D;CACF,CAAC,CAAC,CAAC,YAAY,KAAA,CAAS;CACxB,OAAO;EACL,UAAU,CAAC,yBAAyB,aAAa,OAAO,CAAC;EACzD,OAAO;GACL;IACE,MAAM;IACN,OAAO;IACP,aAAa;IACb,eAAe;IACf,YAAY;KACV,MAAM;KACN,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,EAAE;KACrD,sBAAsB;IACxB;IACA,MAAM,QAAQ,aAAa,SAAS,QAAQ;KAC1C,IAAI,CAAC,mBAAmB,WAAW,KAAA,KAAa,OAAO,UAAU,UAC/D,MAAM,IAAI,MAAM,8CAA8C;KAChE,MAAM,cAAc,MAAM,OAAO,QAAQ,QAAQ,EAC/C,mBAAoB,QAA4C,sBAAsB,MACxF,CAAC;KACD,OAAO,0BAA0B,WAAW;IAC9C;GACF;GACA;IACE,MAAM;IACN,OAAO;IACP,aAAa;IACb,eAAe;IACf,YAAY;KACV,MAAM;KACN,YAAY;MACV,MAAM;OAAE,MAAM;OAAU,MAAM;QAAC;QAAS;QAAS;QAAa;OAAQ;MAAE;MACxE,YAAY,EAAE,MAAM,SAAS;MAC7B,YAAY,EAAE,MAAM,SAAS;MAC7B,OAAO,EAAE,MAAM,SAAS;MACxB,WAAW;OAAE,MAAM;OAAU,MAAM;QAAC;QAAM;QAAQ;QAAQ;OAAO;MAAE;MACnE,QAAQ;OAAE,MAAM;OAAU,MAAM,CAAC,QAAQ,MAAM;MAAE;KACnD;KACA,UAAU;MAAC;MAAQ;MAAc;KAAY;KAC7C,sBAAsB;IACxB;IACA,MAAM,QAAQ,aAAa,QAAQ,QAAQ;KACzC,IAAI,CAAC,mBAAmB,WAAW,KAAA,KAAa,OAAO,UAAU,UAC/D,MAAM,IAAI,MAAM,8CAA8C;KAChE,MAAM,SAAS,MAAM,OAAO,IAAI,QAAwC,MAAM;KAC9E,OAAO;MAAE,SAAS,CAAC;OAAE,MAAM;OAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC;MAAE,CAAC;MAAG,SAAS;KAAO;IAC/F;GACF;GACA;IACE,MAAM;IACN,OAAO;IACP,aACE;IACF,eACE;IACF,YAAY;KACV,MAAM;KACN,YAAY;MACV,YAAY,EAAE,MAAM,SAAS;MAC7B,OAAO,CAAC;MACR,SAAS,EAAE,MAAM,UAAU;MAC3B,mBAAmB,EAAE,MAAM,UAAU;KACvC;KACA,UAAU,CAAC,cAAc,OAAO;KAChC,sBAAsB;IACxB;IACA,MAAM,QAAQ,aAAa,QAAQ,QAAQ,WAAW,SAAS;KAC7D,IAAI,CAAC,mBAAmB,WAAW,KAAA,KAAa,OAAO,UAAU,UAC/D,MAAM,IAAI,MAAM,8CAA8C;KAChE,IAAI,aAAa,iBAAiB,KAAA,GAAW,MAAM,IAAI,MAAM,2CAA2C;KACxG,MAAM,QAAQ;KACd,IAAI;MACF,OAAO,qBACL,MAAM,aAAa,aAAa,QAAQ,MAAM,YAAY,MAAM,OAAO,QAAQ,OAAO,QAAQ,GAAG,CACnG;KACF,SAAS,OAAO;MACd,OAAO,sBAAsB,KAAK;KACpC;IACF;GACF;EACF;EACA,UAAU,CACR,aAAa;GACX,gBAAiB,mBAAmB,WAAW,KAAA,IAAY,CAAC,IAAI,IAAI,CAAC;GACrE,UAAU,UAAU;IAClB,cAAc,IAAI,QAAQ;IAC1B,aAAa;KACX,cAAc,OAAO,QAAQ;IAC/B;GACF;EACF,CAAC,CACH;EACA,kBAAkB,CAChB;GACE,QAAQ;GACR,WAAW,UAAU,cAAc,YAAY,UAAU,SAAS;GAClE,UAAU,UAAU;IAClB,qBAAqB,IAAI,QAAQ;IACjC,aAAa;KACX,qBAAqB,OAAO,QAAQ;IACtC;GACF;EACF,CACF;EACA,QAAQ;GACN,qBAAqB,UACnB,mBAAmB,OAAO,UAAU,WAChC,EAAE,cAAc,GAAG,MAAM,aAAa,MAAM,wBAAwB,IACpE,KAAA;GACN,gBAAgB,QAAQ,YAAY;IAClC,IAAI,OAAO,SAAS;IACpB,gBAAgB;IAChB,eAAe,KAAK;IACpB,IAAI,WAAW,KAAA,GAAW;KACxB,QAAQ;KACR;IACF;IACA,QAAa;IACb,IAAI,OAAO,cAAc,KAAK;IAC9B,QAAQ,kBAAkB,KAAK,QAAQ,GAAG,GAAG;IAC7C,MAAM,QAAQ;GAChB;EACF;EACA,SAAS;GACP,IAAI,OAAO,cAAc,KAAK;GAC9B,QAAQ,KAAA;EACV;EACA,YAAY;GACV,IAAI,OAAO,cAAc,KAAK;GAC9B,QAAQ,KAAA;GACR,eAAe,KAAK;GACpB,eAAe,GAAG,UAAU,8BAA8B,KAAA,CAAS;GACnE,eAAe,GAAG,UAAU,yBAAyB,KAAA,CAAS;GAC9D,gBAAgB,KAAA;EAClB;CACF;AACF;;;AC/SA,IAAA,sBAAiB,EAAE,SAAS,aAC1B,yBAAyB,WAAW,8BAA8B,GAAG,MAAM;;;ACH7E,IAAA,mBAAe,YAAY,YAA2C;CACpE,MAAM,QAAQA,kBAAQ,OAAO;CAC7B,OAAO;EACL;EACA,UAAU,MAAM;EAEhB,QAAQ,MAAM;EACd,WAAW,MAAM;CACnB;AACF,CAAC;;;ACTD,IAAA,6BAAe,kBAAkB,YAAqB,QAAQ,KAAK,SAAU,EAAG;;;ACAhF,IAAA,iCAAe,eAAe,YAAqB,QAAQ,KAAK,OAAQ,qBAAsB;;;ACA9F,IAAA,4BAAe,eAAe,YAAqB,QAAQ,KAAK,OAAQ,gBAAiB;;;ACAzF,IAAA,2BAAe,uBAAuB,YAAqB,QAAQ,KAAK,iBAAkB,EAAG;;;ACC7F,IAAA,iCAAe,eAAe,YAAyC,QAAQ,KAAK,MAAO,EAAG;;;ACA9F,IAAA,kCAAe,eAAe,YAAyC,QAAQ,KAAK,MAAO,EAAG;;;ACA9F,IAAA,gCAAe,eAAe,YAAyC,QAAQ,KAAK,MAAO,EAAG;;;ACe9F,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AACpE,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,YAAY,kBAAoC,kCAAkC,OAAO,YAAY;CAChH,MAAM,eAAe,MAAMC,iBAAY,OAAO;CAC9C,MAAM,iBAAiB;EAAE,GAAG;EAAS,MAAM,aAAa;CAAM;CAC9D,OAAO;EACL,GAAG,iBAAiB,YAAY;EAChC,IAAI,WAA8C;GAAE,OAAO,CAAC,GAAGC,4BAAoB,cAAc,CAAC;EAAG;EACrG,QAAQ;GACN,oBAAoB,GAAGC,gCAAsB,cAAc;GAC3D,eAAe,GAAGC,2BAAkB,cAAc;EACpD;EACA,IAAI,mBAA8D;GAAE,OAAO,CAAC,GAAGC,0BAA4B,cAAc,CAAC;EAAG;EAC7H,GAAG,oBAAoB,kCAAkC;GAAC,IAAI,EAAE,MAAM,oBAAoB,GAAG,GAAGC,gCAAqB,cAAc,CAAC;GAAG,IAAI,EAAE,MAAM,qBAAqB,GAAG,GAAGC,iCAAsB,cAAc,CAAC;GAAG,IAAI,EAAE,MAAM,mBAAmB,GAAG,GAAGC,+BAAoB,cAAc,CAAC;EAAC,CAAC;EAChS,UAAU,CAAC,GAAI,aAAa,YAAY,CAAC,CAAE;CAC7C;AACF,CAAC"}
|
|
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_extensionService = require("../extensionService-
|
|
6
|
-
const require_computerUseMode = require("../computerUseMode-
|
|
5
|
+
const require_extensionService = require("../extensionService-CIDyPyzP.cjs");
|
|
6
|
+
const require_computerUseMode = require("../computerUseMode-KnoOWve4.cjs");
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
node_path = require_extensionService.__toESM(node_path, 1);
|
|
9
9
|
let _agimon_ai_doompi_core_extensionFile = require("@agimon-ai/doompi-core/extensionFile");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as COMMAND_NAME, i as COMMAND_DESCRIPTION, r as ComputerScriptRunner, t as DefaultComputerUseExtensionService } from "../extensionService-
|
|
2
|
-
import { a as computerScriptOutput, d as COMPUTER_USE_ROUTES, f as COMPUTER_USE_STATUS_KEY, i as computerScriptFailure, l as COMPUTER_USE_MODE_ID, m as computerUseChannelType, n as modeState, o as API_BASE_PATH, p as COMPUTER_USE_WAKE_LIMIT, r as computerObservationOutput, s as COMPUTER_USE_CONFIRMATION_WINDOW_MS } from "../computerUseMode-
|
|
1
|
+
import { a as COMMAND_NAME, i as COMMAND_DESCRIPTION, r as ComputerScriptRunner, t as DefaultComputerUseExtensionService } from "../extensionService-BSqhP2uB.mjs";
|
|
2
|
+
import { a as computerScriptOutput, d as COMPUTER_USE_ROUTES, f as COMPUTER_USE_STATUS_KEY, i as computerScriptFailure, l as COMPUTER_USE_MODE_ID, m as computerUseChannelType, n as modeState, o as API_BASE_PATH, p as COMPUTER_USE_WAKE_LIMIT, r as computerObservationOutput, s as COMPUTER_USE_CONFIRMATION_WINDOW_MS } from "../computerUseMode-C1r5mG7K.mjs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { composeRootHooks, defineChannel, defineRoot, defineRoutedContribution } from "@agimon-ai/doompi-core/extensionFile";
|
|
5
5
|
import { defineMinorMode, serverMinorModes } from "@agimon-ai/doompi-minor-mode";
|
|
@@ -240,7 +240,7 @@ interface ComputerScriptExecutionOptions {
|
|
|
240
240
|
includeScreenshot?: boolean;
|
|
241
241
|
}
|
|
242
242
|
interface ComputerScriptExecutor {
|
|
243
|
-
execute(scriptPath: string, input: unknown, signal?: AbortSignal, options?: ComputerScriptExecutionOptions): Promise<ComputerScriptExecutionResult>;
|
|
243
|
+
execute(scriptPath: string, input: unknown, signal?: AbortSignal, options?: ComputerScriptExecutionOptions, cwd?: string): Promise<ComputerScriptExecutionResult>;
|
|
244
244
|
}
|
|
245
245
|
interface ComputerScriptRunnerOptions {
|
|
246
246
|
readonly client: ComputerUseSessionClient;
|
|
@@ -264,7 +264,7 @@ interface ComputerUseExtensionDependencies {
|
|
|
264
264
|
service: ComputerUseExtensionService;
|
|
265
265
|
client?: ComputerUseSessionClient;
|
|
266
266
|
scriptRunner?: ComputerScriptExecutor;
|
|
267
|
-
enabled?: () => boolean | Promise<boolean>;
|
|
267
|
+
enabled?: (cwd?: string) => boolean | Promise<boolean>;
|
|
268
268
|
}
|
|
269
269
|
//#endregion
|
|
270
270
|
//#region src/services/dependencies/index.d.ts
|
|
@@ -279,7 +279,7 @@ declare class ComputerScriptRunner {
|
|
|
279
279
|
private readonly timeoutMs;
|
|
280
280
|
private readonly maxOutputBytes;
|
|
281
281
|
constructor(options: ComputerScriptRunnerOptions);
|
|
282
|
-
execute(scriptPath: string, input: unknown, signal?: AbortSignal, options?: ComputerScriptExecutionOptions): Promise<ComputerScriptExecutionResult>;
|
|
282
|
+
execute(scriptPath: string, input: unknown, signal?: AbortSignal, options?: ComputerScriptExecutionOptions, cwd?: string): Promise<ComputerScriptExecutionResult>;
|
|
283
283
|
}
|
|
284
284
|
//#endregion
|
|
285
285
|
//#region src/services/extensionService/index.d.ts
|
|
@@ -320,4 +320,4 @@ interface ComputerUseTraceRecord {
|
|
|
320
320
|
declare function redactComputerUseTrace(input: ComputerUseTraceInput): ComputerUseTraceRecord;
|
|
321
321
|
//#endregion
|
|
322
322
|
export { ComputerUseSessionClient as A, COMPUTER_USE_MODE_STATUS_KEY as B, ComputerUseActionKind as C, ComputerUseObservation as D, ComputerUseGrant as E, API_BASE_PATH as F, ComputerUseArtifactView as G, COMPUTER_USE_STATUS_KEY as H, COMPUTER_USE_CONFIRMATION_WINDOW_MS as I, ComputerUseChannelPayload as J, ComputerUseBrokerRequest as K, COMPUTER_USE_DEFAULT_DURATION_MS as L, ComputerUseState as M, ComputerUseStateEvent as N, ComputerUseObservationOptions as O, ComputerUseTarget as P, COMPUTER_USE_TOOL_NAMES as Q, COMPUTER_USE_MAX_DURATION_MS as R, ComputerUseAction as S, ComputerUseFailureCode as T, COMPUTER_USE_WAKE_LIMIT as U, COMPUTER_USE_ROUTES as V, ComputerUseActivationRequest as W, computerUseChannelType as X, ComputerUseSessionView as Y, COMPUTER_USE_GUIDANCE as Z, ComputerScriptRun as _, ComputerScriptRunner as a, createComputerUseSessionClient as b, ComputerUseExtensionDependencies as c, ComputerUseNotificationLevel as d, ComputerScriptExecutionOptions as f, ComputerScriptProgram as g, ComputerScriptLogger as h, DefaultComputerUseExtensionService as i, ComputerUseSessionIdentity as j, ComputerUsePhase as k, ComputerUseExtensionResult as l, ComputerScriptExecutor as m, initialComputerUseState as n, COMPUTER_USE_SCRIPT_PATHS_ENV as o, ComputerScriptExecutionResult as p, ComputerUseBrowserCommand as q, reduceComputerUseState as r, createComputerUseDependencies as s, redactComputerUseTrace as t, ComputerUseExtensionService as u, ComputerScriptRunContext as v, ComputerUseElement as w, COMPUTER_USE_PHASES as x, ComputerScriptRunnerOptions as y, COMPUTER_USE_MODE_ID as z };
|
|
323
|
-
//# sourceMappingURL=index-
|
|
323
|
+
//# sourceMappingURL=index-DoKasntC.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-DoKasntC.d.mts","names":[],"sources":["../src/constants/computerUse.ts","../src/types/computerUseApi.ts","../src/types/computerUse.ts","../src/services/sessionApiClient/index.ts","../src/types/computerScript.ts","../src/types/extension.ts","../src/services/dependencies/index.ts","../src/services/computerScriptRunner/index.ts","../src/services/extensionService/index.ts","../src/models/computerUseState.ts","../src/services/traceRedaction/index.ts"],"mappings":";;cAAa;cAKA;;;cCHA;cACA;cACA;cACA;cACA;cACA;cACA;cACA;;;;;;;;cASA;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;cAGW;UAEI;WACN;WACA;WACA;WACA;WACA;WACA;WACA;aAAqB;aAAuB;;;UAGtC;WACN;WACA;WACA;WACA;WACA;WACA,SAAS;WACT;WACA;WACA;aAAqB;aAAuB;;WAC5C,WAAW;;UAGL;WACN;WACA,QAAQ;WACR;WACA;WACA;WACA,QAAQ;;UAGF;WACN;WACA;WACA;WACA;WACA;;UAGM;WACN,OAAO;WACP,kBAAkB;WAClB;;KAGC;WAAuC;;;;UC9ElC;EACf,MAAM,SAAS,cAAc,QAAQ;EACrC,iBAAiB,WAAW,OAAO;EACnC,QAAQ,SAAS,aAAa,UAAU,gCAAgC,QAAQ;EAChF,IAAI,QAAQ,mBAAmB,SAAS,cAAc;EACtD,KAAK,SAAS,cAAc,QAAQ;;UAGrB;EACf;;cAGW;KAUD,2BAA2B;UAEtB;WACN;WACA;WACA;;UAGM;WACN;WACA;WACA;WACA;WACA;;UAGM;WACN;WACA;WACA;WACA;WACA;;UAGM;WACN;WACA;WACA;WACA;WACA;WACA;WACA,kBAAkB;;UAGZ;WACN;WACA;WACA;WACA;WACA;WACA;WACA,mBAAmB;WACnB;aACE;aACA;;;KAID;KAEA;WAEG;WACA;WACA;;WAGA;WACA;WACA;WACA;;WAGA;WACA;WACA;WACA;WACA;;KAGH;UAeK;WACN;WACA,OAAO;WACP,UAAU;WACV;WACA,SAAS;WACT,QAAQ;WACR;aACE,MAAM;aACN;;;KAID;WACG;WAA0B;WAA4B,QAAQ;;WAC9D;WAAqC;;WACrC;WAA0B;;WAC1B;WAAuB;;WACvB;WAA4B;WAA4B,OAAO;;WAC/D;;WACA;;WACA;WAAuB,MAAM;WAAiC;;WAC9D;;;;;iBC9HC,+BAA+B,OAAO,2BAA2B;;;UCEhE;EACf,QAAQ,UAAU,gCAAgC,QAAQ;EAC1D,IAAI,QAAQ,oBAAoB;;UAGjB;EACf,MAAM;EACN,KAAK;EACL,KAAK;EACL,MAAM;;UAGS;EACf;IAAW,SAAS;;EACpB;EACA,QAAQ;;EAER,QAAQ,KAAK;;;KAIH,qBAAqB,SAAS;UAEzB;EACf;EACA,aAAa;EACb;EACA;IACE;IACA;IACA;IACA;;;UAIa;;EAEf;EACA;;UAGe;EACf,QACE,oBACA,gBACA,SAAS,aACT,UAAU,gCACV,eACC,QAAQ;;UAGI;WACN,QAAQ;WACR;;WAEA;WACA;WACA;;;;KC7DC;UAEK;EACf;EACA,OAAO;;UAGQ;EACf,WAAW,QAAQ;;UAGJ;EACf,SAAS;EACT,SAAS;EACT,eAAe;EACf,WAAW,2BAA2B;;;;cCT3B;iBACG,8BACd,YAAW,QAAQ,oCAClB;;;cC4BU;mBACM;mBACA;mBACA;mBACA;mBACA;EAEjB,YAAY,SAAS;EAQf,QACJ,oBACA,gBACA,SAAS,aACT,UAAS,gCACT,eACC,QAAQ;;;;cC1DA,8CAA8C;mBACrB;EAApC,YAAoC,SAAS;EAEhC,WAAW,QAAQ;;;;iBCQlB,wBAAwB,UAAU,+BAA+B;iBAIjE,uBAAuB,OAAO,kBAAkB,OAAO,wBAAwB;;;UChB9E;WACN;WACA;WACA;WACA;WACA,QAAQ;WACR;WACA;WACA;WACA,YAAY;;UAGN;WACN;WACA;WACA;WACA;WACA,YAAY;WACZ;WACA;WACA;WACA,SAAS;WACT,YAAY;;iBAGP,uBAAuB,OAAO,wBAAwB"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_extensionService = require("./extensionService-
|
|
3
|
-
const require_dependencies = require("./dependencies-
|
|
2
|
+
const require_extensionService = require("./extensionService-CIDyPyzP.cjs");
|
|
3
|
+
const require_dependencies = require("./dependencies-BQOsqM8Q.cjs");
|
|
4
4
|
//#region src/models/computerUseState.ts
|
|
5
5
|
function requireRequest(state, requestId) {
|
|
6
6
|
if (state.requestId !== requestId) throw new Error("The computer-use activation request is stale.");
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as ComputerUseSessionClient, B as COMPUTER_USE_MODE_STATUS_KEY, C as ComputerUseActionKind, D as ComputerUseObservation, E as ComputerUseGrant, F as API_BASE_PATH, G as ComputerUseArtifactView, H as COMPUTER_USE_STATUS_KEY, I as COMPUTER_USE_CONFIRMATION_WINDOW_MS, J as ComputerUseChannelPayload, K as ComputerUseBrokerRequest, L as COMPUTER_USE_DEFAULT_DURATION_MS, M as ComputerUseState, N as ComputerUseStateEvent, O as ComputerUseObservationOptions, P as ComputerUseTarget, Q as COMPUTER_USE_TOOL_NAMES, R as COMPUTER_USE_MAX_DURATION_MS, S as ComputerUseAction, T as ComputerUseFailureCode, U as COMPUTER_USE_WAKE_LIMIT, V as COMPUTER_USE_ROUTES, W as ComputerUseActivationRequest, X as computerUseChannelType, Y as ComputerUseSessionView, Z as COMPUTER_USE_GUIDANCE, _ as ComputerScriptRun, a as ComputerScriptRunner, b as createComputerUseSessionClient, c as ComputerUseExtensionDependencies, d as ComputerUseNotificationLevel, f as ComputerScriptExecutionOptions, g as ComputerScriptProgram, h as ComputerScriptLogger, i as DefaultComputerUseExtensionService, j as ComputerUseSessionIdentity, k as ComputerUsePhase, l as ComputerUseExtensionResult, m as ComputerScriptExecutor, n as initialComputerUseState, o as COMPUTER_USE_SCRIPT_PATHS_ENV, p as ComputerScriptExecutionResult, q as ComputerUseBrowserCommand, r as reduceComputerUseState, s as createComputerUseDependencies, t as redactComputerUseTrace, u as ComputerUseExtensionService, v as ComputerScriptRunContext, w as ComputerUseElement, x as COMPUTER_USE_PHASES, y as ComputerScriptRunnerOptions, z as COMPUTER_USE_MODE_ID } from "./index-
|
|
1
|
+
import { A as ComputerUseSessionClient, B as COMPUTER_USE_MODE_STATUS_KEY, C as ComputerUseActionKind, D as ComputerUseObservation, E as ComputerUseGrant, F as API_BASE_PATH, G as ComputerUseArtifactView, H as COMPUTER_USE_STATUS_KEY, I as COMPUTER_USE_CONFIRMATION_WINDOW_MS, J as ComputerUseChannelPayload, K as ComputerUseBrokerRequest, L as COMPUTER_USE_DEFAULT_DURATION_MS, M as ComputerUseState, N as ComputerUseStateEvent, O as ComputerUseObservationOptions, P as ComputerUseTarget, Q as COMPUTER_USE_TOOL_NAMES, R as COMPUTER_USE_MAX_DURATION_MS, S as ComputerUseAction, T as ComputerUseFailureCode, U as COMPUTER_USE_WAKE_LIMIT, V as COMPUTER_USE_ROUTES, W as ComputerUseActivationRequest, X as computerUseChannelType, Y as ComputerUseSessionView, Z as COMPUTER_USE_GUIDANCE, _ as ComputerScriptRun, a as ComputerScriptRunner, b as createComputerUseSessionClient, c as ComputerUseExtensionDependencies, d as ComputerUseNotificationLevel, f as ComputerScriptExecutionOptions, g as ComputerScriptProgram, h as ComputerScriptLogger, i as DefaultComputerUseExtensionService, j as ComputerUseSessionIdentity, k as ComputerUsePhase, l as ComputerUseExtensionResult, m as ComputerScriptExecutor, n as initialComputerUseState, o as COMPUTER_USE_SCRIPT_PATHS_ENV, p as ComputerScriptExecutionResult, q as ComputerUseBrowserCommand, r as reduceComputerUseState, s as createComputerUseDependencies, t as redactComputerUseTrace, u as ComputerUseExtensionService, v as ComputerScriptRunContext, w as ComputerUseElement, x as COMPUTER_USE_PHASES, y as ComputerScriptRunnerOptions, z as COMPUTER_USE_MODE_ID } from "./index-DoKasntC.mjs";
|
|
2
2
|
export { type API_BASE_PATH, type COMPUTER_USE_CONFIRMATION_WINDOW_MS, type COMPUTER_USE_DEFAULT_DURATION_MS, COMPUTER_USE_GUIDANCE, type COMPUTER_USE_MAX_DURATION_MS, type COMPUTER_USE_MODE_ID, type COMPUTER_USE_MODE_STATUS_KEY, type COMPUTER_USE_PHASES, type COMPUTER_USE_ROUTES, COMPUTER_USE_SCRIPT_PATHS_ENV, type COMPUTER_USE_STATUS_KEY, COMPUTER_USE_TOOL_NAMES, type COMPUTER_USE_WAKE_LIMIT, type ComputerScriptExecutionOptions, type ComputerScriptExecutionResult, type ComputerScriptExecutor, type ComputerScriptLogger, type ComputerScriptProgram, type ComputerScriptRun, type ComputerScriptRunContext, ComputerScriptRunner, type ComputerScriptRunnerOptions, type ComputerUseAction, type ComputerUseActionKind, type ComputerUseActivationRequest, type ComputerUseArtifactView, type ComputerUseBrokerRequest, type ComputerUseBrowserCommand, type ComputerUseChannelPayload, type ComputerUseElement, type ComputerUseExtensionDependencies, type ComputerUseExtensionResult, type ComputerUseExtensionService, type ComputerUseFailureCode, type ComputerUseGrant, type ComputerUseNotificationLevel, type ComputerUseObservation, type ComputerUseObservationOptions, type ComputerUsePhase, type ComputerUseSessionClient, type ComputerUseSessionIdentity, type ComputerUseSessionView, type ComputerUseState, type ComputerUseStateEvent, type ComputerUseTarget, DefaultComputerUseExtensionService, type computerUseChannelType, createComputerUseDependencies, createComputerUseSessionClient, initialComputerUseState, redactComputerUseTrace, reduceComputerUseState };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { o as COMPUTER_USE_GUIDANCE, r as ComputerScriptRunner, s as COMPUTER_USE_TOOL_NAMES, t as DefaultComputerUseExtensionService } from "./extensionService-
|
|
2
|
-
import { n as createComputerUseDependencies, r as createComputerUseSessionClient, t as COMPUTER_USE_SCRIPT_PATHS_ENV } from "./dependencies-
|
|
1
|
+
import { o as COMPUTER_USE_GUIDANCE, r as ComputerScriptRunner, s as COMPUTER_USE_TOOL_NAMES, t as DefaultComputerUseExtensionService } from "./extensionService-BSqhP2uB.mjs";
|
|
2
|
+
import { n as createComputerUseDependencies, r as createComputerUseSessionClient, t as COMPUTER_USE_SCRIPT_PATHS_ENV } from "./dependencies-ChuvtRxU.mjs";
|
|
3
3
|
//#region src/models/computerUseState.ts
|
|
4
4
|
function requireRequest(state, requestId) {
|
|
5
5
|
if (state.requestId !== requestId) throw new Error("The computer-use activation request is stale.");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-computer-use",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.34",
|
|
4
4
|
"description": "Session scoped semantic computer control through the DoomPi Desktop capability.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -65,18 +65,18 @@
|
|
|
65
65
|
"access": "public"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@agimon-ai/doompi-config": "0.0.1-alpha.
|
|
69
|
-
"@agimon-ai/doompi-core": "0.0.1-alpha.
|
|
70
|
-
"@agimon-ai/doompi-minor-mode": "0.0.1-alpha.
|
|
71
|
-
"@agimon-ai/doompi-web-components": "0.0.1-alpha.
|
|
72
|
-
"@agimon-ai/doompi-web-security": "0.0.1-alpha.
|
|
68
|
+
"@agimon-ai/doompi-config": "0.0.1-alpha.89",
|
|
69
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.90",
|
|
70
|
+
"@agimon-ai/doompi-minor-mode": "0.0.1-alpha.90",
|
|
71
|
+
"@agimon-ai/doompi-web-components": "0.0.1-alpha.48",
|
|
72
|
+
"@agimon-ai/doompi-web-security": "0.0.1-alpha.46",
|
|
73
73
|
"@deepseek-ai/cordis": "4.0.2",
|
|
74
74
|
"quickjs-emscripten": "0.32.0",
|
|
75
75
|
"typebox": "1.3.34"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
|
-
"@agimon-ai/doompi-build": "0.0.1-alpha.
|
|
79
|
-
"@agimon-ai/vibe-lint-plugin-doom-extension": "0.0.1-alpha.
|
|
78
|
+
"@agimon-ai/doompi-build": "0.0.1-alpha.15",
|
|
79
|
+
"@agimon-ai/vibe-lint-plugin-doom-extension": "0.0.1-alpha.81",
|
|
80
80
|
"@earendil-works/pi-coding-agent": "0.87.1",
|
|
81
81
|
"@tanstack/react-store": "0.11.1",
|
|
82
82
|
"@tanstack/store": "0.11.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extensionService-BJXeNc4R.mjs","names":[],"sources":["../src/constants/computerUse.ts","../src/services/computerScriptWorker/index.ts","../src/services/computerScriptRunner/index.ts","../src/services/extensionService/index.ts"],"sourcesContent":["export const COMPUTER_USE_GUIDANCE = `[COMPUTER USE ACTIVE]\nUse computer_state before acting and after any action that may change the interface. Use only element refs and snapshot ids returned by computer_state. Use computer_action for one semantic press, focus, set_value, or scroll at a time. Use computer_exec only for a trusted, explicitly allowed local TypeScript script. Never infer coordinates, inspect another application, bypass secure elements, or retry an uncertain outcome. Stop computer use when the task is complete.`;\nexport const COMMAND_NAME = 'computer-use';\nexport const COMMAND_DESCRIPTION = 'Inspect or manage the session computer use mode';\n\nexport const COMPUTER_USE_TOOL_NAMES = ['computer_state', 'computer_action', 'computer_exec'] as const;\n","/** Source for an isolated child process. Restricted modules execute in QuickJS, not in Node's realm. */\nexport const COMPUTER_SCRIPT_WORKER_SOURCE = String.raw`\nimport { readFileSync, realpathSync, statSync } from 'node:fs';\nimport path from 'node:path';\nimport { stripTypeScriptTypes } from 'node:module';\nimport { pathToFileURL } from 'node:url';\n\nlet nextRequestId = 0;\nlet started = false;\nconst pending = new Map();\nconst controller = new AbortController();\nprocess.once('SIGTERM', () => controller.abort());\nconst send = (message) => {\n if (process.connected) process.send(message, () => {});\n};\nconst call = (operation, payload) => new Promise((resolve, reject) => {\n if (controller.signal.aborted) return reject(new Error('Computer script was cancelled.'));\n if (pending.size >= 64) return reject(new Error('Too many outstanding program operations.'));\n const id = String(++nextRequestId);\n pending.set(id, { resolve, reject });\n send({ type: 'program', id, operation, payload });\n});\n\nasync function restricted(message) {\n const { getQuickJS } = await import(pathToFileURL(message.quickjsPath).href);\n const QuickJS = await getQuickJS();\n const runtime = QuickJS.newRuntime();\n runtime.setMemoryLimit(32 * 1024 * 1024);\n runtime.setMaxStackSize(512 * 1024);\n const deadline = Date.now() + message.timeoutMs;\n runtime.setInterruptHandler(() => controller.signal.aborted || Date.now() >= deadline);\n const root = realpathSync(message.scriptRoot);\n const sources = new Map();\n let sourceBytes = 0;\n let moduleFailure;\n const modulePath = (candidate) => {\n const filename = realpathSync(candidate);\n const relative = path.relative(root, filename);\n if (relative === '..' || relative.startsWith('..' + path.sep) || path.isAbsolute(relative)) {\n throw new Error('Computer helper escapes the admitted script root.');\n }\n if (!/\\.(ts|js|mjs)$/.test(filename)) throw new Error('Computer helpers must be JavaScript or erasable TypeScript.');\n return filename;\n };\n const entry = modulePath(message.scriptPath);\n runtime.setModuleLoader((filename) => {\n // Preserve a rejected normalization even if the engine subsequently asks to load an empty name.\n if (moduleFailure) throw moduleFailure;\n if (sources.has(filename)) return sources.get(filename);\n if (sources.size >= 32 || statSync(filename).size > 256 * 1024) throw new Error('Computer script module limit exceeded.');\n const source = readFileSync(filename, 'utf8');\n sourceBytes += Buffer.byteLength(source);\n if (sourceBytes > 512 * 1024) throw new Error('Computer script source limit exceeded.');\n const compiled = filename.endsWith('.ts') ? stripTypeScriptTypes(source, { mode: 'strip' }) : source;\n sources.set(filename, compiled);\n return compiled;\n }, (base, name) => {\n try {\n if (name === '__entry__') return entry;\n if (!name.startsWith('./') && !name.startsWith('../')) {\n throw new Error('Restricted computer functions cannot import host or package modules.');\n }\n return modulePath(path.resolve(path.dirname(base), name));\n } catch (error) {\n moduleFailure = error;\n throw error;\n }\n });\n const vm = runtime.newContext();\n let disposed = false;\n const deferreds = new Set();\n const pump = () => {\n if (disposed) return;\n const jobs = runtime.executePendingJobs();\n if (jobs.error) {\n const detail = vm.dump(jobs.error);\n jobs.error.dispose();\n throw new Error(detail?.message ?? String(detail));\n }\n };\n const set = (name, value) => {\n vm.setProp(vm.global, name, value);\n value.dispose();\n };\n set('__input', vm.newString(JSON.stringify(message.input)));\n set('__aborted', vm.newFunction('__aborted', () => controller.signal.aborted ? vm.true : vm.false));\n set('__log', vm.newFunction('__log', (level, text) => {\n send({ type: 'log', level: vm.getString(level), message: vm.getString(text) });\n }));\n set('__call', vm.newFunction('__call', (operationHandle, payloadHandle) => {\n const operation = vm.getString(operationHandle);\n const serialized = vm.getString(payloadHandle);\n if (serialized.length > message.maxOutputBytes) throw new Error('Computer action exceeds the size limit.');\n if (operation !== 'observe' && operation !== 'act') throw new Error('Unsupported program operation.');\n const deferred = vm.newPromise();\n deferreds.add(deferred);\n call(operation, JSON.parse(serialized)).then((value) => {\n if (disposed) return;\n const handle = vm.newString(JSON.stringify(value));\n deferred.resolve(handle);\n handle.dispose();\n }, (error) => {\n if (disposed) return;\n const handle = vm.newError(error.message);\n deferred.reject(handle);\n handle.dispose();\n }).then(() => {\n if (disposed) return;\n deferred.dispose();\n deferreds.delete(deferred);\n pump();\n }).catch((error) => send({ type: 'failed', error: error.message }));\n return deferred.handle.dup();\n }));\n let evaluation;\n try {\n evaluation = vm.unwrapResult(vm.evalCode(\n 'import { run } from \"__entry__\";\\n' +\n 'const invoke = __call; const log = __log; const isAborted = __aborted;\\n' +\n 'const program = Object.freeze({\\n' +\n ' observe: async (options = {}) => JSON.parse(await invoke(\"observe\", JSON.stringify(options))),\\n' +\n ' act: async (action) => JSON.parse(await invoke(\"act\", JSON.stringify(action)))\\n' +\n '});\\n' +\n 'const logger = Object.freeze(Object.fromEntries([\"debug\",\"info\",\"warn\",\"error\"].map(level => [level, value => log(level, String(value))])));\\n' +\n 'const signal = Object.freeze({ get aborted() { return isAborted(); }, throwIfAborted() { if (isAborted()) throw new Error(\"Computer script was cancelled.\"); } });\\n' +\n 'const result = await run({ context: { program }, input: JSON.parse(__input), logger, signal });\\n' +\n 'globalThis.__result = result === undefined ? undefined : JSON.stringify(result);',\n path.join(root, '__computer_entry__.mjs'), { type: 'module' },\n ));\n const completion = vm.resolvePromise(evaluation);\n pump();\n const completed = vm.unwrapResult(await completion);\n completed.dispose();\n const result = vm.getProp(vm.global, '__result');\n const resultJson = vm.dump(result);\n result.dispose();\n return resultJson;\n } finally {\n disposed = true;\n for (const deferred of deferreds) deferred.dispose();\n evaluation?.dispose();\n vm.dispose();\n runtime.dispose();\n }\n}\n\nprocess.on('message', async (message) => {\n if (message?.type === 'response') {\n const request = pending.get(message.id);\n if (!request) return;\n pending.delete(message.id);\n if (message.error) request.reject(new Error(message.error));\n else request.resolve(message.value);\n return;\n }\n if (message?.type !== 'start' || started) return;\n started = true;\n try {\n let resultJson;\n if (message.trusted) {\n const loaded = await import(pathToFileURL(message.scriptPath).href);\n if (typeof loaded.run !== 'function') throw new Error('Computer script must export a named run function.');\n const program = {\n observe: (options = {}) => call('observe', options),\n act: (action) => call('act', action),\n };\n const logger = Object.fromEntries(['debug','info','warn','error'].map(level => [level, value => {\n send({ type: 'log', level, message: String(value) });\n }]));\n const result = await loaded.run({ context: { program }, input: message.input, logger, signal: controller.signal });\n resultJson = result === undefined ? undefined : JSON.stringify(result);\n } else {\n resultJson = await restricted(message);\n }\n if (typeof resultJson === 'string' && Buffer.byteLength(resultJson) > message.maxOutputBytes) {\n throw new Error('Computer script result exceeded the size limit.');\n }\n send({ type: 'complete', resultJson });\n } catch (error) {\n send({ type: 'failed', error: String(error?.message ?? error).slice(0, 1024) });\n }\n});\n`;\n","import { spawn } from 'node:child_process';\nimport { realpath } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport type {\n ComputerScriptExecutionOptions,\n ComputerScriptExecutionResult,\n ComputerScriptRunnerOptions,\n} from '../../types/computerScript';\nimport type { ComputerUseAction, ComputerUseObservation, ComputerUseSessionClient } from '../../types/computerUse';\nimport { COMPUTER_SCRIPT_WORKER_SOURCE } from '../computerScriptWorker';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_OUTPUT_BYTES = 256 * 1024;\nconst MAX_IMAGE_BYTES = 6 * 1024 * 1024;\nconst MAX_PENDING_OPERATIONS = 64;\n\nexport class ComputerScriptExecutionError extends Error {\n constructor(\n message: string,\n readonly completedActions: number,\n readonly outcomeUncertain: boolean,\n ) {\n super(message);\n this.name = 'ComputerScriptExecutionError';\n }\n}\n\ninterface WorkerMessage {\n readonly type?: unknown;\n readonly id?: unknown;\n readonly operation?: unknown;\n readonly payload?: unknown;\n readonly level?: unknown;\n readonly message?: unknown;\n readonly resultJson?: unknown;\n readonly error?: unknown;\n}\n\nexport class ComputerScriptRunner {\n private readonly client: ComputerUseSessionClient;\n private readonly allowedScriptPaths: readonly string[];\n private readonly scriptRoot?: string;\n private readonly timeoutMs: number;\n private readonly maxOutputBytes: number;\n\n constructor(options: ComputerScriptRunnerOptions) {\n this.client = options.client;\n this.allowedScriptPaths = options.allowedScriptPaths;\n this.scriptRoot = options.scriptRoot;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;\n }\n\n async execute(\n scriptPath: string,\n input: unknown,\n signal?: AbortSignal,\n options: ComputerScriptExecutionOptions = {},\n ): Promise<ComputerScriptExecutionResult> {\n signal?.throwIfAborted();\n const resolvedPath = await realpath(path.resolve(this.scriptRoot ?? process.cwd(), scriptPath));\n const allowedPaths = await Promise.all(\n this.allowedScriptPaths.map(async (candidate) => realpath(candidate).catch(() => '')),\n );\n const trusted = options.trusted === true;\n if ((trusted || this.scriptRoot === undefined) && !allowedPaths.includes(resolvedPath)) {\n throw new Error('Computer script path is not explicitly allowed.');\n }\n if (!/\\.(ts|js|mjs)$/u.test(resolvedPath))\n throw new Error('Computer scripts must be JavaScript or erasable TypeScript files.');\n const root = await realpath(this.scriptRoot ?? path.dirname(resolvedPath));\n const relative = path.relative(root, resolvedPath);\n if (!trusted && (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative))) {\n throw new Error('Computer script escapes the admitted script root.');\n }\n const serializedInput = JSON.stringify(input);\n if (serializedInput === undefined) throw new Error('Computer script input must be JSON serializable.');\n if (Buffer.byteLength(serializedInput) > this.maxOutputBytes)\n throw new Error('Computer script input exceeds the size limit.');\n const quickjsPath = trusted ? undefined : createRequire(import.meta.url).resolve('quickjs-emscripten');\n signal?.throwIfAborted();\n const started = performance.now();\n\n return new Promise((resolve, reject) => {\n const child = spawn(process.execPath, ['--input-type=module', '--eval', COMPUTER_SCRIPT_WORKER_SOURCE], {\n stdio: ['ignore', 'pipe', 'pipe', 'ipc'],\n // Preserve Electron's Node mode, but no host credentials, for restricted workers.\n env: trusted ? process.env : { ELECTRON_RUN_AS_NODE: '1' },\n });\n const controller = new AbortController();\n const logs: string[] = [];\n let outputBytes = 0;\n let completedActions = 0;\n let observations = 0;\n let actionInFlight = false;\n let settled = false;\n let completing = false;\n let outstanding = 0;\n let operation: Promise<void> = Promise.resolve();\n const finish = (error?: Error, value?: ComputerScriptExecutionResult): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timeout);\n signal?.removeEventListener('abort', onAbort);\n controller.abort();\n child.kill('SIGTERM');\n const killTimer = setTimeout(() => child.kill('SIGKILL'), 250);\n killTimer.unref();\n if (error) reject(new ComputerScriptExecutionError(error.message, completedActions, actionInFlight));\n else resolve(value!);\n };\n const addOutput = (value: string): boolean => {\n outputBytes += Buffer.byteLength(value);\n if (outputBytes <= this.maxOutputBytes) return true;\n finish(new Error('Computer script output exceeded the size limit.'));\n return false;\n };\n const send = (value: object): void => {\n if (settled || !child.connected) return;\n child.send(value, (error) => {\n if (error && !settled) finish(error);\n });\n };\n const onAbort = (): void => finish(new Error('Computer script execution was cancelled.'));\n const timeout = setTimeout(() => finish(new Error('Computer script execution timed out.')), this.timeoutMs);\n timeout.unref();\n signal?.addEventListener('abort', onAbort, { once: true });\n if (signal?.aborted) return onAbort();\n child.stdout?.on('data', (chunk: Buffer) => addOutput(chunk.toString('utf8')));\n child.stderr?.on('data', (chunk: Buffer) => addOutput(chunk.toString('utf8')));\n child.on('error', (error) => finish(error));\n child.on('exit', (code, exitSignal) => {\n if (!settled)\n finish(new Error(`Computer script worker exited before completion (${exitSignal ?? code ?? 'unknown'}).`));\n });\n\n const observe = async (includeScreenshot: boolean): Promise<ComputerUseObservation> => {\n const value = await this.client.observe(controller.signal, { includeScreenshot });\n observations += 1;\n const { screenshot, ...semantic } = value;\n if (Buffer.byteLength(JSON.stringify(semantic)) > this.maxOutputBytes)\n throw new Error('Computer observation exceeds the size limit.');\n if (includeScreenshot && screenshot) {\n if (screenshot.mimeType !== 'image/png' || screenshot.data.length > Math.ceil(MAX_IMAGE_BYTES / 3) * 4) {\n throw new Error('Computer screenshot exceeds the image limit.');\n }\n return { ...semantic, screenshot };\n }\n return semantic;\n };\n\n child.on('message', (raw: WorkerMessage) => {\n if (settled) return;\n if (!raw || typeof raw !== 'object' || Buffer.byteLength(JSON.stringify(raw)) > this.maxOutputBytes + 4096) {\n finish(new Error('Computer worker message exceeds the size limit.'));\n return;\n }\n if (raw.type === 'log' && typeof raw.message === 'string') {\n const line = `[${String(raw.level)}] ${raw.message}`;\n if (addOutput(line)) logs.push(line);\n return;\n }\n if (raw.type === 'program') {\n if (\n completing ||\n typeof raw.id !== 'string' ||\n raw.id.length > 128 ||\n (raw.operation !== 'observe' && raw.operation !== 'act') ||\n outstanding >= MAX_PENDING_OPERATIONS\n ) {\n finish(new Error('Invalid or excessive computer program operations.'));\n return;\n }\n outstanding += 1;\n operation = operation\n .then(async () => {\n if (settled || controller.signal.aborted) return;\n try {\n let value: unknown;\n if (raw.operation === 'observe') {\n const settings = raw.payload;\n if (\n !settings ||\n typeof settings !== 'object' ||\n Array.isArray(settings) ||\n Object.keys(settings).some((key) => key !== 'includeScreenshot') ||\n ('includeScreenshot' in settings && typeof settings.includeScreenshot !== 'boolean')\n ) {\n throw new Error('Invalid observation options.');\n }\n value = await observe('includeScreenshot' in settings && settings.includeScreenshot === true);\n } else {\n actionInFlight = true;\n value = await this.client.act(raw.payload as ComputerUseAction, controller.signal);\n completedActions += 1;\n actionInFlight = false;\n }\n send({ type: 'response', id: raw.id, value });\n } catch (error) {\n // An action can have taken effect before its transport failed. Never run the remaining chain.\n if (actionInFlight) finish(error instanceof Error ? error : new Error(String(error)));\n else\n send({ type: 'response', id: raw.id, error: error instanceof Error ? error.message : String(error) });\n } finally {\n outstanding -= 1;\n }\n })\n .catch((error: unknown) => finish(error instanceof Error ? error : new Error(String(error))));\n return;\n }\n if (raw.type === 'failed' && typeof raw.error === 'string') {\n finish(new Error(raw.error));\n return;\n }\n if (raw.type === 'complete') {\n if (completing) {\n finish(new Error('Computer worker completed twice.'));\n return;\n }\n completing = true;\n operation = operation\n .then(async () => {\n if (settled) return;\n const resultJson = raw.resultJson;\n if (resultJson !== undefined && typeof resultJson !== 'string')\n throw new Error('Computer script returned an invalid result.');\n if (typeof resultJson === 'string' && !addOutput(resultJson)) return;\n const observation = await observe(options.includeScreenshot === true);\n if (settled || !addOutput(JSON.stringify({ ...observation, screenshot: undefined }))) return;\n finish(undefined, {\n ...(typeof resultJson === 'string' ? { result: JSON.parse(resultJson) as unknown } : {}),\n observation,\n logs,\n metrics: {\n actions: completedActions,\n observations,\n durationMs: Math.round(performance.now() - started),\n outputBytes,\n },\n });\n })\n .catch((error: unknown) => finish(error instanceof Error ? error : new Error(String(error))));\n }\n });\n send({\n type: 'start',\n scriptPath: resolvedPath,\n scriptRoot: root,\n input: JSON.parse(serializedInput) as unknown,\n trusted,\n quickjsPath,\n timeoutMs: this.timeoutMs,\n maxOutputBytes: this.maxOutputBytes,\n });\n });\n }\n}\n","import type { ComputerUseExtensionResult, ComputerUseExtensionService } from '../../types/extension';\nimport type { ComputerUseSessionClient } from '../sessionApiClient';\n\nexport class DefaultComputerUseExtensionService implements ComputerUseExtensionService {\n public constructor(private readonly client?: ComputerUseSessionClient) {}\n\n public async execute(): Promise<ComputerUseExtensionResult> {\n if (this.client === undefined)\n return { message: 'Computer use requires a DoomPi Desktop session.', level: 'error' };\n const state = await this.client.state();\n return { message: `Computer use is ${state.phase.replaceAll('_', ' ')}.`, level: 'info' };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extensionService-CZS-zDP0.cjs","names":["realpath","path","createRequire","spawn"],"sources":["../src/constants/computerUse.ts","../src/services/computerScriptWorker/index.ts","../src/services/computerScriptRunner/index.ts","../src/services/extensionService/index.ts"],"sourcesContent":["export const COMPUTER_USE_GUIDANCE = `[COMPUTER USE ACTIVE]\nUse computer_state before acting and after any action that may change the interface. Use only element refs and snapshot ids returned by computer_state. Use computer_action for one semantic press, focus, set_value, or scroll at a time. Use computer_exec only for a trusted, explicitly allowed local TypeScript script. Never infer coordinates, inspect another application, bypass secure elements, or retry an uncertain outcome. Stop computer use when the task is complete.`;\nexport const COMMAND_NAME = 'computer-use';\nexport const COMMAND_DESCRIPTION = 'Inspect or manage the session computer use mode';\n\nexport const COMPUTER_USE_TOOL_NAMES = ['computer_state', 'computer_action', 'computer_exec'] as const;\n","/** Source for an isolated child process. Restricted modules execute in QuickJS, not in Node's realm. */\nexport const COMPUTER_SCRIPT_WORKER_SOURCE = String.raw`\nimport { readFileSync, realpathSync, statSync } from 'node:fs';\nimport path from 'node:path';\nimport { stripTypeScriptTypes } from 'node:module';\nimport { pathToFileURL } from 'node:url';\n\nlet nextRequestId = 0;\nlet started = false;\nconst pending = new Map();\nconst controller = new AbortController();\nprocess.once('SIGTERM', () => controller.abort());\nconst send = (message) => {\n if (process.connected) process.send(message, () => {});\n};\nconst call = (operation, payload) => new Promise((resolve, reject) => {\n if (controller.signal.aborted) return reject(new Error('Computer script was cancelled.'));\n if (pending.size >= 64) return reject(new Error('Too many outstanding program operations.'));\n const id = String(++nextRequestId);\n pending.set(id, { resolve, reject });\n send({ type: 'program', id, operation, payload });\n});\n\nasync function restricted(message) {\n const { getQuickJS } = await import(pathToFileURL(message.quickjsPath).href);\n const QuickJS = await getQuickJS();\n const runtime = QuickJS.newRuntime();\n runtime.setMemoryLimit(32 * 1024 * 1024);\n runtime.setMaxStackSize(512 * 1024);\n const deadline = Date.now() + message.timeoutMs;\n runtime.setInterruptHandler(() => controller.signal.aborted || Date.now() >= deadline);\n const root = realpathSync(message.scriptRoot);\n const sources = new Map();\n let sourceBytes = 0;\n let moduleFailure;\n const modulePath = (candidate) => {\n const filename = realpathSync(candidate);\n const relative = path.relative(root, filename);\n if (relative === '..' || relative.startsWith('..' + path.sep) || path.isAbsolute(relative)) {\n throw new Error('Computer helper escapes the admitted script root.');\n }\n if (!/\\.(ts|js|mjs)$/.test(filename)) throw new Error('Computer helpers must be JavaScript or erasable TypeScript.');\n return filename;\n };\n const entry = modulePath(message.scriptPath);\n runtime.setModuleLoader((filename) => {\n // Preserve a rejected normalization even if the engine subsequently asks to load an empty name.\n if (moduleFailure) throw moduleFailure;\n if (sources.has(filename)) return sources.get(filename);\n if (sources.size >= 32 || statSync(filename).size > 256 * 1024) throw new Error('Computer script module limit exceeded.');\n const source = readFileSync(filename, 'utf8');\n sourceBytes += Buffer.byteLength(source);\n if (sourceBytes > 512 * 1024) throw new Error('Computer script source limit exceeded.');\n const compiled = filename.endsWith('.ts') ? stripTypeScriptTypes(source, { mode: 'strip' }) : source;\n sources.set(filename, compiled);\n return compiled;\n }, (base, name) => {\n try {\n if (name === '__entry__') return entry;\n if (!name.startsWith('./') && !name.startsWith('../')) {\n throw new Error('Restricted computer functions cannot import host or package modules.');\n }\n return modulePath(path.resolve(path.dirname(base), name));\n } catch (error) {\n moduleFailure = error;\n throw error;\n }\n });\n const vm = runtime.newContext();\n let disposed = false;\n const deferreds = new Set();\n const pump = () => {\n if (disposed) return;\n const jobs = runtime.executePendingJobs();\n if (jobs.error) {\n const detail = vm.dump(jobs.error);\n jobs.error.dispose();\n throw new Error(detail?.message ?? String(detail));\n }\n };\n const set = (name, value) => {\n vm.setProp(vm.global, name, value);\n value.dispose();\n };\n set('__input', vm.newString(JSON.stringify(message.input)));\n set('__aborted', vm.newFunction('__aborted', () => controller.signal.aborted ? vm.true : vm.false));\n set('__log', vm.newFunction('__log', (level, text) => {\n send({ type: 'log', level: vm.getString(level), message: vm.getString(text) });\n }));\n set('__call', vm.newFunction('__call', (operationHandle, payloadHandle) => {\n const operation = vm.getString(operationHandle);\n const serialized = vm.getString(payloadHandle);\n if (serialized.length > message.maxOutputBytes) throw new Error('Computer action exceeds the size limit.');\n if (operation !== 'observe' && operation !== 'act') throw new Error('Unsupported program operation.');\n const deferred = vm.newPromise();\n deferreds.add(deferred);\n call(operation, JSON.parse(serialized)).then((value) => {\n if (disposed) return;\n const handle = vm.newString(JSON.stringify(value));\n deferred.resolve(handle);\n handle.dispose();\n }, (error) => {\n if (disposed) return;\n const handle = vm.newError(error.message);\n deferred.reject(handle);\n handle.dispose();\n }).then(() => {\n if (disposed) return;\n deferred.dispose();\n deferreds.delete(deferred);\n pump();\n }).catch((error) => send({ type: 'failed', error: error.message }));\n return deferred.handle.dup();\n }));\n let evaluation;\n try {\n evaluation = vm.unwrapResult(vm.evalCode(\n 'import { run } from \"__entry__\";\\n' +\n 'const invoke = __call; const log = __log; const isAborted = __aborted;\\n' +\n 'const program = Object.freeze({\\n' +\n ' observe: async (options = {}) => JSON.parse(await invoke(\"observe\", JSON.stringify(options))),\\n' +\n ' act: async (action) => JSON.parse(await invoke(\"act\", JSON.stringify(action)))\\n' +\n '});\\n' +\n 'const logger = Object.freeze(Object.fromEntries([\"debug\",\"info\",\"warn\",\"error\"].map(level => [level, value => log(level, String(value))])));\\n' +\n 'const signal = Object.freeze({ get aborted() { return isAborted(); }, throwIfAborted() { if (isAborted()) throw new Error(\"Computer script was cancelled.\"); } });\\n' +\n 'const result = await run({ context: { program }, input: JSON.parse(__input), logger, signal });\\n' +\n 'globalThis.__result = result === undefined ? undefined : JSON.stringify(result);',\n path.join(root, '__computer_entry__.mjs'), { type: 'module' },\n ));\n const completion = vm.resolvePromise(evaluation);\n pump();\n const completed = vm.unwrapResult(await completion);\n completed.dispose();\n const result = vm.getProp(vm.global, '__result');\n const resultJson = vm.dump(result);\n result.dispose();\n return resultJson;\n } finally {\n disposed = true;\n for (const deferred of deferreds) deferred.dispose();\n evaluation?.dispose();\n vm.dispose();\n runtime.dispose();\n }\n}\n\nprocess.on('message', async (message) => {\n if (message?.type === 'response') {\n const request = pending.get(message.id);\n if (!request) return;\n pending.delete(message.id);\n if (message.error) request.reject(new Error(message.error));\n else request.resolve(message.value);\n return;\n }\n if (message?.type !== 'start' || started) return;\n started = true;\n try {\n let resultJson;\n if (message.trusted) {\n const loaded = await import(pathToFileURL(message.scriptPath).href);\n if (typeof loaded.run !== 'function') throw new Error('Computer script must export a named run function.');\n const program = {\n observe: (options = {}) => call('observe', options),\n act: (action) => call('act', action),\n };\n const logger = Object.fromEntries(['debug','info','warn','error'].map(level => [level, value => {\n send({ type: 'log', level, message: String(value) });\n }]));\n const result = await loaded.run({ context: { program }, input: message.input, logger, signal: controller.signal });\n resultJson = result === undefined ? undefined : JSON.stringify(result);\n } else {\n resultJson = await restricted(message);\n }\n if (typeof resultJson === 'string' && Buffer.byteLength(resultJson) > message.maxOutputBytes) {\n throw new Error('Computer script result exceeded the size limit.');\n }\n send({ type: 'complete', resultJson });\n } catch (error) {\n send({ type: 'failed', error: String(error?.message ?? error).slice(0, 1024) });\n }\n});\n`;\n","import { spawn } from 'node:child_process';\nimport { realpath } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport type {\n ComputerScriptExecutionOptions,\n ComputerScriptExecutionResult,\n ComputerScriptRunnerOptions,\n} from '../../types/computerScript';\nimport type { ComputerUseAction, ComputerUseObservation, ComputerUseSessionClient } from '../../types/computerUse';\nimport { COMPUTER_SCRIPT_WORKER_SOURCE } from '../computerScriptWorker';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_OUTPUT_BYTES = 256 * 1024;\nconst MAX_IMAGE_BYTES = 6 * 1024 * 1024;\nconst MAX_PENDING_OPERATIONS = 64;\n\nexport class ComputerScriptExecutionError extends Error {\n constructor(\n message: string,\n readonly completedActions: number,\n readonly outcomeUncertain: boolean,\n ) {\n super(message);\n this.name = 'ComputerScriptExecutionError';\n }\n}\n\ninterface WorkerMessage {\n readonly type?: unknown;\n readonly id?: unknown;\n readonly operation?: unknown;\n readonly payload?: unknown;\n readonly level?: unknown;\n readonly message?: unknown;\n readonly resultJson?: unknown;\n readonly error?: unknown;\n}\n\nexport class ComputerScriptRunner {\n private readonly client: ComputerUseSessionClient;\n private readonly allowedScriptPaths: readonly string[];\n private readonly scriptRoot?: string;\n private readonly timeoutMs: number;\n private readonly maxOutputBytes: number;\n\n constructor(options: ComputerScriptRunnerOptions) {\n this.client = options.client;\n this.allowedScriptPaths = options.allowedScriptPaths;\n this.scriptRoot = options.scriptRoot;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;\n }\n\n async execute(\n scriptPath: string,\n input: unknown,\n signal?: AbortSignal,\n options: ComputerScriptExecutionOptions = {},\n ): Promise<ComputerScriptExecutionResult> {\n signal?.throwIfAborted();\n const resolvedPath = await realpath(path.resolve(this.scriptRoot ?? process.cwd(), scriptPath));\n const allowedPaths = await Promise.all(\n this.allowedScriptPaths.map(async (candidate) => realpath(candidate).catch(() => '')),\n );\n const trusted = options.trusted === true;\n if ((trusted || this.scriptRoot === undefined) && !allowedPaths.includes(resolvedPath)) {\n throw new Error('Computer script path is not explicitly allowed.');\n }\n if (!/\\.(ts|js|mjs)$/u.test(resolvedPath))\n throw new Error('Computer scripts must be JavaScript or erasable TypeScript files.');\n const root = await realpath(this.scriptRoot ?? path.dirname(resolvedPath));\n const relative = path.relative(root, resolvedPath);\n if (!trusted && (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative))) {\n throw new Error('Computer script escapes the admitted script root.');\n }\n const serializedInput = JSON.stringify(input);\n if (serializedInput === undefined) throw new Error('Computer script input must be JSON serializable.');\n if (Buffer.byteLength(serializedInput) > this.maxOutputBytes)\n throw new Error('Computer script input exceeds the size limit.');\n const quickjsPath = trusted ? undefined : createRequire(import.meta.url).resolve('quickjs-emscripten');\n signal?.throwIfAborted();\n const started = performance.now();\n\n return new Promise((resolve, reject) => {\n const child = spawn(process.execPath, ['--input-type=module', '--eval', COMPUTER_SCRIPT_WORKER_SOURCE], {\n stdio: ['ignore', 'pipe', 'pipe', 'ipc'],\n // Preserve Electron's Node mode, but no host credentials, for restricted workers.\n env: trusted ? process.env : { ELECTRON_RUN_AS_NODE: '1' },\n });\n const controller = new AbortController();\n const logs: string[] = [];\n let outputBytes = 0;\n let completedActions = 0;\n let observations = 0;\n let actionInFlight = false;\n let settled = false;\n let completing = false;\n let outstanding = 0;\n let operation: Promise<void> = Promise.resolve();\n const finish = (error?: Error, value?: ComputerScriptExecutionResult): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timeout);\n signal?.removeEventListener('abort', onAbort);\n controller.abort();\n child.kill('SIGTERM');\n const killTimer = setTimeout(() => child.kill('SIGKILL'), 250);\n killTimer.unref();\n if (error) reject(new ComputerScriptExecutionError(error.message, completedActions, actionInFlight));\n else resolve(value!);\n };\n const addOutput = (value: string): boolean => {\n outputBytes += Buffer.byteLength(value);\n if (outputBytes <= this.maxOutputBytes) return true;\n finish(new Error('Computer script output exceeded the size limit.'));\n return false;\n };\n const send = (value: object): void => {\n if (settled || !child.connected) return;\n child.send(value, (error) => {\n if (error && !settled) finish(error);\n });\n };\n const onAbort = (): void => finish(new Error('Computer script execution was cancelled.'));\n const timeout = setTimeout(() => finish(new Error('Computer script execution timed out.')), this.timeoutMs);\n timeout.unref();\n signal?.addEventListener('abort', onAbort, { once: true });\n if (signal?.aborted) return onAbort();\n child.stdout?.on('data', (chunk: Buffer) => addOutput(chunk.toString('utf8')));\n child.stderr?.on('data', (chunk: Buffer) => addOutput(chunk.toString('utf8')));\n child.on('error', (error) => finish(error));\n child.on('exit', (code, exitSignal) => {\n if (!settled)\n finish(new Error(`Computer script worker exited before completion (${exitSignal ?? code ?? 'unknown'}).`));\n });\n\n const observe = async (includeScreenshot: boolean): Promise<ComputerUseObservation> => {\n const value = await this.client.observe(controller.signal, { includeScreenshot });\n observations += 1;\n const { screenshot, ...semantic } = value;\n if (Buffer.byteLength(JSON.stringify(semantic)) > this.maxOutputBytes)\n throw new Error('Computer observation exceeds the size limit.');\n if (includeScreenshot && screenshot) {\n if (screenshot.mimeType !== 'image/png' || screenshot.data.length > Math.ceil(MAX_IMAGE_BYTES / 3) * 4) {\n throw new Error('Computer screenshot exceeds the image limit.');\n }\n return { ...semantic, screenshot };\n }\n return semantic;\n };\n\n child.on('message', (raw: WorkerMessage) => {\n if (settled) return;\n if (!raw || typeof raw !== 'object' || Buffer.byteLength(JSON.stringify(raw)) > this.maxOutputBytes + 4096) {\n finish(new Error('Computer worker message exceeds the size limit.'));\n return;\n }\n if (raw.type === 'log' && typeof raw.message === 'string') {\n const line = `[${String(raw.level)}] ${raw.message}`;\n if (addOutput(line)) logs.push(line);\n return;\n }\n if (raw.type === 'program') {\n if (\n completing ||\n typeof raw.id !== 'string' ||\n raw.id.length > 128 ||\n (raw.operation !== 'observe' && raw.operation !== 'act') ||\n outstanding >= MAX_PENDING_OPERATIONS\n ) {\n finish(new Error('Invalid or excessive computer program operations.'));\n return;\n }\n outstanding += 1;\n operation = operation\n .then(async () => {\n if (settled || controller.signal.aborted) return;\n try {\n let value: unknown;\n if (raw.operation === 'observe') {\n const settings = raw.payload;\n if (\n !settings ||\n typeof settings !== 'object' ||\n Array.isArray(settings) ||\n Object.keys(settings).some((key) => key !== 'includeScreenshot') ||\n ('includeScreenshot' in settings && typeof settings.includeScreenshot !== 'boolean')\n ) {\n throw new Error('Invalid observation options.');\n }\n value = await observe('includeScreenshot' in settings && settings.includeScreenshot === true);\n } else {\n actionInFlight = true;\n value = await this.client.act(raw.payload as ComputerUseAction, controller.signal);\n completedActions += 1;\n actionInFlight = false;\n }\n send({ type: 'response', id: raw.id, value });\n } catch (error) {\n // An action can have taken effect before its transport failed. Never run the remaining chain.\n if (actionInFlight) finish(error instanceof Error ? error : new Error(String(error)));\n else\n send({ type: 'response', id: raw.id, error: error instanceof Error ? error.message : String(error) });\n } finally {\n outstanding -= 1;\n }\n })\n .catch((error: unknown) => finish(error instanceof Error ? error : new Error(String(error))));\n return;\n }\n if (raw.type === 'failed' && typeof raw.error === 'string') {\n finish(new Error(raw.error));\n return;\n }\n if (raw.type === 'complete') {\n if (completing) {\n finish(new Error('Computer worker completed twice.'));\n return;\n }\n completing = true;\n operation = operation\n .then(async () => {\n if (settled) return;\n const resultJson = raw.resultJson;\n if (resultJson !== undefined && typeof resultJson !== 'string')\n throw new Error('Computer script returned an invalid result.');\n if (typeof resultJson === 'string' && !addOutput(resultJson)) return;\n const observation = await observe(options.includeScreenshot === true);\n if (settled || !addOutput(JSON.stringify({ ...observation, screenshot: undefined }))) return;\n finish(undefined, {\n ...(typeof resultJson === 'string' ? { result: JSON.parse(resultJson) as unknown } : {}),\n observation,\n logs,\n metrics: {\n actions: completedActions,\n observations,\n durationMs: Math.round(performance.now() - started),\n outputBytes,\n },\n });\n })\n .catch((error: unknown) => finish(error instanceof Error ? error : new Error(String(error))));\n }\n });\n send({\n type: 'start',\n scriptPath: resolvedPath,\n scriptRoot: root,\n input: JSON.parse(serializedInput) as unknown,\n trusted,\n quickjsPath,\n timeoutMs: this.timeoutMs,\n maxOutputBytes: this.maxOutputBytes,\n });\n });\n }\n}\n","import type { ComputerUseExtensionResult, ComputerUseExtensionService } from '../../types/extension';\nimport type { ComputerUseSessionClient } from '../sessionApiClient';\n\nexport class DefaultComputerUseExtensionService implements ComputerUseExtensionService {\n public constructor(private readonly client?: ComputerUseSessionClient) {}\n\n public async execute(): Promise<ComputerUseExtensionResult> {\n if (this.client === undefined)\n return { message: 'Computer use requires a DoomPi Desktop session.', level: 'error' };\n const state = await this.client.state();\n return { message: `Computer use is ${state.phase.replaceAll('_', ' ')}.`, level: 'info' };\n }\n}\n"],"mappings":"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"}
|