@agimon-ai/doompi-computer-use 0.0.1-alpha.11 → 0.0.1-alpha.2

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.
Files changed (95) hide show
  1. package/README.md +3 -6
  2. package/dist/adapters/computerUseApi.cjs +1 -1
  3. package/dist/adapters/computerUseApi.cjs.map +1 -1
  4. package/dist/adapters/computerUseApi.d.cts +5 -9
  5. package/dist/adapters/computerUseApi.d.cts.map +1 -1
  6. package/dist/adapters/computerUseApi.d.mts +5 -9
  7. package/dist/adapters/computerUseApi.d.mts.map +1 -1
  8. package/dist/adapters/computerUseApi.mjs +1 -1
  9. package/dist/adapters/computerUseApi.mjs.map +1 -1
  10. package/dist/adapters/pi/extension.cjs +2 -2
  11. package/dist/adapters/pi/extension.cjs.map +1 -1
  12. package/dist/adapters/pi/extension.d.cts +4 -4
  13. package/dist/adapters/pi/extension.d.cts.map +1 -1
  14. package/dist/adapters/pi/extension.d.mts +4 -4
  15. package/dist/adapters/pi/extension.d.mts.map +1 -1
  16. package/dist/adapters/pi/extension.mjs +2 -2
  17. package/dist/adapters/pi/extension.mjs.map +1 -1
  18. package/dist/adapters/pi/sessionApiClient.d.cts +4 -3
  19. package/dist/adapters/pi/sessionApiClient.d.cts.map +1 -1
  20. package/dist/adapters/pi/sessionApiClient.d.mts +4 -3
  21. package/dist/adapters/pi/sessionApiClient.d.mts.map +1 -1
  22. package/dist/adapters/webComputerUseChannel.cjs +1 -1
  23. package/dist/adapters/webComputerUseChannel.cjs.map +1 -1
  24. package/dist/adapters/webComputerUseChannel.d.cts +3 -3
  25. package/dist/adapters/webComputerUseChannel.d.cts.map +1 -1
  26. package/dist/adapters/webComputerUseChannel.d.mts +3 -3
  27. package/dist/adapters/webComputerUseChannel.d.mts.map +1 -1
  28. package/dist/adapters/webComputerUseChannel.mjs +1 -1
  29. package/dist/adapters/webComputerUseChannel.mjs.map +1 -1
  30. package/dist/container/index.cjs +1 -1
  31. package/dist/container/index.cjs.map +1 -1
  32. package/dist/container/index.d.cts +2 -2
  33. package/dist/container/index.d.cts.map +1 -1
  34. package/dist/container/index.d.mts +2 -2
  35. package/dist/container/index.d.mts.map +1 -1
  36. package/dist/container/index.mjs +1 -1
  37. package/dist/container/index.mjs.map +1 -1
  38. package/dist/index.cjs +1 -1
  39. package/dist/index.d.cts +2 -4
  40. package/dist/index.d.mts +2 -4
  41. package/dist/index.mjs +1 -1
  42. package/dist/services/extensionService.d.cts +2 -1
  43. package/dist/services/extensionService.d.cts.map +1 -1
  44. package/dist/services/extensionService.d.mts +2 -1
  45. package/dist/services/extensionService.d.mts.map +1 -1
  46. package/dist/services/sessionController.d.cts +3 -2
  47. package/dist/services/sessionController.d.cts.map +1 -1
  48. package/dist/services/sessionController.d.mts +3 -2
  49. package/dist/services/sessionController.d.mts.map +1 -1
  50. package/dist/services/traceRedaction.d.cts +4 -3
  51. package/dist/services/traceRedaction.d.cts.map +1 -1
  52. package/dist/services/traceRedaction.d.mts +4 -3
  53. package/dist/services/traceRedaction.d.mts.map +1 -1
  54. package/dist/types/computerUse.d.cts +14 -14
  55. package/dist/types/computerUse.d.cts.map +1 -1
  56. package/dist/types/computerUse.d.mts +14 -14
  57. package/dist/types/computerUse.d.mts.map +1 -1
  58. package/dist/types/computerUseApi.cjs.map +1 -1
  59. package/dist/types/computerUseApi.d.cts +19 -22
  60. package/dist/types/computerUseApi.d.cts.map +1 -1
  61. package/dist/types/computerUseApi.d.mts +19 -22
  62. package/dist/types/computerUseApi.d.mts.map +1 -1
  63. package/dist/types/computerUseApi.mjs.map +1 -1
  64. package/dist/types/extension.d.cts +5 -7
  65. package/dist/types/extension.d.cts.map +1 -1
  66. package/dist/types/extension.d.mts +5 -7
  67. package/dist/types/extension.d.mts.map +1 -1
  68. package/llms.txt +0 -1
  69. package/package.json +12 -14
  70. package/src/prompts/doompi-use-computer-use/SKILL.md +1 -1
  71. package/src/types/computerUse.ts +2 -3
  72. package/src/types/computerUseApi.ts +0 -1
  73. package/src/web/{components/ComputerActionToolCard.tsx → ComputerActionToolCard.tsx} +1 -1
  74. package/src/web/{components/ComputerStateToolCard.tsx → ComputerStateToolCard.tsx} +1 -1
  75. package/src/web/{components/ComputerUsePanel.tsx → ComputerUsePanel.tsx} +5 -14
  76. package/src/web/{stores/computerUseStore.ts → computerUseStore.ts} +2 -2
  77. package/src/web/index.ts +6 -12
  78. package/dist/adapters/pi/computerScriptRunner.cjs +0 -45
  79. package/dist/adapters/pi/computerScriptRunner.cjs.map +0 -1
  80. package/dist/adapters/pi/computerScriptRunner.d.cts +0 -12
  81. package/dist/adapters/pi/computerScriptRunner.d.cts.map +0 -1
  82. package/dist/adapters/pi/computerScriptRunner.d.mts +0 -12
  83. package/dist/adapters/pi/computerScriptRunner.d.mts.map +0 -1
  84. package/dist/adapters/pi/computerScriptRunner.mjs +0 -45
  85. package/dist/adapters/pi/computerScriptRunner.mjs.map +0 -1
  86. package/dist/types/computerScript.d.cts +0 -38
  87. package/dist/types/computerScript.d.cts.map +0 -1
  88. package/dist/types/computerScript.d.mts +0 -38
  89. package/dist/types/computerScript.d.mts.map +0 -1
  90. package/docs/computer-scripts.md +0 -37
  91. package/src/web/components/ComputerExecToolCard.tsx +0 -44
  92. package/src/web/lib/computerExecToolRender.ts +0 -14
  93. package/src/web/lib/computerUseSettings.ts +0 -17
  94. /package/src/web/{lib/computerActionToolRender.ts → computerActionToolRender.ts} +0 -0
  95. /package/src/web/{lib/computerStateToolRender.ts → computerStateToolRender.ts} +0 -0
@@ -1,3 +1,3 @@
1
- import{registerComputerUseCommand as e}from"../../commands/computerUseCommand.mjs";import{COMPUTER_USE_MODE_ID as t,COMPUTER_USE_MODE_STATUS_KEY as n,COMPUTER_USE_STATUS_KEY as r}from"../../types/computerUseApi.mjs";import{createComputerUseContainer as i}from"../../container/index.mjs";import{connectDoomCordisHost as a}from"@agimon-ai/doompi-extension-contracts/cordis-host";import{DOOM_MINOR_MODE_CATALOG_SERVICE as o,registerMinorModeOwner as s,requireMinorModeCatalog as c}from"@agimon-ai/doompi-extension-contracts/mode";const l=`@agimon-ai/doompi-computer-use`,u=[`computer_state`,`computer_action`,`computer_exec`],d=`[COMPUTER USE ACTIVE]
2
- Use 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.`;function f(e,t=!1){let n=e?.phase??`inactive`,r=t||n!==`inactive`&&n!==`failed`;return{activation:r?n===`stopping`?`deactivating`:n===`awaiting_confirmation`||n===`activating`?`activating`:`active`:`inactive`,condition:n===`awaiting_confirmation`?`blocked`:n===`failed`?`failed`:n===`activating`||n===`stopping`?`queued`:`ready`,...r&&n===`inactive`?{detail:`configure computer use in Activity`}:{},...n===`awaiting_confirmation`?{detail:`awaiting confirmation in Activity`}:{},actions:[{id:`activate`,enabled:!r,...r?{disabledReason:`Computer use is already enabled.`}:{}},{id:`deactivate`,enabled:r,...r?{}:{disabledReason:`Computer use is not enabled.`}},{id:`doctor`,enabled:!0}]}}function p(e,t){let n=new Set(u),r=e.getActiveTools(),i=r.filter(e=>!n.has(e));t&&i.push(...u),(i.length!==r.length||i.some((e,t)=>e!==r[t]))&&e.setActiveTools(i)}function m(a,u,m=i()){let h=m.client,g,_=!1,v=!1,y,b=()=>void 0,x,S,C=``,w,T,E=()=>{let e=g?.phase??`inactive`,t=`${_}:${e}:${g?.revision??`none`}`;y!==void 0&&t!==C&&(y.publish(f(g,_)),C=t);let i=g===void 0?void 0:_||e!==`inactive`?e:``;S!==void 0&&i!==w&&(S.ui.setStatus(n,i),w=i);let a=_||e!==`inactive`?`computer use: ${e}`:void 0;S!==void 0&&a!==T&&(S.ui.setStatus(r,a),T=a)},D=async()=>{let e=!1;try{e=await m.enabled?.()===!0}catch{e=!1}if(e!==v){if(v=e,!v){if(h!==void 0&&g!==void 0&&g.phase!==`inactive`&&g.phase!==`failed`)try{await h.stop()}catch{}_=!1,g=void 0,p(u,!1)}b()}if(!v||h===void 0){g=void 0,p(u,!1),E();return}try{g=await h.state(),p(u,g.phase===`active`),E()}catch{g=void 0,p(u,!1),E()}};u.registerTool({name:`computer_state`,label:`Computer State`,description:`Observe the authorized application window and return its semantic accessibility state.`,promptSnippet:`Observe the authorized application before choosing a semantic action`,parameters:{type:`object`,properties:{},additionalProperties:!1},async execute(e,t,n){if(!v||h===void 0||g?.phase!==`active`)throw Error(`Computer use is not active for this session.`);let r=await h.observe(n);return{content:[{type:`text`,text:JSON.stringify(r,null,2)}],details:r}}}),u.registerTool({name:`computer_action`,label:`Computer Action`,description:`Perform one constrained semantic action in the authorized application window.`,promptSnippet:`Perform one action using a current computer_state snapshot and element ref`,parameters:{type:`object`,properties:{kind:{type:`string`,enum:[`press`,`focus`,`set_value`,`scroll`]},snapshotId:{type:`string`},elementRef:{type:`string`},value:{type:`string`},direction:{type:`string`,enum:[`up`,`down`,`left`,`right`]},amount:{type:`string`,enum:[`line`,`page`]}},required:[`kind`,`snapshotId`,`elementRef`],additionalProperties:!1},async execute(e,t,n){if(!v||h===void 0||g?.phase!==`active`)throw Error(`Computer use is not active for this session.`);let r=await h.act(t,n);return{content:[{type:`text`,text:JSON.stringify(r,null,2)}],details:r}}}),u.registerTool({name:`computer_exec`,label:`Computer Script`,description:`Run a trusted, explicitly allowed local TypeScript script against the authorized application session.`,promptSnippet:`Run a trusted reusable computer script by its explicitly allowed path and JSON input`,parameters:{type:`object`,properties:{scriptPath:{type:`string`},input:{}},required:[`scriptPath`,`input`],additionalProperties:!1},async execute(e,t,n){if(!v||h===void 0||g?.phase!==`active`)throw Error(`Computer use is not active for this session.`);if(m.scriptRunner===void 0)throw Error(`Computer script execution is unavailable.`);let r=t,i=await m.scriptRunner.execute(r.scriptPath,r.input,n);return{content:[{type:`text`,text:JSON.stringify(i,null,2)}],details:i}}}),a.inject([o],e=>{let n=c(e),r=()=>s(n,{descriptor:{source:l,id:t,label:`Computer Use`,description:`Session-scoped semantic control through DoomPi Desktop.`,order:450,actions:[{id:`activate`,label:`Activate`,description:`Open the cockpit activation workflow and native confirmation.`,contexts:[`tui`,`headless`],parameters:[]},{id:`deactivate`,label:`Deactivate`,description:`Stop this session computer-use run.`,contexts:[`tui`,`headless`],parameters:[]},{id:`doctor`,label:`Doctor`,description:`Report Desktop availability and session state.`,contexts:[`tui`,`headless`],parameters:[]}]},initialState:f(g,_),async handleAction(e,t,n){if(S=n.context,e===`activate`){if(await m.enabled?.()!==!0)throw await D(),Error(`Enable computer use in global settings first.`);if(h===void 0)throw Error(`DoomPi Desktop computer use is unavailable.`);return _=!0,await D(),E(),{message:`Computer use is ready to configure in Activity.`}}if(e===`doctor`)return await D(),{message:h===void 0?`DoomPi Desktop session API is unavailable.`:`Computer use is ${g?.phase.replaceAll(`_`,` `)??`unavailable`}.`};if(e===`deactivate`){if(h===void 0)throw Error(`DoomPi Desktop computer use is unavailable.`);return g!==void 0&&g.phase!==`inactive`&&g.phase!==`failed`&&await h.stop(n.signal),_=!1,await D(),E(),{message:`Computer use is off.`}}throw Error(`Unknown computer-use action: ${e}`)}});return b=()=>{v&&y===void 0?(C=``,y=r()):!v&&y!==void 0&&(y.dispose(),y=void 0,C=``)},b(),()=>{b=()=>void 0,y?.dispose(),y=void 0}}),u.on(`before_agent_start`,e=>v&&g?.phase===`active`?{systemPrompt:`${e.systemPrompt}\n\n${d}`}:void 0),u.on(`session_start`,(e,t)=>{S=t,p(u,!1),D(),x&&clearInterval(x),x=setInterval(()=>void D(),250),x.unref?.()}),a.effect(()=>()=>{x&&clearInterval(x),x=void 0,p(u,!1),S?.ui.setStatus(n,void 0),S?.ui.setStatus(r,void 0),S=void 0,y?.dispose(),y=void 0},`${l}/runtime`),e(u,m.service)}function h(e,t){m(e,t.pi,t.dependencies)}async function g(e,t=i()){let n=await a(e,l,{allowStandalone:!0}),r=n.root.plugin(h,{pi:e,dependencies:t});try{await r}catch(e){try{await r.dispose()}finally{await n.dispose()}throw e}let o;e.on(`session_shutdown`,()=>o??=(async()=>{try{await r.dispose()}finally{await n.dispose()}})())}export{d as COMPUTER_USE_GUIDANCE,t as COMPUTER_USE_MODE_ID,u as COMPUTER_USE_TOOL_NAMES,g as activateComputerUseExtension,g as default,m as installComputerUseRuntime,f as modeState,p as reconcileTools};
1
+ import{registerComputerUseCommand as e}from"../../commands/computerUseCommand.mjs";import{COMPUTER_USE_MODE_ID as t,COMPUTER_USE_MODE_STATUS_KEY as n,COMPUTER_USE_STATUS_KEY as r}from"../../types/computerUseApi.mjs";import{createComputerUseContainer as i}from"../../container/index.mjs";import{connectDoomCordisHost as a}from"@agimon-ai/doompi-extension-contracts/cordis-host";import{DOOM_MINOR_MODE_CATALOG_SERVICE as o,registerMinorModeOwner as s,requireMinorModeCatalog as c}from"@agimon-ai/doompi-extension-contracts/mode";const l=`@agimon-ai/doompi-computer-use`,u=[`computer_state`,`computer_action`],d=`[COMPUTER USE ACTIVE]
2
+ Use 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, set_value, or scroll at a time. Never infer coordinates, inspect another application, bypass secure elements, or retry an uncertain outcome. Stop computer use when the task is complete.`;function f(e,t=!1){let n=e?.phase??`inactive`,r=t||n!==`inactive`&&n!==`failed`;return{activation:r?n===`stopping`?`deactivating`:n===`awaiting_confirmation`||n===`activating`?`activating`:`active`:`inactive`,condition:n===`awaiting_confirmation`?`blocked`:n===`failed`?`failed`:n===`activating`||n===`stopping`?`queued`:`ready`,...r&&n===`inactive`?{detail:`configure computer use in Activity`}:{},...n===`awaiting_confirmation`?{detail:`awaiting confirmation in Activity`}:{},actions:[{id:`activate`,enabled:!r,...r?{disabledReason:`Computer use is already enabled.`}:{}},{id:`deactivate`,enabled:r,...r?{}:{disabledReason:`Computer use is not enabled.`}},{id:`doctor`,enabled:!0}]}}function p(e,t){let n=new Set(u),r=e.getActiveTools(),i=r.filter(e=>!n.has(e));t&&i.push(...u),(i.length!==r.length||i.some((e,t)=>e!==r[t]))&&e.setActiveTools(i)}function m(a,u,m=i()){let h=m.client,g,_=!1,v,y,b,x=``,S,C,w=()=>{let e=g?.phase??`inactive`,t=`${_}:${e}:${g?.revision??`none`}`;v!==void 0&&t!==x&&(v.publish(f(g,_)),x=t);let i=g===void 0?void 0:_||e!==`inactive`?e:``;b!==void 0&&i!==S&&(b.ui.setStatus(n,i),S=i);let a=_||e!==`inactive`?`computer use: ${e}`:void 0;b!==void 0&&a!==C&&(b.ui.setStatus(r,a),C=a)},T=async()=>{if(h===void 0){g=void 0,p(u,!1),w();return}try{g=await h.state(),p(u,g.phase===`active`),w()}catch{g=void 0,p(u,!1),w()}};u.registerTool({name:`computer_state`,label:`Computer State`,description:`Observe the authorized application window and return its semantic accessibility state.`,promptSnippet:`Observe the authorized application before choosing a semantic action`,parameters:{type:`object`,properties:{},additionalProperties:!1},async execute(e,t,n){if(h===void 0||g?.phase!==`active`)throw Error(`Computer use is not active for this session.`);let r=await h.observe(n);return{content:[{type:`text`,text:JSON.stringify(r,null,2)}],details:r}}}),u.registerTool({name:`computer_action`,label:`Computer Action`,description:`Perform one constrained semantic action in the authorized application window.`,promptSnippet:`Perform one action using a current computer_state snapshot and element ref`,parameters:{type:`object`,properties:{kind:{type:`string`,enum:[`press`,`set_value`,`scroll`]},snapshotId:{type:`string`},elementRef:{type:`string`},value:{type:`string`},direction:{type:`string`,enum:[`up`,`down`,`left`,`right`]},amount:{type:`string`,enum:[`line`,`page`]}},required:[`kind`,`snapshotId`,`elementRef`],additionalProperties:!1},async execute(e,t,n){if(h===void 0||g?.phase!==`active`)throw Error(`Computer use is not active for this session.`);let r=await h.act(t,n);return{content:[{type:`text`,text:JSON.stringify(r,null,2)}],details:r}}}),a.inject([o],e=>{let n=s(c(e),{descriptor:{source:l,id:t,label:`Computer Use`,description:`Session-scoped semantic control through DoomPi Desktop.`,order:450,actions:[{id:`activate`,label:`Activate`,description:`Open the cockpit activation workflow and native confirmation.`,contexts:[`tui`,`headless`],parameters:[]},{id:`deactivate`,label:`Deactivate`,description:`Stop this session computer-use run.`,contexts:[`tui`,`headless`],parameters:[]},{id:`doctor`,label:`Doctor`,description:`Report Desktop availability and session state.`,contexts:[`tui`,`headless`],parameters:[]}]},initialState:f(g,_),async handleAction(e,t,n){if(b=n.context,e===`activate`){if(h===void 0)throw Error(`DoomPi Desktop computer use is unavailable.`);return _=!0,await T(),w(),{message:`Computer use is ready to configure in Activity.`}}if(e===`doctor`)return await T(),{message:h===void 0?`DoomPi Desktop session API is unavailable.`:`Computer use is ${g?.phase.replaceAll(`_`,` `)??`unavailable`}.`};if(e===`deactivate`){if(h===void 0)throw Error(`DoomPi Desktop computer use is unavailable.`);return g!==void 0&&g.phase!==`inactive`&&g.phase!==`failed`&&await h.stop(n.signal),_=!1,await T(),w(),{message:`Computer use is off.`}}throw Error(`Unknown computer-use action: ${e}`)}});return v=n,()=>{n.dispose(),v===n&&(v=void 0)}}),u.on(`before_agent_start`,e=>g?.phase===`active`?{systemPrompt:`${e.systemPrompt}\n\n${d}`}:void 0),u.on(`session_start`,(e,t)=>{b=t,p(u,!1),T(),y&&clearInterval(y),y=setInterval(()=>void T(),250),y.unref?.()}),a.effect(()=>()=>{y&&clearInterval(y),y=void 0,p(u,!1),b?.ui.setStatus(n,void 0),b?.ui.setStatus(r,void 0),b=void 0,v?.dispose(),v=void 0},`${l}/runtime`),e(u,m.service)}function h(e,t){m(e,t.pi,t.dependencies)}async function g(e,t=i()){let n=await a(e,l,{allowStandalone:!0}),r=n.root.plugin(h,{pi:e,dependencies:t});try{await r}catch(e){try{await r.dispose()}finally{await n.dispose()}throw e}let o;e.on(`session_shutdown`,()=>o??=(async()=>{try{await r.dispose()}finally{await n.dispose()}})())}export{d as COMPUTER_USE_GUIDANCE,t as COMPUTER_USE_MODE_ID,u as COMPUTER_USE_TOOL_NAMES,g as activateComputerUseExtension,g as default,m as installComputerUseRuntime,f as modeState,p as reconcileTools};
3
3
  //# sourceMappingURL=extension.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension.mjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import { connectDoomCordisHost } from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport {\n DOOM_MINOR_MODE_CATALOG_SERVICE,\n type MinorModeOwnerHandle,\n type MinorModeState,\n registerMinorModeOwner,\n requireMinorModeCatalog,\n} from '@agimon-ai/doompi-extension-contracts/mode';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport { registerComputerUseCommand } from '../../commands/computerUseCommand.ts';\nimport { createComputerUseContainer } from '../../container/index.ts';\nimport {\n COMPUTER_USE_MODE_ID,\n COMPUTER_USE_MODE_STATUS_KEY,\n COMPUTER_USE_STATUS_KEY,\n type ComputerUseSessionView,\n} from '../../types/computerUseApi.ts';\nimport type { ComputerUseAction } from '../../types/computerUse.ts';\nimport type { ComputerUseExtensionDependencies } from '../../types/extension.ts';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-computer-use';\nexport { COMPUTER_USE_MODE_ID };\nexport const COMPUTER_USE_TOOL_NAMES = ['computer_state', 'computer_action', 'computer_exec'] as const;\nexport 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.`;\n\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\nexport function reconcileTools(pi: Pick<ExtensionAPI, 'getActiveTools' | 'setActiveTools'>, active: boolean): void {\n const owned = new Set<string>(COMPUTER_USE_TOOL_NAMES);\n const current = pi.getActiveTools();\n const next = current.filter((name) => !owned.has(name));\n if (active) next.push(...COMPUTER_USE_TOOL_NAMES);\n if (next.length !== current.length || next.some((name, index) => name !== current[index])) pi.setActiveTools(next);\n}\n\nexport function installComputerUseRuntime(\n cordis: Context,\n pi: ExtensionAPI,\n dependencies: ComputerUseExtensionDependencies = createComputerUseContainer(),\n): void {\n const client = dependencies.client;\n let state: ComputerUseSessionView | undefined;\n let enabled = false;\n let globallyEnabled = false;\n let mode: MinorModeOwnerHandle | undefined;\n let syncModeOwner = (): void => undefined;\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(modeState(state, enabled));\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 let nextGloballyEnabled = false;\n try {\n nextGloballyEnabled = (await dependencies.enabled?.()) === true;\n } catch {\n nextGloballyEnabled = false;\n }\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(pi, false);\n }\n syncModeOwner();\n }\n if (!globallyEnabled || client === undefined) {\n state = undefined;\n reconcileTools(pi, false);\n publish();\n return;\n }\n try {\n state = await client.state();\n reconcileTools(pi, state.phase === 'active');\n publish();\n } catch {\n state = undefined;\n reconcileTools(pi, false);\n publish();\n }\n };\n\n pi.registerTool({\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: { type: 'object', properties: {}, additionalProperties: false },\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 return { content: [{ type: 'text', text: JSON.stringify(observation, null, 2) }], details: observation };\n },\n });\n pi.registerTool({\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 pi.registerTool({\n name: 'computer_exec',\n label: 'Computer Script',\n description:\n 'Run a trusted, explicitly allowed local TypeScript script against the authorized application session.',\n promptSnippet: 'Run a trusted reusable computer script by its explicitly allowed path and JSON input',\n parameters: {\n type: 'object',\n properties: {\n scriptPath: { type: 'string' },\n input: {},\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 };\n const result = await dependencies.scriptRunner.execute(input.scriptPath, input.input, signal);\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], details: result };\n },\n });\n cordis.inject([DOOM_MINOR_MODE_CATALOG_SERVICE], (context) => {\n const catalog = requireMinorModeCatalog(context);\n const registerOwner = (): MinorModeOwnerHandle =>\n registerMinorModeOwner<ExtensionContext>(catalog, {\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 initialState: modeState(state, enabled),\n async handleAction(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 });\n syncModeOwner = (): void => {\n if (globallyEnabled && mode === undefined) {\n publishedMode = '';\n mode = registerOwner();\n } else if (!globallyEnabled && mode !== undefined) {\n mode.dispose();\n mode = undefined;\n publishedMode = '';\n }\n };\n syncModeOwner();\n return () => {\n syncModeOwner = () => undefined;\n mode?.dispose();\n mode = undefined;\n };\n });\n\n pi.on('before_agent_start', (event) =>\n globallyEnabled && state?.phase === 'active'\n ? { systemPrompt: `${event.systemPrompt}\\n\\n${COMPUTER_USE_GUIDANCE}` }\n : undefined,\n );\n pi.on('session_start', (_event, context) => {\n activeContext = context;\n reconcileTools(pi, false);\n void refresh();\n if (timer) clearInterval(timer);\n timer = setInterval(() => void refresh(), 250);\n timer.unref?.();\n });\n cordis.effect(\n () => () => {\n if (timer) clearInterval(timer);\n timer = undefined;\n reconcileTools(pi, false);\n activeContext?.ui.setStatus(COMPUTER_USE_MODE_STATUS_KEY, undefined);\n activeContext?.ui.setStatus(COMPUTER_USE_STATUS_KEY, undefined);\n activeContext = undefined;\n mode?.dispose();\n mode = undefined;\n },\n `${PACKAGE_SOURCE}/runtime`,\n );\n\n registerComputerUseCommand(pi, dependencies.service);\n}\n\ninterface ComputerUsePluginConfig {\n readonly pi: ExtensionAPI;\n readonly dependencies: ComputerUseExtensionDependencies;\n}\n\nfunction computerUsePlugin(cordis: Context, config: ComputerUsePluginConfig): void {\n installComputerUseRuntime(cordis, config.pi, config.dependencies);\n}\n\nexport async function activateComputerUseExtension(\n pi: ExtensionAPI,\n dependencies: ComputerUseExtensionDependencies = createComputerUseContainer(),\n): Promise<void> {\n const connection = await connectDoomCordisHost(pi, PACKAGE_SOURCE, { allowStandalone: true });\n const fiber = connection.root.plugin(computerUsePlugin, { pi, dependencies });\n try {\n await fiber;\n } catch (error) {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n throw error;\n }\n let disposal: Promise<void> | undefined;\n pi.on(\n 'session_shutdown',\n () =>\n (disposal ??= (async () => {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n })()),\n );\n}\n\nexport default activateComputerUseExtension;\n"],"mappings":"+gBAqBA,MAAM,EAAiB,iCAEV,EAA0B,CAAC,iBAAkB,kBAAmB,eAAe,EAC/E,EAAwB;wdAGrC,SAAgB,EAAU,EAAgC,EAAU,GAAuB,CACzF,IAAM,EAAQ,GAAO,OAAS,WAExB,EAAc,GADJ,IAAU,YAAc,IAAU,SASlD,MAAO,CACL,WARiB,EACf,IAAU,WACR,eACA,IAAU,yBAA2B,IAAU,aAC7C,aACA,SACJ,WAGF,UACE,IAAU,wBACN,UACA,IAAU,SACR,SACA,IAAU,cAAgB,IAAU,WAClC,SACA,QACV,GAAI,GAAe,IAAU,WAAa,CAAE,OAAQ,oCAAqC,EAAI,CAAC,EAC9F,GAAI,IAAU,wBAA0B,CAAE,OAAQ,mCAAoC,EAAI,CAAC,EAC3F,QAAS,CACP,CACE,GAAI,WACJ,QAAS,CAAC,EACV,GAAK,EAAmB,CAAE,eAAgB,kCAAmC,EAA1D,CAAC,CACtB,EACA,CACE,GAAI,aACJ,QAAS,EACT,GAAI,EAAc,CAAC,EAAI,CAAE,eAAgB,8BAA+B,CAC1E,EACA,CAAE,GAAI,SAAU,QAAS,EAAK,CAChC,CACF,CACF,CAEA,SAAgB,EAAe,EAA6D,EAAuB,CACjH,IAAM,EAAQ,IAAI,IAAY,CAAuB,EAC/C,EAAU,EAAG,eAAe,EAC5B,EAAO,EAAQ,OAAQ,GAAS,CAAC,EAAM,IAAI,CAAI,CAAC,EAClD,GAAQ,EAAK,KAAK,GAAG,CAAuB,GAC5C,EAAK,SAAW,EAAQ,QAAU,EAAK,MAAM,EAAM,IAAU,IAAS,EAAQ,EAAM,IAAG,EAAG,eAAe,CAAI,CACnH,CAEA,SAAgB,EACd,EACA,EACA,EAAiD,EAA2B,EACtE,CACN,IAAM,EAAS,EAAa,OACxB,EACA,EAAU,GACV,EAAkB,GAClB,EACA,MAA4B,IAAA,GAC5B,EACA,EACA,EAAgB,GAChB,EACA,EACE,MAAsB,CAC1B,IAAM,EAAQ,GAAO,OAAS,WACxB,EAAa,GAAG,EAAQ,GAAG,EAAM,GAAG,GAAO,UAAY,SACzD,IAAS,IAAA,IAAa,IAAe,IACvC,EAAK,QAAQ,EAAU,EAAO,CAAO,CAAC,EACtC,EAAgB,GAElB,IAAM,EAAa,IAAU,IAAA,GAAY,IAAA,GAAY,GAAW,IAAU,WAAa,EAAQ,GAC3F,IAAkB,IAAA,IAAa,IAAe,IAChD,EAAc,GAAG,UAAU,EAA8B,CAAU,EACnE,EAAsB,GAExB,IAAM,EAAiB,GAAW,IAAU,WAAa,iBAAiB,IAAU,IAAA,GAChF,IAAkB,IAAA,IAAa,IAAmB,IACpD,EAAc,GAAG,UAAU,EAAyB,CAAc,EAClE,EAA0B,EAE9B,EACM,EAAU,SAA2B,CACzC,IAAI,EAAsB,GAC1B,GAAI,CACF,EAAuB,MAAM,EAAa,UAAU,IAAO,EAC7D,MAAQ,CACN,EAAsB,EACxB,CACA,GAAI,IAAwB,EAAiB,CAE3C,GADA,EAAkB,EACd,CAAC,EAAiB,CACpB,GAAI,IAAW,IAAA,IAAa,IAAU,IAAA,IAAa,EAAM,QAAU,YAAc,EAAM,QAAU,SAC/F,GAAI,CACF,MAAM,EAAO,KAAK,CACpB,MAAQ,CAER,CAEF,EAAU,GACV,EAAQ,IAAA,GACR,EAAe,EAAI,EAAK,CAC1B,CACA,EAAc,CAChB,CACA,GAAI,CAAC,GAAmB,IAAW,IAAA,GAAW,CAC5C,EAAQ,IAAA,GACR,EAAe,EAAI,EAAK,EACxB,EAAQ,EACR,MACF,CACA,GAAI,CACF,EAAQ,MAAM,EAAO,MAAM,EAC3B,EAAe,EAAI,EAAM,QAAU,QAAQ,EAC3C,EAAQ,CACV,MAAQ,CACN,EAAQ,IAAA,GACR,EAAe,EAAI,EAAK,EACxB,EAAQ,CACV,CACF,EAEA,EAAG,aAAa,CACd,KAAM,iBACN,MAAO,iBACP,YAAa,yFACb,cAAe,uEACf,WAAY,CAAE,KAAM,SAAU,WAAY,CAAC,EAAG,qBAAsB,EAAM,EAC1E,MAAM,QAAQ,EAAa,EAAS,EAAQ,CAC1C,GAAI,CAAC,GAAmB,IAAW,IAAA,IAAa,GAAO,QAAU,SAC/D,MAAU,MAAM,8CAA8C,EAChE,IAAM,EAAc,MAAM,EAAO,QAAQ,CAAM,EAC/C,MAAO,CAAE,QAAS,CAAC,CAAE,KAAM,OAAQ,KAAM,KAAK,UAAU,EAAa,KAAM,CAAC,CAAE,CAAC,EAAG,QAAS,CAAY,CACzG,CACF,CAAC,EACD,EAAG,aAAa,CACd,KAAM,kBACN,MAAO,kBACP,YAAa,gFACb,cAAe,6EACf,WAAY,CACV,KAAM,SACN,WAAY,CACV,KAAM,CAAE,KAAM,SAAU,KAAM,CAAC,QAAS,QAAS,YAAa,QAAQ,CAAE,EACxE,WAAY,CAAE,KAAM,QAAS,EAC7B,WAAY,CAAE,KAAM,QAAS,EAC7B,MAAO,CAAE,KAAM,QAAS,EACxB,UAAW,CAAE,KAAM,SAAU,KAAM,CAAC,KAAM,OAAQ,OAAQ,OAAO,CAAE,EACnE,OAAQ,CAAE,KAAM,SAAU,KAAM,CAAC,OAAQ,MAAM,CAAE,CACnD,EACA,SAAU,CAAC,OAAQ,aAAc,YAAY,EAC7C,qBAAsB,EACxB,EACA,MAAM,QAAQ,EAAa,EAAQ,EAAQ,CACzC,GAAI,CAAC,GAAmB,IAAW,IAAA,IAAa,GAAO,QAAU,SAC/D,MAAU,MAAM,8CAA8C,EAChE,IAAM,EAAS,MAAM,EAAO,IAAI,EAAwC,CAAM,EAC9E,MAAO,CAAE,QAAS,CAAC,CAAE,KAAM,OAAQ,KAAM,KAAK,UAAU,EAAQ,KAAM,CAAC,CAAE,CAAC,EAAG,QAAS,CAAO,CAC/F,CACF,CAAC,EACD,EAAG,aAAa,CACd,KAAM,gBACN,MAAO,kBACP,YACE,wGACF,cAAe,uFACf,WAAY,CACV,KAAM,SACN,WAAY,CACV,WAAY,CAAE,KAAM,QAAS,EAC7B,MAAO,CAAC,CACV,EACA,SAAU,CAAC,aAAc,OAAO,EAChC,qBAAsB,EACxB,EACA,MAAM,QAAQ,EAAa,EAAQ,EAAQ,CACzC,GAAI,CAAC,GAAmB,IAAW,IAAA,IAAa,GAAO,QAAU,SAC/D,MAAU,MAAM,8CAA8C,EAChE,GAAI,EAAa,eAAiB,IAAA,GAAW,MAAU,MAAM,2CAA2C,EACxG,IAAM,EAAQ,EACR,EAAS,MAAM,EAAa,aAAa,QAAQ,EAAM,WAAY,EAAM,MAAO,CAAM,EAC5F,MAAO,CAAE,QAAS,CAAC,CAAE,KAAM,OAAQ,KAAM,KAAK,UAAU,EAAQ,KAAM,CAAC,CAAE,CAAC,EAAG,QAAS,CAAO,CAC/F,CACF,CAAC,EACD,EAAO,OAAO,CAAC,CAA+B,EAAI,GAAY,CAC5D,IAAM,EAAU,EAAwB,CAAO,EACzC,MACJ,EAAyC,EAAS,CAChD,WAAY,CACV,OAAQ,EACR,GAAI,EACJ,MAAO,eACP,YAAa,0DACb,MAAO,IACP,QAAS,CACP,CACE,GAAI,WACJ,MAAO,WACP,YAAa,gEACb,SAAU,CAAC,MAAO,UAAU,EAC5B,WAAY,CAAC,CACf,EACA,CACE,GAAI,aACJ,MAAO,aACP,YAAa,sCACb,SAAU,CAAC,MAAO,UAAU,EAC5B,WAAY,CAAC,CACf,EACA,CACE,GAAI,SACJ,MAAO,SACP,YAAa,iDACb,SAAU,CAAC,MAAO,UAAU,EAC5B,WAAY,CAAC,CACf,CACF,CACF,EACA,aAAc,EAAU,EAAO,CAAO,EACtC,MAAM,aAAa,EAAU,EAAiB,EAAW,CAEvD,GADA,EAAgB,EAAU,QACtB,IAAa,WAAY,CAC3B,GAAK,MAAM,EAAa,UAAU,IAAO,GAEvC,MADA,MAAM,EAAQ,EACJ,MAAM,+CAA+C,EAEjE,GAAI,IAAW,IAAA,GAAW,MAAU,MAAM,6CAA6C,EAIvF,MAHA,GAAU,GACV,MAAM,EAAQ,EACd,EAAQ,EACD,CAAE,QAAS,iDAAkD,CACtE,CACA,GAAI,IAAa,SAEf,OADA,MAAM,EAAQ,EACP,CACL,QACE,IAAW,IAAA,GACP,6CACA,mBAAmB,GAAO,MAAM,WAAW,IAAK,GAAG,GAAK,cAAc,EAC9E,EAEF,GAAI,IAAa,aAAc,CAC7B,GAAI,IAAW,IAAA,GAAW,MAAU,MAAM,6CAA6C,EAMvF,OALI,IAAU,IAAA,IAAa,EAAM,QAAU,YAAc,EAAM,QAAU,UACvE,MAAM,EAAO,KAAK,EAAU,MAAM,EACpC,EAAU,GACV,MAAM,EAAQ,EACd,EAAQ,EACD,CAAE,QAAS,sBAAuB,CAC3C,CACA,MAAU,MAAM,gCAAgC,GAAU,CAC5D,CACF,CAAC,EAYH,MAXA,OAA4B,CACtB,GAAmB,IAAS,IAAA,IAC9B,EAAgB,GAChB,EAAO,EAAc,GACZ,CAAC,GAAmB,IAAS,IAAA,KACtC,EAAK,QAAQ,EACb,EAAO,IAAA,GACP,EAAgB,GAEpB,EACA,EAAc,MACD,CACX,MAAsB,IAAA,GACtB,GAAM,QAAQ,EACd,EAAO,IAAA,EACT,CACF,CAAC,EAED,EAAG,GAAG,qBAAuB,GAC3B,GAAmB,GAAO,QAAU,SAChC,CAAE,aAAc,GAAG,EAAM,aAAa,MAAM,GAAwB,EACpE,IAAA,EACN,EACA,EAAG,GAAG,iBAAkB,EAAQ,IAAY,CAC1C,EAAgB,EAChB,EAAe,EAAI,EAAK,EACxB,EAAa,EACT,GAAO,cAAc,CAAK,EAC9B,EAAQ,gBAAkB,KAAK,EAAQ,EAAG,GAAG,EAC7C,EAAM,QAAQ,CAChB,CAAC,EACD,EAAO,eACO,CACN,GAAO,cAAc,CAAK,EAC9B,EAAQ,IAAA,GACR,EAAe,EAAI,EAAK,EACxB,GAAe,GAAG,UAAU,EAA8B,IAAA,EAAS,EACnE,GAAe,GAAG,UAAU,EAAyB,IAAA,EAAS,EAC9D,EAAgB,IAAA,GAChB,GAAM,QAAQ,EACd,EAAO,IAAA,EACT,EACA,GAAG,EAAe,SACpB,EAEA,EAA2B,EAAI,EAAa,OAAO,CACrD,CAOA,SAAS,EAAkB,EAAiB,EAAuC,CACjF,EAA0B,EAAQ,EAAO,GAAI,EAAO,YAAY,CAClE,CAEA,eAAsB,EACpB,EACA,EAAiD,EAA2B,EAC7D,CACf,IAAM,EAAa,MAAM,EAAsB,EAAI,EAAgB,CAAE,gBAAiB,EAAK,CAAC,EACtF,EAAQ,EAAW,KAAK,OAAO,EAAmB,CAAE,KAAI,cAAa,CAAC,EAC5E,GAAI,CACF,MAAM,CACR,OAAS,EAAO,CACd,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACA,MAAM,CACR,CACA,IAAI,EACJ,EAAG,GACD,uBAEG,KAAc,SAAY,CACzB,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACF,EAAA,CAAG,CACP,CACF"}
1
+ {"version":3,"file":"extension.mjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import { connectDoomCordisHost } from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport {\n DOOM_MINOR_MODE_CATALOG_SERVICE,\n type MinorModeOwnerHandle,\n type MinorModeState,\n registerMinorModeOwner,\n requireMinorModeCatalog,\n} from '@agimon-ai/doompi-extension-contracts/mode';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport { registerComputerUseCommand } from '../../commands/computerUseCommand.ts';\nimport { createComputerUseContainer } from '../../container/index.ts';\nimport {\n COMPUTER_USE_MODE_ID,\n COMPUTER_USE_MODE_STATUS_KEY,\n COMPUTER_USE_STATUS_KEY,\n type ComputerUseSessionView,\n} from '../../types/computerUseApi.ts';\nimport type { ComputerUseAction } from '../../types/computerUse.ts';\nimport type { ComputerUseExtensionDependencies } from '../../types/extension.ts';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-computer-use';\nexport { COMPUTER_USE_MODE_ID };\nexport const COMPUTER_USE_TOOL_NAMES = ['computer_state', 'computer_action'] as const;\nexport 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, set_value, or scroll at a time. Never infer coordinates, inspect another application, bypass secure elements, or retry an uncertain outcome. Stop computer use when the task is complete.`;\n\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\nexport function reconcileTools(pi: Pick<ExtensionAPI, 'getActiveTools' | 'setActiveTools'>, active: boolean): void {\n const owned = new Set<string>(COMPUTER_USE_TOOL_NAMES);\n const current = pi.getActiveTools();\n const next = current.filter((name) => !owned.has(name));\n if (active) next.push(...COMPUTER_USE_TOOL_NAMES);\n if (next.length !== current.length || next.some((name, index) => name !== current[index])) pi.setActiveTools(next);\n}\n\nexport function installComputerUseRuntime(\n cordis: Context,\n pi: ExtensionAPI,\n dependencies: ComputerUseExtensionDependencies = createComputerUseContainer(),\n): void {\n const client = dependencies.client;\n let state: ComputerUseSessionView | undefined;\n let enabled = false;\n let mode: MinorModeOwnerHandle | undefined;\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\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(modeState(state, enabled));\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 (client === undefined) {\n state = undefined;\n reconcileTools(pi, false);\n publish();\n return;\n }\n try {\n state = await client.state();\n reconcileTools(pi, state.phase === 'active');\n publish();\n } catch {\n state = undefined;\n reconcileTools(pi, false);\n publish();\n }\n };\n\n pi.registerTool({\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: { type: 'object', properties: {}, additionalProperties: false },\n async execute(_toolCallId, _params, signal) {\n if (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 return { content: [{ type: 'text', text: JSON.stringify(observation, null, 2) }], details: observation };\n },\n });\n pi.registerTool({\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', '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 (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 cordis.inject([DOOM_MINOR_MODE_CATALOG_SERVICE], (context) => {\n const owner = registerMinorModeOwner<ExtensionContext>(requireMinorModeCatalog(context), {\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 initialState: modeState(state, enabled),\n async handleAction(actionId, _argumentsValue, execution) {\n activeContext = execution.context;\n if (actionId === 'activate') {\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 });\n mode = owner;\n return () => {\n owner.dispose();\n if (mode === owner) mode = undefined;\n };\n });\n\n pi.on('before_agent_start', (event) =>\n state?.phase === 'active' ? { systemPrompt: `${event.systemPrompt}\\n\\n${COMPUTER_USE_GUIDANCE}` } : undefined,\n );\n pi.on('session_start', (_event, context) => {\n activeContext = context;\n reconcileTools(pi, false);\n void refresh();\n if (timer) clearInterval(timer);\n timer = setInterval(() => void refresh(), 250);\n timer.unref?.();\n });\n cordis.effect(\n () => () => {\n if (timer) clearInterval(timer);\n timer = undefined;\n reconcileTools(pi, false);\n activeContext?.ui.setStatus(COMPUTER_USE_MODE_STATUS_KEY, undefined);\n activeContext?.ui.setStatus(COMPUTER_USE_STATUS_KEY, undefined);\n activeContext = undefined;\n mode?.dispose();\n mode = undefined;\n },\n `${PACKAGE_SOURCE}/runtime`,\n );\n\n registerComputerUseCommand(pi, dependencies.service);\n}\n\ninterface ComputerUsePluginConfig {\n readonly pi: ExtensionAPI;\n readonly dependencies: ComputerUseExtensionDependencies;\n}\n\nfunction computerUsePlugin(cordis: Context, config: ComputerUsePluginConfig): void {\n installComputerUseRuntime(cordis, config.pi, config.dependencies);\n}\n\nexport async function activateComputerUseExtension(\n pi: ExtensionAPI,\n dependencies: ComputerUseExtensionDependencies = createComputerUseContainer(),\n): Promise<void> {\n const connection = await connectDoomCordisHost(pi, PACKAGE_SOURCE, { allowStandalone: true });\n const fiber = connection.root.plugin(computerUsePlugin, { pi, dependencies });\n try {\n await fiber;\n } catch (error) {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n throw error;\n }\n let disposal: Promise<void> | undefined;\n pi.on(\n 'session_shutdown',\n () =>\n (disposal ??= (async () => {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n })()),\n );\n}\n\nexport default activateComputerUseExtension;\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { ComputerUseSessionView } from "../../types/computerUseApi.cjs";
2
2
  import { ComputerUseAction, ComputerUseObservation } from "../../types/computerUse.cjs";
3
3
  //#region src/adapters/pi/sessionApiClient.d.ts
4
- export interface ComputerUseSessionClient {
4
+ interface ComputerUseSessionClient {
5
5
  state(signal?: AbortSignal): Promise<ComputerUseSessionView>;
6
6
  observe(signal?: AbortSignal): Promise<ComputerUseObservation>;
7
7
  act(action: ComputerUseAction, signal?: AbortSignal): Promise<unknown>;
@@ -11,7 +11,7 @@ interface ClientOptions {
11
11
  readonly socketPath: string;
12
12
  readonly token: string;
13
13
  }
14
- export declare class UnixComputerUseSessionClient implements ComputerUseSessionClient {
14
+ declare class UnixComputerUseSessionClient implements ComputerUseSessionClient {
15
15
  private readonly options;
16
16
  constructor(options: ClientOptions);
17
17
  private request;
@@ -20,6 +20,7 @@ export declare class UnixComputerUseSessionClient implements ComputerUseSessionC
20
20
  act(action: ComputerUseAction, signal?: AbortSignal): Promise<unknown>;
21
21
  stop(signal?: AbortSignal): Promise<ComputerUseSessionView>;
22
22
  }
23
- export declare function createComputerUseSessionClient(environment?: NodeJS.ProcessEnv): ComputerUseSessionClient | undefined;
23
+ declare function createComputerUseSessionClient(environment?: NodeJS.ProcessEnv): ComputerUseSessionClient | undefined;
24
24
  //#endregion
25
+ export { ComputerUseSessionClient, UnixComputerUseSessionClient, createComputerUseSessionClient };
25
26
  //# sourceMappingURL=sessionApiClient.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sessionApiClient.d.cts","names":[],"sources":["../../../src/adapters/pi/sessionApiClient.ts"],"mappings":";;;iBASiB;EACf,MAAM,SAAS,cAAc,QAAQ;EACrC,QAAQ,SAAS,cAAc,QAAQ;EACvC,IAAI,QAAQ,mBAAmB,SAAS,cAAc;EACtD,KAAK,SAAS,cAAc,QAAQ;;UAG5B;WACC;WACA;;qBAGE,wCAAwC;mBACf;EAApC,YAAoC,SAAS;UAErC;EAyCK,MAAM,SAAS,cAAc,QAAQ;EAIrC,QAAQ,SAAS,cAAc,QAAQ;EAI7C,IAAI,QAAQ,mBAAmB,SAAS,cAAc;EAIhD,KAAK,SAAS,cAAc,QAAQ;;wBAKnC,+BACd,cAAa,OAAO,aACnB"}
1
+ {"version":3,"file":"sessionApiClient.d.cts","names":[],"sources":["../../../src/adapters/pi/sessionApiClient.ts"],"mappings":";;;UASiB;EACf,MAAM,SAAS,cAAc,QAAQ;EACrC,QAAQ,SAAS,cAAc,QAAQ;EACvC,IAAI,QAAQ,mBAAmB,SAAS,cAAc;EACtD,KAAK,SAAS,cAAc,QAAQ;;UAG5B;WACC;WACA;;cAGE,wCAAwC;mBACf;EAApC,YAAoC,SAAS;UAErC;EAyCK,MAAM,SAAS,cAAc,QAAQ;EAIrC,QAAQ,SAAS,cAAc,QAAQ;EAI7C,IAAI,QAAQ,mBAAmB,SAAS,cAAc;EAIhD,KAAK,SAAS,cAAc,QAAQ;;iBAKnC,+BACd,cAAa,OAAO,aACnB"}
@@ -1,7 +1,7 @@
1
1
  import { ComputerUseSessionView } from "../../types/computerUseApi.mjs";
2
2
  import { ComputerUseAction, ComputerUseObservation } from "../../types/computerUse.mjs";
3
3
  //#region src/adapters/pi/sessionApiClient.d.ts
4
- export interface ComputerUseSessionClient {
4
+ interface ComputerUseSessionClient {
5
5
  state(signal?: AbortSignal): Promise<ComputerUseSessionView>;
6
6
  observe(signal?: AbortSignal): Promise<ComputerUseObservation>;
7
7
  act(action: ComputerUseAction, signal?: AbortSignal): Promise<unknown>;
@@ -11,7 +11,7 @@ interface ClientOptions {
11
11
  readonly socketPath: string;
12
12
  readonly token: string;
13
13
  }
14
- export declare class UnixComputerUseSessionClient implements ComputerUseSessionClient {
14
+ declare class UnixComputerUseSessionClient implements ComputerUseSessionClient {
15
15
  private readonly options;
16
16
  constructor(options: ClientOptions);
17
17
  private request;
@@ -20,6 +20,7 @@ export declare class UnixComputerUseSessionClient implements ComputerUseSessionC
20
20
  act(action: ComputerUseAction, signal?: AbortSignal): Promise<unknown>;
21
21
  stop(signal?: AbortSignal): Promise<ComputerUseSessionView>;
22
22
  }
23
- export declare function createComputerUseSessionClient(environment?: NodeJS.ProcessEnv): ComputerUseSessionClient | undefined;
23
+ declare function createComputerUseSessionClient(environment?: NodeJS.ProcessEnv): ComputerUseSessionClient | undefined;
24
24
  //#endregion
25
+ export { ComputerUseSessionClient, UnixComputerUseSessionClient, createComputerUseSessionClient };
25
26
  //# sourceMappingURL=sessionApiClient.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sessionApiClient.d.mts","names":[],"sources":["../../../src/adapters/pi/sessionApiClient.ts"],"mappings":";;;iBASiB;EACf,MAAM,SAAS,cAAc,QAAQ;EACrC,QAAQ,SAAS,cAAc,QAAQ;EACvC,IAAI,QAAQ,mBAAmB,SAAS,cAAc;EACtD,KAAK,SAAS,cAAc,QAAQ;;UAG5B;WACC;WACA;;qBAGE,wCAAwC;mBACf;EAApC,YAAoC,SAAS;UAErC;EAyCK,MAAM,SAAS,cAAc,QAAQ;EAIrC,QAAQ,SAAS,cAAc,QAAQ;EAI7C,IAAI,QAAQ,mBAAmB,SAAS,cAAc;EAIhD,KAAK,SAAS,cAAc,QAAQ;;wBAKnC,+BACd,cAAa,OAAO,aACnB"}
1
+ {"version":3,"file":"sessionApiClient.d.mts","names":[],"sources":["../../../src/adapters/pi/sessionApiClient.ts"],"mappings":";;;UASiB;EACf,MAAM,SAAS,cAAc,QAAQ;EACrC,QAAQ,SAAS,cAAc,QAAQ;EACvC,IAAI,QAAQ,mBAAmB,SAAS,cAAc;EACtD,KAAK,SAAS,cAAc,QAAQ;;UAG5B;WACC;WACA;;cAGE,wCAAwC;mBACf;EAApC,YAAoC,SAAS;UAErC;EAyCK,MAAM,SAAS,cAAc,QAAQ;EAIrC,QAAQ,SAAS,cAAc,QAAQ;EAI7C,IAAI,QAAQ,mBAAmB,SAAS,cAAc;EAIhD,KAAK,SAAS,cAAc,QAAQ;;iBAKnC,+BACd,cAAa,OAAO,aACnB"}
@@ -1,2 +1,2 @@
1
- const e=require("../types/computerUseApi.cjs"),t=require("./webComputerUseAvailability.cjs");let n=require("node:crypto");function r(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:void 0}function i(e){let t=r(e);return t?.action===`status`||t?.action===`targets`||t?.action===`stop`||t?.action===`artifacts`?{action:t.action}:void 0}async function a(e){let n=await e.json();if(!e.ok)throw t.computerUseSessionApiError(e.status,n);return n}function o(o={}){let s;return{frameType:e.computerUseChannelType,lifecycle:`hub`,start(c){let l=new Map,u=new Map,d=new Map,f=new Map,p=new Set,m=new Map,h,g=!1,_=async(t,n,r=`GET`,i)=>c.requestSessionApi(t,{basePath:e.API_BASE_PATH,path:n,method:r,...i===void 0?{}:{body:JSON.stringify(i)}}),v=(e,t)=>{let n={state:t,targets:d.get(e.sessionId)??[],...h!==void 0&&h!==e.sessionId?{busy:!0}:{}};u.set(e.sessionId,n),c.publish(e.sessionId,n)},y=async t=>{let n=await a(await _(t,e.COMPUTER_USE_ROUTES.hubState));if(n.phase===`active`||n.phase===`activating`||n.phase===`stopping`){if(h=t.sessionId,n.phase===`active`&&!f.has(t.sessionId)){let n=await a(await _(t,e.COMPUTER_USE_ROUTES.hubAuthorization));n!==null&&f.set(t.sessionId,n.grantId)}}else h===t.sessionId&&(h=void 0),f.delete(t.sessionId);return m.delete(t.sessionId),v(t,n),n},b=async(t,n)=>{if(!c.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);try{let r=await c.computerUse.request(t,{operation:n.operation,payload:n.operation===`act`?{grantId:n.grantId,sequence:n.sequence,action:n.payload}:{grantId:n.grantId}});await a(await _(t,e.COMPUTER_USE_ROUTES.hubComplete,`POST`,{id:n.id,result:r}))}catch(r){await a(await _(t,e.COMPUTER_USE_ROUTES.hubComplete,`POST`,{id:n.id,error:r instanceof Error?r.message:String(r)}))}},x=async t=>{let r=await a(await _(t,e.COMPUTER_USE_ROUTES.hubAuthorization)),i;if(r!==null&&c.computerUse?.available)try{i=await c.computerUse.request(t,{operation:`stop`,payload:{grantId:r.grantId}})}catch(e){let t=e instanceof Error?e.message:String(e);i={artifactId:(0,n.randomUUID)(),status:`failed`,failure:{code:`recording_failed`,message:t.slice(0,512)}},c.onNotice(`computer-use Desktop stop was already unavailable (${t})`)}await a(await _(t,e.COMPUTER_USE_ROUTES.hubStop,`POST`,{artifact:i})),f.delete(t.sessionId),h===t.sessionId&&(h=void 0)},S=async n=>{if(!(g||p.has(n.sessionId))&&!((m.get(n.sessionId)??0)>Date.now())){p.add(n.sessionId);try{let t=await y(n);if(t.phase===`active`){let e=typeof t.expiresAt==`number`&&t.expiresAt<=Date.now(),i=!1;if(!e&&c.computerUse?.available)try{i=r(await c.computerUse.request(n,{operation:`status`}))?.ownedBySession===!0}catch{i=!0}if(e||!i){await x(n),await y(n);return}}if(t.phase===`awaiting_confirmation`&&(h===void 0||h===n.sessionId)){if(!c.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);let t=await a(await _(n,e.COMPUTER_USE_ROUTES.hubActivation));if(t!==null){h=n.sessionId;try{let i=await c.computerUse.request(n,{operation:`activate`,payload:t});await a(await _(n,e.COMPUTER_USE_ROUTES.hubStop,`POST`,{host:i}));let o=r(i)?.grantId;typeof o==`string`&&f.set(n.sessionId,o)}catch(t){h=void 0,await a(await _(n,e.COMPUTER_USE_ROUTES.hubStop,`POST`,{error:t instanceof Error?t.message:String(t)}))}await y(n)}}t.phase===`stopping`&&(await x(n),await y(n));let i=await a(await _(n,e.COMPUTER_USE_ROUTES.hubNext));i!==null&&await b(n,i)}catch(e){e instanceof t.MissingComputerUseApiError?(m.set(n.sessionId,t.missingComputerUseApiRetryAt(Date.now())),u.delete(n.sessionId)):c.onNotice(`computer-use poll failed for ${n.sessionId} (${e instanceof Error?e.message:String(e)})`)}finally{p.delete(n.sessionId)}}};s=(e,n)=>{let a=i(n);a!==void 0&&(m.delete(e.sessionId),(async()=>{try{if(a.action===`targets`){if(!c.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);let t=await c.computerUse.request(e,{operation:`targets`});d.set(e.sessionId,Array.isArray(t)?t.filter(e=>r(e)!==void 0):[])}else a.action===`stop`&&await x(e);await y(e)}catch(n){n instanceof t.MissingComputerUseApiError?(m.set(e.sessionId,t.missingComputerUseApiRetryAt(Date.now())),u.delete(e.sessionId)):c.onNotice(`computer-use command failed for ${e.sessionId} (${n instanceof Error?n.message:String(n)})`)}})())};let C=setInterval(()=>{for(let e of l.values())S(e)},o.pollMs??250);return{payloadFor:e=>u.get(e.sessionId),sessionAdded(e){l.set(e.sessionId,e),S(e)},sessionRemoved(e){let t=l.get(e),n=f.get(e);t!==void 0&&n!==void 0&&c.computerUse?.available&&c.computerUse.request(t,{operation:`stop`,payload:{grantId:n}}).catch(e=>c.onNotice(`computer-use session cleanup failed (${e instanceof Error?e.message:String(e)})`)),l.delete(e),u.delete(e),d.delete(e),f.delete(e),p.delete(e),m.delete(e),h===e&&(h=void 0)},close(){if(g=!0,clearInterval(C),c.computerUse?.available)for(let[e,t]of f){let n=l.get(e);n!==void 0&&c.computerUse.request(n,{operation:`stop`,payload:{grantId:t}}).catch(()=>void 0)}l.clear(),u.clear(),d.clear(),f.clear(),m.clear()}}},receive(e,t){s?.(e,t)}}}const s=[o()];exports.computerUseChannelType=e.computerUseChannelType,exports.createComputerUseChannel=o,exports.webHubChannels=s;
1
+ const e=require("../types/computerUseApi.cjs"),t=require("./webComputerUseAvailability.cjs");function n(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:void 0}function r(e){let t=n(e);return t?.action===`status`||t?.action===`targets`||t?.action===`stop`||t?.action===`artifacts`?{action:t.action}:void 0}async function i(e){let n=await e.json();if(!e.ok)throw t.computerUseSessionApiError(e.status,n);return n}function a(a={}){let o;return{frameType:e.computerUseChannelType,lifecycle:`hub`,start(s){let c=new Map,l=new Map,u=new Map,d=new Map,f=new Set,p=new Map,m,h=!1,g=async(t,n,r=`GET`,i)=>s.requestSessionApi(t,{basePath:e.API_BASE_PATH,path:n,method:r,...i===void 0?{}:{body:JSON.stringify(i)}}),_=(e,t)=>{let n={state:t,targets:u.get(e.sessionId)??[],...m!==void 0&&m!==e.sessionId?{busy:!0}:{}};l.set(e.sessionId,n),s.publish(e.sessionId,n)},v=async t=>{let n=await i(await g(t,e.COMPUTER_USE_ROUTES.hubState));if(n.phase===`active`||n.phase===`activating`||n.phase===`stopping`){if(m=t.sessionId,n.phase===`active`&&!d.has(t.sessionId)){let n=await i(await g(t,e.COMPUTER_USE_ROUTES.hubAuthorization));n!==null&&d.set(t.sessionId,n.grantId)}}else m===t.sessionId&&(m=void 0),d.delete(t.sessionId);return p.delete(t.sessionId),_(t,n),n},y=async(t,n)=>{if(!s.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);try{let r=await s.computerUse.request(t,{operation:n.operation,payload:n.operation===`act`?{grantId:n.grantId,sequence:n.sequence,action:n.payload}:{grantId:n.grantId}});await i(await g(t,e.COMPUTER_USE_ROUTES.hubComplete,`POST`,{id:n.id,result:r}))}catch(r){await i(await g(t,e.COMPUTER_USE_ROUTES.hubComplete,`POST`,{id:n.id,error:r instanceof Error?r.message:String(r)}))}},b=async t=>{let n=await i(await g(t,e.COMPUTER_USE_ROUTES.hubAuthorization)),r;if(n!==null&&s.computerUse?.available)try{r=await s.computerUse.request(t,{operation:`stop`,payload:{grantId:n.grantId}})}catch(e){s.onNotice(`computer-use Desktop stop was already unavailable (${e instanceof Error?e.message:String(e)})`)}await i(await g(t,e.COMPUTER_USE_ROUTES.hubStop,`POST`,{artifact:r})),d.delete(t.sessionId),m===t.sessionId&&(m=void 0)},x=async r=>{if(!(h||f.has(r.sessionId))&&!((p.get(r.sessionId)??0)>Date.now())){f.add(r.sessionId);try{let t=await v(r);if(t.phase===`active`){let a=typeof t.expiresAt==`number`&&t.expiresAt<=Date.now(),o=!1;if(!a&&s.computerUse?.available)try{o=n(await s.computerUse.request(r,{operation:`status`}))?.ownedBySession===!0}catch{o=!0}if(a||!o){await i(await g(r,e.COMPUTER_USE_ROUTES.hubStop,`POST`)),d.delete(r.sessionId),m===r.sessionId&&(m=void 0),await v(r);return}}if(t.phase===`awaiting_confirmation`&&(m===void 0||m===r.sessionId)){if(!s.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);let t=await i(await g(r,e.COMPUTER_USE_ROUTES.hubActivation));if(t!==null){m=r.sessionId;try{let a=await s.computerUse.request(r,{operation:`activate`,payload:t});await i(await g(r,e.COMPUTER_USE_ROUTES.hubStop,`POST`,{host:a}));let o=n(a)?.grantId;typeof o==`string`&&d.set(r.sessionId,o)}catch(t){m=void 0,await i(await g(r,e.COMPUTER_USE_ROUTES.hubStop,`POST`,{error:t instanceof Error?t.message:String(t)}))}await v(r)}}t.phase===`stopping`&&(await b(r),await v(r));let a=await i(await g(r,e.COMPUTER_USE_ROUTES.hubNext));a!==null&&await y(r,a)}catch(e){e instanceof t.MissingComputerUseApiError?(p.set(r.sessionId,t.missingComputerUseApiRetryAt(Date.now())),l.delete(r.sessionId)):s.onNotice(`computer-use poll failed for ${r.sessionId} (${e instanceof Error?e.message:String(e)})`)}finally{f.delete(r.sessionId)}}};o=(e,i)=>{let a=r(i);a!==void 0&&(p.delete(e.sessionId),(async()=>{try{if(a.action===`targets`){if(!s.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);let t=await s.computerUse.request(e,{operation:`targets`});u.set(e.sessionId,Array.isArray(t)?t.filter(e=>n(e)!==void 0):[])}else a.action===`stop`&&await b(e);await v(e)}catch(n){n instanceof t.MissingComputerUseApiError?(p.set(e.sessionId,t.missingComputerUseApiRetryAt(Date.now())),l.delete(e.sessionId)):s.onNotice(`computer-use command failed for ${e.sessionId} (${n instanceof Error?n.message:String(n)})`)}})())};let S=setInterval(()=>{for(let e of c.values())x(e)},a.pollMs??250);return{payloadFor:e=>l.get(e.sessionId),sessionAdded(e){c.set(e.sessionId,e),x(e)},sessionRemoved(e){let t=c.get(e),n=d.get(e);t!==void 0&&n!==void 0&&s.computerUse?.available&&s.computerUse.request(t,{operation:`stop`,payload:{grantId:n}}).catch(e=>s.onNotice(`computer-use session cleanup failed (${e instanceof Error?e.message:String(e)})`)),c.delete(e),l.delete(e),u.delete(e),d.delete(e),f.delete(e),p.delete(e),m===e&&(m=void 0)},close(){if(h=!0,clearInterval(S),s.computerUse?.available)for(let[e,t]of d){let n=c.get(e);n!==void 0&&s.computerUse.request(n,{operation:`stop`,payload:{grantId:t}}).catch(()=>void 0)}c.clear(),l.clear(),u.clear(),d.clear(),p.clear()}}},receive(e,t){o?.(e,t)}}}const o=[a()];exports.computerUseChannelType=e.computerUseChannelType,exports.createComputerUseChannel=a,exports.webHubChannels=o;
2
2
  //# sourceMappingURL=webComputerUseChannel.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"webComputerUseChannel.cjs","names":["computerUseSessionApiError","computerUseChannelType","API_BASE_PATH","COMPUTER_USE_ROUTES","randomUUID","MissingComputerUseApiError","missingComputerUseApiRetryAt"],"sources":["../../src/adapters/webComputerUseChannel.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { HubChannelSource, HubSessionScope, WebHubChannel } from '@agimon-ai/doompi-web-contracts';\nimport {\n API_BASE_PATH,\n computerUseChannelType,\n COMPUTER_USE_ROUTES,\n type ComputerUseActivationRequest,\n type ComputerUseBrokerRequest,\n type ComputerUseBrowserCommand,\n type ComputerUseChannelPayload,\n type ComputerUseSessionView,\n} from '../types/computerUseApi.ts';\nimport {\n computerUseSessionApiError,\n MissingComputerUseApiError,\n missingComputerUseApiRetryAt,\n} from './webComputerUseAvailability.ts';\nexport { computerUseChannelType };\n\nconst POLL_MS = 250;\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction command(value: unknown): ComputerUseBrowserCommand | undefined {\n const input = record(value);\n return input?.action === 'status' ||\n input?.action === 'targets' ||\n input?.action === 'stop' ||\n input?.action === 'artifacts'\n ? { action: input.action }\n : undefined;\n}\n\nasync function responseJson(response: Response): Promise<unknown> {\n const value = await response.json();\n if (!response.ok) throw computerUseSessionApiError(response.status, value);\n return value;\n}\n\nexport function createComputerUseChannel(options: { pollMs?: number } = {}): WebHubChannel {\n let receiveCommand: ((scope: HubSessionScope, payload: unknown) => void) | undefined;\n return {\n frameType: computerUseChannelType,\n lifecycle: 'hub',\n start(host) {\n const scopes = new Map<string, HubSessionScope>();\n const latest = new Map<string, ComputerUseChannelPayload>();\n const targets = new Map<string, readonly Record<string, unknown>[]>();\n const grants = new Map<string, string>();\n const processing = new Set<string>();\n const unavailableUntil = new Map<string, number>();\n let activeSessionId: string | undefined;\n let closed = false;\n\n const sessionRequest = async (scope: HubSessionScope, path: string, method = 'GET', value?: unknown) =>\n host.requestSessionApi(scope, {\n basePath: API_BASE_PATH,\n path,\n method,\n ...(value === undefined ? {} : { body: JSON.stringify(value) }),\n });\n\n const publish = (scope: HubSessionScope, state: ComputerUseSessionView): void => {\n const payload: ComputerUseChannelPayload = {\n state,\n targets: targets.get(scope.sessionId) ?? [],\n ...(activeSessionId !== undefined && activeSessionId !== scope.sessionId ? { busy: true } : {}),\n };\n latest.set(scope.sessionId, payload);\n host.publish(scope.sessionId, payload);\n };\n\n const refresh = async (scope: HubSessionScope): Promise<ComputerUseSessionView> => {\n const state = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubState),\n )) as ComputerUseSessionView;\n if (state.phase === 'active' || state.phase === 'activating' || state.phase === 'stopping') {\n activeSessionId = scope.sessionId;\n if (state.phase === 'active' && !grants.has(scope.sessionId)) {\n const authorization = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubAuthorization),\n )) as { grantId: string } | null;\n if (authorization !== null) grants.set(scope.sessionId, authorization.grantId);\n }\n } else {\n if (activeSessionId === scope.sessionId) activeSessionId = undefined;\n grants.delete(scope.sessionId);\n }\n unavailableUntil.delete(scope.sessionId);\n publish(scope, state);\n return state;\n };\n\n const completePending = async (scope: HubSessionScope, pending: ComputerUseBrokerRequest): Promise<void> => {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n try {\n const result = await host.computerUse.request(scope, {\n operation: pending.operation,\n payload:\n pending.operation === 'act'\n ? { grantId: pending.grantId, sequence: pending.sequence, action: pending.payload }\n : { grantId: pending.grantId },\n });\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubComplete, 'POST', { id: pending.id, result }),\n );\n } catch (error) {\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubComplete, 'POST', {\n id: pending.id,\n error: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n };\n\n const stopSession = async (scope: HubSessionScope): Promise<void> => {\n const authorization = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubAuthorization),\n )) as { grantId: string } | null;\n let artifact: unknown;\n if (authorization !== null && host.computerUse?.available) {\n try {\n artifact = await host.computerUse.request(scope, {\n operation: 'stop',\n payload: { grantId: authorization.grantId },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n artifact = {\n artifactId: randomUUID(),\n status: 'failed',\n failure: { code: 'recording_failed', message: message.slice(0, 512) },\n };\n host.onNotice(`computer-use Desktop stop was already unavailable (${message})`);\n }\n }\n await responseJson(await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', { artifact }));\n grants.delete(scope.sessionId);\n if (activeSessionId === scope.sessionId) activeSessionId = undefined;\n };\n const pollScope = async (scope: HubSessionScope): Promise<void> => {\n if (closed || processing.has(scope.sessionId)) return;\n if ((unavailableUntil.get(scope.sessionId) ?? 0) > Date.now()) return;\n processing.add(scope.sessionId);\n try {\n const state = await refresh(scope);\n if (state.phase === 'active') {\n const expired = typeof state.expiresAt === 'number' && state.expiresAt <= Date.now();\n let owned = false;\n if (!expired && host.computerUse?.available) {\n try {\n const hostStatus = record(await host.computerUse.request(scope, { operation: 'status' }));\n owned = hostStatus?.ownedBySession === true;\n } catch {\n owned = true;\n }\n }\n if (expired || !owned) {\n await stopSession(scope);\n await refresh(scope);\n return;\n }\n }\n if (\n state.phase === 'awaiting_confirmation' &&\n (activeSessionId === undefined || activeSessionId === scope.sessionId)\n ) {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n const activation = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubActivation),\n )) as ComputerUseActivationRequest | null;\n if (activation !== null) {\n activeSessionId = scope.sessionId;\n try {\n const hostResult = await host.computerUse.request(scope, {\n operation: 'activate',\n payload: activation,\n });\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', { host: hostResult }),\n );\n const grantId = record(hostResult)?.grantId;\n if (typeof grantId === 'string') grants.set(scope.sessionId, grantId);\n } catch (error) {\n activeSessionId = undefined;\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', {\n error: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n await refresh(scope);\n }\n }\n if (state.phase === 'stopping') {\n await stopSession(scope);\n await refresh(scope);\n }\n const pending = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubNext),\n )) as ComputerUseBrokerRequest | null;\n if (pending !== null) await completePending(scope, pending);\n } catch (error) {\n if (error instanceof MissingComputerUseApiError) {\n unavailableUntil.set(scope.sessionId, missingComputerUseApiRetryAt(Date.now()));\n latest.delete(scope.sessionId);\n } else {\n host.onNotice(\n `computer-use poll failed for ${scope.sessionId} (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n } finally {\n processing.delete(scope.sessionId);\n }\n };\n\n receiveCommand = (scope, payload) => {\n const parsed = command(payload);\n if (parsed === undefined) return;\n unavailableUntil.delete(scope.sessionId);\n void (async () => {\n try {\n if (parsed.action === 'targets') {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n const result = await host.computerUse.request(scope, { operation: 'targets' });\n targets.set(\n scope.sessionId,\n Array.isArray(result)\n ? result.filter((item): item is Record<string, unknown> => record(item) !== undefined)\n : [],\n );\n } else if (parsed.action === 'stop') {\n await stopSession(scope);\n }\n await refresh(scope);\n } catch (error) {\n if (error instanceof MissingComputerUseApiError) {\n unavailableUntil.set(scope.sessionId, missingComputerUseApiRetryAt(Date.now()));\n latest.delete(scope.sessionId);\n } else {\n host.onNotice(\n `computer-use command failed for ${scope.sessionId} (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n }\n })();\n };\n\n const timer: ReturnType<typeof setInterval> = setInterval(() => {\n for (const scope of scopes.values()) void pollScope(scope);\n }, options.pollMs ?? POLL_MS);\n\n const source: HubChannelSource = {\n payloadFor: (scope) => latest.get(scope.sessionId),\n sessionAdded(scope) {\n scopes.set(scope.sessionId, scope);\n void pollScope(scope);\n },\n sessionRemoved(sessionId) {\n const scope = scopes.get(sessionId);\n const grantId = grants.get(sessionId);\n if (scope !== undefined && grantId !== undefined && host.computerUse?.available) {\n void host.computerUse\n .request(scope, { operation: 'stop', payload: { grantId } })\n .catch((error: unknown) =>\n host.onNotice(\n `computer-use session cleanup failed (${error instanceof Error ? error.message : String(error)})`,\n ),\n );\n }\n scopes.delete(sessionId);\n latest.delete(sessionId);\n targets.delete(sessionId);\n grants.delete(sessionId);\n processing.delete(sessionId);\n unavailableUntil.delete(sessionId);\n if (activeSessionId === sessionId) activeSessionId = undefined;\n },\n close() {\n closed = true;\n clearInterval(timer);\n if (host.computerUse?.available) {\n for (const [sessionId, grantId] of grants) {\n const scope = scopes.get(sessionId);\n if (scope !== undefined)\n void host.computerUse\n .request(scope, { operation: 'stop', payload: { grantId } })\n .catch(() => undefined);\n }\n }\n scopes.clear();\n latest.clear();\n targets.clear();\n grants.clear();\n unavailableUntil.clear();\n },\n };\n return source;\n },\n receive(scope, payload) {\n receiveCommand?.(scope, payload);\n },\n };\n}\n\nexport const webHubChannels: readonly WebHubChannel[] = [createComputerUseChannel()];\n"],"mappings":"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"}
1
+ {"version":3,"file":"webComputerUseChannel.cjs","names":["computerUseSessionApiError","computerUseChannelType","API_BASE_PATH","COMPUTER_USE_ROUTES","MissingComputerUseApiError","missingComputerUseApiRetryAt"],"sources":["../../src/adapters/webComputerUseChannel.ts"],"sourcesContent":["import type { HubChannelSource, HubSessionScope, WebHubChannel } from '@agimon-ai/doompi-web-contracts';\nimport {\n API_BASE_PATH,\n computerUseChannelType,\n COMPUTER_USE_ROUTES,\n type ComputerUseActivationRequest,\n type ComputerUseBrokerRequest,\n type ComputerUseBrowserCommand,\n type ComputerUseChannelPayload,\n type ComputerUseSessionView,\n} from '../types/computerUseApi.ts';\nimport {\n computerUseSessionApiError,\n MissingComputerUseApiError,\n missingComputerUseApiRetryAt,\n} from './webComputerUseAvailability.ts';\nexport { computerUseChannelType };\n\nconst POLL_MS = 250;\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction command(value: unknown): ComputerUseBrowserCommand | undefined {\n const input = record(value);\n return input?.action === 'status' ||\n input?.action === 'targets' ||\n input?.action === 'stop' ||\n input?.action === 'artifacts'\n ? { action: input.action }\n : undefined;\n}\n\nasync function responseJson(response: Response): Promise<unknown> {\n const value = await response.json();\n if (!response.ok) throw computerUseSessionApiError(response.status, value);\n return value;\n}\n\nexport function createComputerUseChannel(options: { pollMs?: number } = {}): WebHubChannel {\n let receiveCommand: ((scope: HubSessionScope, payload: unknown) => void) | undefined;\n return {\n frameType: computerUseChannelType,\n lifecycle: 'hub',\n start(host) {\n const scopes = new Map<string, HubSessionScope>();\n const latest = new Map<string, ComputerUseChannelPayload>();\n const targets = new Map<string, readonly Record<string, unknown>[]>();\n const grants = new Map<string, string>();\n const processing = new Set<string>();\n const unavailableUntil = new Map<string, number>();\n let activeSessionId: string | undefined;\n let closed = false;\n\n const sessionRequest = async (scope: HubSessionScope, path: string, method = 'GET', value?: unknown) =>\n host.requestSessionApi(scope, {\n basePath: API_BASE_PATH,\n path,\n method,\n ...(value === undefined ? {} : { body: JSON.stringify(value) }),\n });\n\n const publish = (scope: HubSessionScope, state: ComputerUseSessionView): void => {\n const payload: ComputerUseChannelPayload = {\n state,\n targets: targets.get(scope.sessionId) ?? [],\n ...(activeSessionId !== undefined && activeSessionId !== scope.sessionId ? { busy: true } : {}),\n };\n latest.set(scope.sessionId, payload);\n host.publish(scope.sessionId, payload);\n };\n\n const refresh = async (scope: HubSessionScope): Promise<ComputerUseSessionView> => {\n const state = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubState),\n )) as ComputerUseSessionView;\n if (state.phase === 'active' || state.phase === 'activating' || state.phase === 'stopping') {\n activeSessionId = scope.sessionId;\n if (state.phase === 'active' && !grants.has(scope.sessionId)) {\n const authorization = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubAuthorization),\n )) as { grantId: string } | null;\n if (authorization !== null) grants.set(scope.sessionId, authorization.grantId);\n }\n } else {\n if (activeSessionId === scope.sessionId) activeSessionId = undefined;\n grants.delete(scope.sessionId);\n }\n unavailableUntil.delete(scope.sessionId);\n publish(scope, state);\n return state;\n };\n\n const completePending = async (scope: HubSessionScope, pending: ComputerUseBrokerRequest): Promise<void> => {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n try {\n const result = await host.computerUse.request(scope, {\n operation: pending.operation,\n payload:\n pending.operation === 'act'\n ? { grantId: pending.grantId, sequence: pending.sequence, action: pending.payload }\n : { grantId: pending.grantId },\n });\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubComplete, 'POST', { id: pending.id, result }),\n );\n } catch (error) {\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubComplete, 'POST', {\n id: pending.id,\n error: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n };\n\n const stopSession = async (scope: HubSessionScope): Promise<void> => {\n const authorization = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubAuthorization),\n )) as { grantId: string } | null;\n let artifact: unknown;\n if (authorization !== null && host.computerUse?.available) {\n try {\n artifact = await host.computerUse.request(scope, {\n operation: 'stop',\n payload: { grantId: authorization.grantId },\n });\n } catch (error) {\n host.onNotice(\n `computer-use Desktop stop was already unavailable (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n }\n await responseJson(await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', { artifact }));\n grants.delete(scope.sessionId);\n if (activeSessionId === scope.sessionId) activeSessionId = undefined;\n };\n const pollScope = async (scope: HubSessionScope): Promise<void> => {\n if (closed || processing.has(scope.sessionId)) return;\n if ((unavailableUntil.get(scope.sessionId) ?? 0) > Date.now()) return;\n processing.add(scope.sessionId);\n try {\n const state = await refresh(scope);\n if (state.phase === 'active') {\n const expired = typeof state.expiresAt === 'number' && state.expiresAt <= Date.now();\n let owned = false;\n if (!expired && host.computerUse?.available) {\n try {\n const hostStatus = record(await host.computerUse.request(scope, { operation: 'status' }));\n owned = hostStatus?.ownedBySession === true;\n } catch {\n owned = true;\n }\n }\n if (expired || !owned) {\n await responseJson(await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST'));\n grants.delete(scope.sessionId);\n if (activeSessionId === scope.sessionId) activeSessionId = undefined;\n await refresh(scope);\n return;\n }\n }\n if (\n state.phase === 'awaiting_confirmation' &&\n (activeSessionId === undefined || activeSessionId === scope.sessionId)\n ) {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n const activation = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubActivation),\n )) as ComputerUseActivationRequest | null;\n if (activation !== null) {\n activeSessionId = scope.sessionId;\n try {\n const hostResult = await host.computerUse.request(scope, {\n operation: 'activate',\n payload: activation,\n });\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', { host: hostResult }),\n );\n const grantId = record(hostResult)?.grantId;\n if (typeof grantId === 'string') grants.set(scope.sessionId, grantId);\n } catch (error) {\n activeSessionId = undefined;\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', {\n error: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n await refresh(scope);\n }\n }\n if (state.phase === 'stopping') {\n await stopSession(scope);\n await refresh(scope);\n }\n const pending = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubNext),\n )) as ComputerUseBrokerRequest | null;\n if (pending !== null) await completePending(scope, pending);\n } catch (error) {\n if (error instanceof MissingComputerUseApiError) {\n unavailableUntil.set(scope.sessionId, missingComputerUseApiRetryAt(Date.now()));\n latest.delete(scope.sessionId);\n } else {\n host.onNotice(\n `computer-use poll failed for ${scope.sessionId} (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n } finally {\n processing.delete(scope.sessionId);\n }\n };\n\n receiveCommand = (scope, payload) => {\n const parsed = command(payload);\n if (parsed === undefined) return;\n unavailableUntil.delete(scope.sessionId);\n void (async () => {\n try {\n if (parsed.action === 'targets') {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n const result = await host.computerUse.request(scope, { operation: 'targets' });\n targets.set(\n scope.sessionId,\n Array.isArray(result)\n ? result.filter((item): item is Record<string, unknown> => record(item) !== undefined)\n : [],\n );\n } else if (parsed.action === 'stop') {\n await stopSession(scope);\n }\n await refresh(scope);\n } catch (error) {\n if (error instanceof MissingComputerUseApiError) {\n unavailableUntil.set(scope.sessionId, missingComputerUseApiRetryAt(Date.now()));\n latest.delete(scope.sessionId);\n } else {\n host.onNotice(\n `computer-use command failed for ${scope.sessionId} (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n }\n })();\n };\n\n const timer: ReturnType<typeof setInterval> = setInterval(() => {\n for (const scope of scopes.values()) void pollScope(scope);\n }, options.pollMs ?? POLL_MS);\n\n const source: HubChannelSource = {\n payloadFor: (scope) => latest.get(scope.sessionId),\n sessionAdded(scope) {\n scopes.set(scope.sessionId, scope);\n void pollScope(scope);\n },\n sessionRemoved(sessionId) {\n const scope = scopes.get(sessionId);\n const grantId = grants.get(sessionId);\n if (scope !== undefined && grantId !== undefined && host.computerUse?.available) {\n void host.computerUse\n .request(scope, { operation: 'stop', payload: { grantId } })\n .catch((error: unknown) =>\n host.onNotice(\n `computer-use session cleanup failed (${error instanceof Error ? error.message : String(error)})`,\n ),\n );\n }\n scopes.delete(sessionId);\n latest.delete(sessionId);\n targets.delete(sessionId);\n grants.delete(sessionId);\n processing.delete(sessionId);\n unavailableUntil.delete(sessionId);\n if (activeSessionId === sessionId) activeSessionId = undefined;\n },\n close() {\n closed = true;\n clearInterval(timer);\n if (host.computerUse?.available) {\n for (const [sessionId, grantId] of grants) {\n const scope = scopes.get(sessionId);\n if (scope !== undefined)\n void host.computerUse\n .request(scope, { operation: 'stop', payload: { grantId } })\n .catch(() => undefined);\n }\n }\n scopes.clear();\n latest.clear();\n targets.clear();\n grants.clear();\n unavailableUntil.clear();\n },\n };\n return source;\n },\n receive(scope, payload) {\n receiveCommand?.(scope, payload);\n },\n };\n}\n\nexport const webHubChannels: readonly WebHubChannel[] = [createComputerUseChannel()];\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { computerUseChannelType } from "../types/computerUseApi.cjs";
2
2
  import { WebHubChannel } from "@agimon-ai/doompi-web-contracts";
3
3
  //#region src/adapters/webComputerUseChannel.d.ts
4
- export declare function createComputerUseChannel(options?: {
4
+ declare function createComputerUseChannel(options?: {
5
5
  pollMs?: number;
6
6
  }): WebHubChannel;
7
- export declare const webHubChannels: readonly WebHubChannel[];
7
+ declare const webHubChannels: readonly WebHubChannel[];
8
8
  //#endregion
9
- export { computerUseChannelType };
9
+ export { computerUseChannelType, createComputerUseChannel, webHubChannels };
10
10
  //# sourceMappingURL=webComputerUseChannel.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webComputerUseChannel.d.cts","names":[],"sources":["../../src/adapters/webComputerUseChannel.ts"],"mappings":";;;wBA2CgB,yBAAyB;EAAW;IAAyB;qBA2QhE,yBAAyB"}
1
+ {"version":3,"file":"webComputerUseChannel.d.cts","names":[],"sources":["../../src/adapters/webComputerUseChannel.ts"],"mappings":";;;iBA0CgB,yBAAyB;EAAW;IAAyB;cAyQhE,yBAAyB"}
@@ -1,10 +1,10 @@
1
1
  import { computerUseChannelType } from "../types/computerUseApi.mjs";
2
2
  import { WebHubChannel } from "@agimon-ai/doompi-web-contracts";
3
3
  //#region src/adapters/webComputerUseChannel.d.ts
4
- export declare function createComputerUseChannel(options?: {
4
+ declare function createComputerUseChannel(options?: {
5
5
  pollMs?: number;
6
6
  }): WebHubChannel;
7
- export declare const webHubChannels: readonly WebHubChannel[];
7
+ declare const webHubChannels: readonly WebHubChannel[];
8
8
  //#endregion
9
- export { computerUseChannelType };
9
+ export { computerUseChannelType, createComputerUseChannel, webHubChannels };
10
10
  //# sourceMappingURL=webComputerUseChannel.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webComputerUseChannel.d.mts","names":[],"sources":["../../src/adapters/webComputerUseChannel.ts"],"mappings":";;;wBA2CgB,yBAAyB;EAAW;IAAyB;qBA2QhE,yBAAyB"}
1
+ {"version":3,"file":"webComputerUseChannel.d.mts","names":[],"sources":["../../src/adapters/webComputerUseChannel.ts"],"mappings":";;;iBA0CgB,yBAAyB;EAAW;IAAyB;cAyQhE,yBAAyB"}
@@ -1,2 +1,2 @@
1
- import{API_BASE_PATH as e,COMPUTER_USE_ROUTES as t,computerUseChannelType as n}from"../types/computerUseApi.mjs";import{MissingComputerUseApiError as r,computerUseSessionApiError as i,missingComputerUseApiRetryAt as a}from"./webComputerUseAvailability.mjs";import{randomUUID as o}from"node:crypto";function s(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:void 0}function c(e){let t=s(e);return t?.action===`status`||t?.action===`targets`||t?.action===`stop`||t?.action===`artifacts`?{action:t.action}:void 0}async function l(e){let t=await e.json();if(!e.ok)throw i(e.status,t);return t}function u(i={}){let u;return{frameType:n,lifecycle:`hub`,start(n){let d=new Map,f=new Map,p=new Map,m=new Map,h=new Set,g=new Map,_,v=!1,y=async(t,r,i=`GET`,a)=>n.requestSessionApi(t,{basePath:e,path:r,method:i,...a===void 0?{}:{body:JSON.stringify(a)}}),b=(e,t)=>{let r={state:t,targets:p.get(e.sessionId)??[],..._!==void 0&&_!==e.sessionId?{busy:!0}:{}};f.set(e.sessionId,r),n.publish(e.sessionId,r)},x=async e=>{let n=await l(await y(e,t.hubState));if(n.phase===`active`||n.phase===`activating`||n.phase===`stopping`){if(_=e.sessionId,n.phase===`active`&&!m.has(e.sessionId)){let n=await l(await y(e,t.hubAuthorization));n!==null&&m.set(e.sessionId,n.grantId)}}else _===e.sessionId&&(_=void 0),m.delete(e.sessionId);return g.delete(e.sessionId),b(e,n),n},S=async(e,r)=>{if(!n.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);try{let i=await n.computerUse.request(e,{operation:r.operation,payload:r.operation===`act`?{grantId:r.grantId,sequence:r.sequence,action:r.payload}:{grantId:r.grantId}});await l(await y(e,t.hubComplete,`POST`,{id:r.id,result:i}))}catch(n){await l(await y(e,t.hubComplete,`POST`,{id:r.id,error:n instanceof Error?n.message:String(n)}))}},C=async e=>{let r=await l(await y(e,t.hubAuthorization)),i;if(r!==null&&n.computerUse?.available)try{i=await n.computerUse.request(e,{operation:`stop`,payload:{grantId:r.grantId}})}catch(e){let t=e instanceof Error?e.message:String(e);i={artifactId:o(),status:`failed`,failure:{code:`recording_failed`,message:t.slice(0,512)}},n.onNotice(`computer-use Desktop stop was already unavailable (${t})`)}await l(await y(e,t.hubStop,`POST`,{artifact:i})),m.delete(e.sessionId),_===e.sessionId&&(_=void 0)},w=async e=>{if(!(v||h.has(e.sessionId))&&!((g.get(e.sessionId)??0)>Date.now())){h.add(e.sessionId);try{let r=await x(e);if(r.phase===`active`){let t=typeof r.expiresAt==`number`&&r.expiresAt<=Date.now(),i=!1;if(!t&&n.computerUse?.available)try{i=s(await n.computerUse.request(e,{operation:`status`}))?.ownedBySession===!0}catch{i=!0}if(t||!i){await C(e),await x(e);return}}if(r.phase===`awaiting_confirmation`&&(_===void 0||_===e.sessionId)){if(!n.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);let r=await l(await y(e,t.hubActivation));if(r!==null){_=e.sessionId;try{let i=await n.computerUse.request(e,{operation:`activate`,payload:r});await l(await y(e,t.hubStop,`POST`,{host:i}));let a=s(i)?.grantId;typeof a==`string`&&m.set(e.sessionId,a)}catch(n){_=void 0,await l(await y(e,t.hubStop,`POST`,{error:n instanceof Error?n.message:String(n)}))}await x(e)}}r.phase===`stopping`&&(await C(e),await x(e));let i=await l(await y(e,t.hubNext));i!==null&&await S(e,i)}catch(t){t instanceof r?(g.set(e.sessionId,a(Date.now())),f.delete(e.sessionId)):n.onNotice(`computer-use poll failed for ${e.sessionId} (${t instanceof Error?t.message:String(t)})`)}finally{h.delete(e.sessionId)}}};u=(e,t)=>{let i=c(t);i!==void 0&&(g.delete(e.sessionId),(async()=>{try{if(i.action===`targets`){if(!n.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);let t=await n.computerUse.request(e,{operation:`targets`});p.set(e.sessionId,Array.isArray(t)?t.filter(e=>s(e)!==void 0):[])}else i.action===`stop`&&await C(e);await x(e)}catch(t){t instanceof r?(g.set(e.sessionId,a(Date.now())),f.delete(e.sessionId)):n.onNotice(`computer-use command failed for ${e.sessionId} (${t instanceof Error?t.message:String(t)})`)}})())};let T=setInterval(()=>{for(let e of d.values())w(e)},i.pollMs??250);return{payloadFor:e=>f.get(e.sessionId),sessionAdded(e){d.set(e.sessionId,e),w(e)},sessionRemoved(e){let t=d.get(e),r=m.get(e);t!==void 0&&r!==void 0&&n.computerUse?.available&&n.computerUse.request(t,{operation:`stop`,payload:{grantId:r}}).catch(e=>n.onNotice(`computer-use session cleanup failed (${e instanceof Error?e.message:String(e)})`)),d.delete(e),f.delete(e),p.delete(e),m.delete(e),h.delete(e),g.delete(e),_===e&&(_=void 0)},close(){if(v=!0,clearInterval(T),n.computerUse?.available)for(let[e,t]of m){let r=d.get(e);r!==void 0&&n.computerUse.request(r,{operation:`stop`,payload:{grantId:t}}).catch(()=>void 0)}d.clear(),f.clear(),p.clear(),m.clear(),g.clear()}}},receive(e,t){u?.(e,t)}}}const d=[u()];export{n as computerUseChannelType,u as createComputerUseChannel,d as webHubChannels};
1
+ import{API_BASE_PATH as e,COMPUTER_USE_ROUTES as t,computerUseChannelType as n}from"../types/computerUseApi.mjs";import{MissingComputerUseApiError as r,computerUseSessionApiError as i,missingComputerUseApiRetryAt as a}from"./webComputerUseAvailability.mjs";function o(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:void 0}function s(e){let t=o(e);return t?.action===`status`||t?.action===`targets`||t?.action===`stop`||t?.action===`artifacts`?{action:t.action}:void 0}async function c(e){let t=await e.json();if(!e.ok)throw i(e.status,t);return t}function l(i={}){let l;return{frameType:n,lifecycle:`hub`,start(n){let u=new Map,d=new Map,f=new Map,p=new Map,m=new Set,h=new Map,g,_=!1,v=async(t,r,i=`GET`,a)=>n.requestSessionApi(t,{basePath:e,path:r,method:i,...a===void 0?{}:{body:JSON.stringify(a)}}),y=(e,t)=>{let r={state:t,targets:f.get(e.sessionId)??[],...g!==void 0&&g!==e.sessionId?{busy:!0}:{}};d.set(e.sessionId,r),n.publish(e.sessionId,r)},b=async e=>{let n=await c(await v(e,t.hubState));if(n.phase===`active`||n.phase===`activating`||n.phase===`stopping`){if(g=e.sessionId,n.phase===`active`&&!p.has(e.sessionId)){let n=await c(await v(e,t.hubAuthorization));n!==null&&p.set(e.sessionId,n.grantId)}}else g===e.sessionId&&(g=void 0),p.delete(e.sessionId);return h.delete(e.sessionId),y(e,n),n},x=async(e,r)=>{if(!n.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);try{let i=await n.computerUse.request(e,{operation:r.operation,payload:r.operation===`act`?{grantId:r.grantId,sequence:r.sequence,action:r.payload}:{grantId:r.grantId}});await c(await v(e,t.hubComplete,`POST`,{id:r.id,result:i}))}catch(n){await c(await v(e,t.hubComplete,`POST`,{id:r.id,error:n instanceof Error?n.message:String(n)}))}},S=async e=>{let r=await c(await v(e,t.hubAuthorization)),i;if(r!==null&&n.computerUse?.available)try{i=await n.computerUse.request(e,{operation:`stop`,payload:{grantId:r.grantId}})}catch(e){n.onNotice(`computer-use Desktop stop was already unavailable (${e instanceof Error?e.message:String(e)})`)}await c(await v(e,t.hubStop,`POST`,{artifact:i})),p.delete(e.sessionId),g===e.sessionId&&(g=void 0)},C=async e=>{if(!(_||m.has(e.sessionId))&&!((h.get(e.sessionId)??0)>Date.now())){m.add(e.sessionId);try{let r=await b(e);if(r.phase===`active`){let i=typeof r.expiresAt==`number`&&r.expiresAt<=Date.now(),a=!1;if(!i&&n.computerUse?.available)try{a=o(await n.computerUse.request(e,{operation:`status`}))?.ownedBySession===!0}catch{a=!0}if(i||!a){await c(await v(e,t.hubStop,`POST`)),p.delete(e.sessionId),g===e.sessionId&&(g=void 0),await b(e);return}}if(r.phase===`awaiting_confirmation`&&(g===void 0||g===e.sessionId)){if(!n.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);let r=await c(await v(e,t.hubActivation));if(r!==null){g=e.sessionId;try{let i=await n.computerUse.request(e,{operation:`activate`,payload:r});await c(await v(e,t.hubStop,`POST`,{host:i}));let a=o(i)?.grantId;typeof a==`string`&&p.set(e.sessionId,a)}catch(n){g=void 0,await c(await v(e,t.hubStop,`POST`,{error:n instanceof Error?n.message:String(n)}))}await b(e)}}r.phase===`stopping`&&(await S(e),await b(e));let i=await c(await v(e,t.hubNext));i!==null&&await x(e,i)}catch(t){t instanceof r?(h.set(e.sessionId,a(Date.now())),d.delete(e.sessionId)):n.onNotice(`computer-use poll failed for ${e.sessionId} (${t instanceof Error?t.message:String(t)})`)}finally{m.delete(e.sessionId)}}};l=(e,t)=>{let i=s(t);i!==void 0&&(h.delete(e.sessionId),(async()=>{try{if(i.action===`targets`){if(!n.computerUse?.available)throw Error(`DoomPi Desktop computer use is unavailable.`);let t=await n.computerUse.request(e,{operation:`targets`});f.set(e.sessionId,Array.isArray(t)?t.filter(e=>o(e)!==void 0):[])}else i.action===`stop`&&await S(e);await b(e)}catch(t){t instanceof r?(h.set(e.sessionId,a(Date.now())),d.delete(e.sessionId)):n.onNotice(`computer-use command failed for ${e.sessionId} (${t instanceof Error?t.message:String(t)})`)}})())};let w=setInterval(()=>{for(let e of u.values())C(e)},i.pollMs??250);return{payloadFor:e=>d.get(e.sessionId),sessionAdded(e){u.set(e.sessionId,e),C(e)},sessionRemoved(e){let t=u.get(e),r=p.get(e);t!==void 0&&r!==void 0&&n.computerUse?.available&&n.computerUse.request(t,{operation:`stop`,payload:{grantId:r}}).catch(e=>n.onNotice(`computer-use session cleanup failed (${e instanceof Error?e.message:String(e)})`)),u.delete(e),d.delete(e),f.delete(e),p.delete(e),m.delete(e),h.delete(e),g===e&&(g=void 0)},close(){if(_=!0,clearInterval(w),n.computerUse?.available)for(let[e,t]of p){let r=u.get(e);r!==void 0&&n.computerUse.request(r,{operation:`stop`,payload:{grantId:t}}).catch(()=>void 0)}u.clear(),d.clear(),f.clear(),p.clear(),h.clear()}}},receive(e,t){l?.(e,t)}}}const u=[l()];export{n as computerUseChannelType,l as createComputerUseChannel,u as webHubChannels};
2
2
  //# sourceMappingURL=webComputerUseChannel.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"webComputerUseChannel.mjs","names":[],"sources":["../../src/adapters/webComputerUseChannel.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { HubChannelSource, HubSessionScope, WebHubChannel } from '@agimon-ai/doompi-web-contracts';\nimport {\n API_BASE_PATH,\n computerUseChannelType,\n COMPUTER_USE_ROUTES,\n type ComputerUseActivationRequest,\n type ComputerUseBrokerRequest,\n type ComputerUseBrowserCommand,\n type ComputerUseChannelPayload,\n type ComputerUseSessionView,\n} from '../types/computerUseApi.ts';\nimport {\n computerUseSessionApiError,\n MissingComputerUseApiError,\n missingComputerUseApiRetryAt,\n} from './webComputerUseAvailability.ts';\nexport { computerUseChannelType };\n\nconst POLL_MS = 250;\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction command(value: unknown): ComputerUseBrowserCommand | undefined {\n const input = record(value);\n return input?.action === 'status' ||\n input?.action === 'targets' ||\n input?.action === 'stop' ||\n input?.action === 'artifacts'\n ? { action: input.action }\n : undefined;\n}\n\nasync function responseJson(response: Response): Promise<unknown> {\n const value = await response.json();\n if (!response.ok) throw computerUseSessionApiError(response.status, value);\n return value;\n}\n\nexport function createComputerUseChannel(options: { pollMs?: number } = {}): WebHubChannel {\n let receiveCommand: ((scope: HubSessionScope, payload: unknown) => void) | undefined;\n return {\n frameType: computerUseChannelType,\n lifecycle: 'hub',\n start(host) {\n const scopes = new Map<string, HubSessionScope>();\n const latest = new Map<string, ComputerUseChannelPayload>();\n const targets = new Map<string, readonly Record<string, unknown>[]>();\n const grants = new Map<string, string>();\n const processing = new Set<string>();\n const unavailableUntil = new Map<string, number>();\n let activeSessionId: string | undefined;\n let closed = false;\n\n const sessionRequest = async (scope: HubSessionScope, path: string, method = 'GET', value?: unknown) =>\n host.requestSessionApi(scope, {\n basePath: API_BASE_PATH,\n path,\n method,\n ...(value === undefined ? {} : { body: JSON.stringify(value) }),\n });\n\n const publish = (scope: HubSessionScope, state: ComputerUseSessionView): void => {\n const payload: ComputerUseChannelPayload = {\n state,\n targets: targets.get(scope.sessionId) ?? [],\n ...(activeSessionId !== undefined && activeSessionId !== scope.sessionId ? { busy: true } : {}),\n };\n latest.set(scope.sessionId, payload);\n host.publish(scope.sessionId, payload);\n };\n\n const refresh = async (scope: HubSessionScope): Promise<ComputerUseSessionView> => {\n const state = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubState),\n )) as ComputerUseSessionView;\n if (state.phase === 'active' || state.phase === 'activating' || state.phase === 'stopping') {\n activeSessionId = scope.sessionId;\n if (state.phase === 'active' && !grants.has(scope.sessionId)) {\n const authorization = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubAuthorization),\n )) as { grantId: string } | null;\n if (authorization !== null) grants.set(scope.sessionId, authorization.grantId);\n }\n } else {\n if (activeSessionId === scope.sessionId) activeSessionId = undefined;\n grants.delete(scope.sessionId);\n }\n unavailableUntil.delete(scope.sessionId);\n publish(scope, state);\n return state;\n };\n\n const completePending = async (scope: HubSessionScope, pending: ComputerUseBrokerRequest): Promise<void> => {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n try {\n const result = await host.computerUse.request(scope, {\n operation: pending.operation,\n payload:\n pending.operation === 'act'\n ? { grantId: pending.grantId, sequence: pending.sequence, action: pending.payload }\n : { grantId: pending.grantId },\n });\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubComplete, 'POST', { id: pending.id, result }),\n );\n } catch (error) {\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubComplete, 'POST', {\n id: pending.id,\n error: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n };\n\n const stopSession = async (scope: HubSessionScope): Promise<void> => {\n const authorization = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubAuthorization),\n )) as { grantId: string } | null;\n let artifact: unknown;\n if (authorization !== null && host.computerUse?.available) {\n try {\n artifact = await host.computerUse.request(scope, {\n operation: 'stop',\n payload: { grantId: authorization.grantId },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n artifact = {\n artifactId: randomUUID(),\n status: 'failed',\n failure: { code: 'recording_failed', message: message.slice(0, 512) },\n };\n host.onNotice(`computer-use Desktop stop was already unavailable (${message})`);\n }\n }\n await responseJson(await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', { artifact }));\n grants.delete(scope.sessionId);\n if (activeSessionId === scope.sessionId) activeSessionId = undefined;\n };\n const pollScope = async (scope: HubSessionScope): Promise<void> => {\n if (closed || processing.has(scope.sessionId)) return;\n if ((unavailableUntil.get(scope.sessionId) ?? 0) > Date.now()) return;\n processing.add(scope.sessionId);\n try {\n const state = await refresh(scope);\n if (state.phase === 'active') {\n const expired = typeof state.expiresAt === 'number' && state.expiresAt <= Date.now();\n let owned = false;\n if (!expired && host.computerUse?.available) {\n try {\n const hostStatus = record(await host.computerUse.request(scope, { operation: 'status' }));\n owned = hostStatus?.ownedBySession === true;\n } catch {\n owned = true;\n }\n }\n if (expired || !owned) {\n await stopSession(scope);\n await refresh(scope);\n return;\n }\n }\n if (\n state.phase === 'awaiting_confirmation' &&\n (activeSessionId === undefined || activeSessionId === scope.sessionId)\n ) {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n const activation = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubActivation),\n )) as ComputerUseActivationRequest | null;\n if (activation !== null) {\n activeSessionId = scope.sessionId;\n try {\n const hostResult = await host.computerUse.request(scope, {\n operation: 'activate',\n payload: activation,\n });\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', { host: hostResult }),\n );\n const grantId = record(hostResult)?.grantId;\n if (typeof grantId === 'string') grants.set(scope.sessionId, grantId);\n } catch (error) {\n activeSessionId = undefined;\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', {\n error: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n await refresh(scope);\n }\n }\n if (state.phase === 'stopping') {\n await stopSession(scope);\n await refresh(scope);\n }\n const pending = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubNext),\n )) as ComputerUseBrokerRequest | null;\n if (pending !== null) await completePending(scope, pending);\n } catch (error) {\n if (error instanceof MissingComputerUseApiError) {\n unavailableUntil.set(scope.sessionId, missingComputerUseApiRetryAt(Date.now()));\n latest.delete(scope.sessionId);\n } else {\n host.onNotice(\n `computer-use poll failed for ${scope.sessionId} (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n } finally {\n processing.delete(scope.sessionId);\n }\n };\n\n receiveCommand = (scope, payload) => {\n const parsed = command(payload);\n if (parsed === undefined) return;\n unavailableUntil.delete(scope.sessionId);\n void (async () => {\n try {\n if (parsed.action === 'targets') {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n const result = await host.computerUse.request(scope, { operation: 'targets' });\n targets.set(\n scope.sessionId,\n Array.isArray(result)\n ? result.filter((item): item is Record<string, unknown> => record(item) !== undefined)\n : [],\n );\n } else if (parsed.action === 'stop') {\n await stopSession(scope);\n }\n await refresh(scope);\n } catch (error) {\n if (error instanceof MissingComputerUseApiError) {\n unavailableUntil.set(scope.sessionId, missingComputerUseApiRetryAt(Date.now()));\n latest.delete(scope.sessionId);\n } else {\n host.onNotice(\n `computer-use command failed for ${scope.sessionId} (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n }\n })();\n };\n\n const timer: ReturnType<typeof setInterval> = setInterval(() => {\n for (const scope of scopes.values()) void pollScope(scope);\n }, options.pollMs ?? POLL_MS);\n\n const source: HubChannelSource = {\n payloadFor: (scope) => latest.get(scope.sessionId),\n sessionAdded(scope) {\n scopes.set(scope.sessionId, scope);\n void pollScope(scope);\n },\n sessionRemoved(sessionId) {\n const scope = scopes.get(sessionId);\n const grantId = grants.get(sessionId);\n if (scope !== undefined && grantId !== undefined && host.computerUse?.available) {\n void host.computerUse\n .request(scope, { operation: 'stop', payload: { grantId } })\n .catch((error: unknown) =>\n host.onNotice(\n `computer-use session cleanup failed (${error instanceof Error ? error.message : String(error)})`,\n ),\n );\n }\n scopes.delete(sessionId);\n latest.delete(sessionId);\n targets.delete(sessionId);\n grants.delete(sessionId);\n processing.delete(sessionId);\n unavailableUntil.delete(sessionId);\n if (activeSessionId === sessionId) activeSessionId = undefined;\n },\n close() {\n closed = true;\n clearInterval(timer);\n if (host.computerUse?.available) {\n for (const [sessionId, grantId] of grants) {\n const scope = scopes.get(sessionId);\n if (scope !== undefined)\n void host.computerUse\n .request(scope, { operation: 'stop', payload: { grantId } })\n .catch(() => undefined);\n }\n }\n scopes.clear();\n latest.clear();\n targets.clear();\n grants.clear();\n unavailableUntil.clear();\n },\n };\n return source;\n },\n receive(scope, payload) {\n receiveCommand?.(scope, payload);\n },\n };\n}\n\nexport const webHubChannels: readonly WebHubChannel[] = [createComputerUseChannel()];\n"],"mappings":"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"}
1
+ {"version":3,"file":"webComputerUseChannel.mjs","names":[],"sources":["../../src/adapters/webComputerUseChannel.ts"],"sourcesContent":["import type { HubChannelSource, HubSessionScope, WebHubChannel } from '@agimon-ai/doompi-web-contracts';\nimport {\n API_BASE_PATH,\n computerUseChannelType,\n COMPUTER_USE_ROUTES,\n type ComputerUseActivationRequest,\n type ComputerUseBrokerRequest,\n type ComputerUseBrowserCommand,\n type ComputerUseChannelPayload,\n type ComputerUseSessionView,\n} from '../types/computerUseApi.ts';\nimport {\n computerUseSessionApiError,\n MissingComputerUseApiError,\n missingComputerUseApiRetryAt,\n} from './webComputerUseAvailability.ts';\nexport { computerUseChannelType };\n\nconst POLL_MS = 250;\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction command(value: unknown): ComputerUseBrowserCommand | undefined {\n const input = record(value);\n return input?.action === 'status' ||\n input?.action === 'targets' ||\n input?.action === 'stop' ||\n input?.action === 'artifacts'\n ? { action: input.action }\n : undefined;\n}\n\nasync function responseJson(response: Response): Promise<unknown> {\n const value = await response.json();\n if (!response.ok) throw computerUseSessionApiError(response.status, value);\n return value;\n}\n\nexport function createComputerUseChannel(options: { pollMs?: number } = {}): WebHubChannel {\n let receiveCommand: ((scope: HubSessionScope, payload: unknown) => void) | undefined;\n return {\n frameType: computerUseChannelType,\n lifecycle: 'hub',\n start(host) {\n const scopes = new Map<string, HubSessionScope>();\n const latest = new Map<string, ComputerUseChannelPayload>();\n const targets = new Map<string, readonly Record<string, unknown>[]>();\n const grants = new Map<string, string>();\n const processing = new Set<string>();\n const unavailableUntil = new Map<string, number>();\n let activeSessionId: string | undefined;\n let closed = false;\n\n const sessionRequest = async (scope: HubSessionScope, path: string, method = 'GET', value?: unknown) =>\n host.requestSessionApi(scope, {\n basePath: API_BASE_PATH,\n path,\n method,\n ...(value === undefined ? {} : { body: JSON.stringify(value) }),\n });\n\n const publish = (scope: HubSessionScope, state: ComputerUseSessionView): void => {\n const payload: ComputerUseChannelPayload = {\n state,\n targets: targets.get(scope.sessionId) ?? [],\n ...(activeSessionId !== undefined && activeSessionId !== scope.sessionId ? { busy: true } : {}),\n };\n latest.set(scope.sessionId, payload);\n host.publish(scope.sessionId, payload);\n };\n\n const refresh = async (scope: HubSessionScope): Promise<ComputerUseSessionView> => {\n const state = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubState),\n )) as ComputerUseSessionView;\n if (state.phase === 'active' || state.phase === 'activating' || state.phase === 'stopping') {\n activeSessionId = scope.sessionId;\n if (state.phase === 'active' && !grants.has(scope.sessionId)) {\n const authorization = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubAuthorization),\n )) as { grantId: string } | null;\n if (authorization !== null) grants.set(scope.sessionId, authorization.grantId);\n }\n } else {\n if (activeSessionId === scope.sessionId) activeSessionId = undefined;\n grants.delete(scope.sessionId);\n }\n unavailableUntil.delete(scope.sessionId);\n publish(scope, state);\n return state;\n };\n\n const completePending = async (scope: HubSessionScope, pending: ComputerUseBrokerRequest): Promise<void> => {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n try {\n const result = await host.computerUse.request(scope, {\n operation: pending.operation,\n payload:\n pending.operation === 'act'\n ? { grantId: pending.grantId, sequence: pending.sequence, action: pending.payload }\n : { grantId: pending.grantId },\n });\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubComplete, 'POST', { id: pending.id, result }),\n );\n } catch (error) {\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubComplete, 'POST', {\n id: pending.id,\n error: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n };\n\n const stopSession = async (scope: HubSessionScope): Promise<void> => {\n const authorization = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubAuthorization),\n )) as { grantId: string } | null;\n let artifact: unknown;\n if (authorization !== null && host.computerUse?.available) {\n try {\n artifact = await host.computerUse.request(scope, {\n operation: 'stop',\n payload: { grantId: authorization.grantId },\n });\n } catch (error) {\n host.onNotice(\n `computer-use Desktop stop was already unavailable (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n }\n await responseJson(await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', { artifact }));\n grants.delete(scope.sessionId);\n if (activeSessionId === scope.sessionId) activeSessionId = undefined;\n };\n const pollScope = async (scope: HubSessionScope): Promise<void> => {\n if (closed || processing.has(scope.sessionId)) return;\n if ((unavailableUntil.get(scope.sessionId) ?? 0) > Date.now()) return;\n processing.add(scope.sessionId);\n try {\n const state = await refresh(scope);\n if (state.phase === 'active') {\n const expired = typeof state.expiresAt === 'number' && state.expiresAt <= Date.now();\n let owned = false;\n if (!expired && host.computerUse?.available) {\n try {\n const hostStatus = record(await host.computerUse.request(scope, { operation: 'status' }));\n owned = hostStatus?.ownedBySession === true;\n } catch {\n owned = true;\n }\n }\n if (expired || !owned) {\n await responseJson(await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST'));\n grants.delete(scope.sessionId);\n if (activeSessionId === scope.sessionId) activeSessionId = undefined;\n await refresh(scope);\n return;\n }\n }\n if (\n state.phase === 'awaiting_confirmation' &&\n (activeSessionId === undefined || activeSessionId === scope.sessionId)\n ) {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n const activation = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubActivation),\n )) as ComputerUseActivationRequest | null;\n if (activation !== null) {\n activeSessionId = scope.sessionId;\n try {\n const hostResult = await host.computerUse.request(scope, {\n operation: 'activate',\n payload: activation,\n });\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', { host: hostResult }),\n );\n const grantId = record(hostResult)?.grantId;\n if (typeof grantId === 'string') grants.set(scope.sessionId, grantId);\n } catch (error) {\n activeSessionId = undefined;\n await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubStop, 'POST', {\n error: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n await refresh(scope);\n }\n }\n if (state.phase === 'stopping') {\n await stopSession(scope);\n await refresh(scope);\n }\n const pending = (await responseJson(\n await sessionRequest(scope, COMPUTER_USE_ROUTES.hubNext),\n )) as ComputerUseBrokerRequest | null;\n if (pending !== null) await completePending(scope, pending);\n } catch (error) {\n if (error instanceof MissingComputerUseApiError) {\n unavailableUntil.set(scope.sessionId, missingComputerUseApiRetryAt(Date.now()));\n latest.delete(scope.sessionId);\n } else {\n host.onNotice(\n `computer-use poll failed for ${scope.sessionId} (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n } finally {\n processing.delete(scope.sessionId);\n }\n };\n\n receiveCommand = (scope, payload) => {\n const parsed = command(payload);\n if (parsed === undefined) return;\n unavailableUntil.delete(scope.sessionId);\n void (async () => {\n try {\n if (parsed.action === 'targets') {\n if (!host.computerUse?.available) throw new Error('DoomPi Desktop computer use is unavailable.');\n const result = await host.computerUse.request(scope, { operation: 'targets' });\n targets.set(\n scope.sessionId,\n Array.isArray(result)\n ? result.filter((item): item is Record<string, unknown> => record(item) !== undefined)\n : [],\n );\n } else if (parsed.action === 'stop') {\n await stopSession(scope);\n }\n await refresh(scope);\n } catch (error) {\n if (error instanceof MissingComputerUseApiError) {\n unavailableUntil.set(scope.sessionId, missingComputerUseApiRetryAt(Date.now()));\n latest.delete(scope.sessionId);\n } else {\n host.onNotice(\n `computer-use command failed for ${scope.sessionId} (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n }\n })();\n };\n\n const timer: ReturnType<typeof setInterval> = setInterval(() => {\n for (const scope of scopes.values()) void pollScope(scope);\n }, options.pollMs ?? POLL_MS);\n\n const source: HubChannelSource = {\n payloadFor: (scope) => latest.get(scope.sessionId),\n sessionAdded(scope) {\n scopes.set(scope.sessionId, scope);\n void pollScope(scope);\n },\n sessionRemoved(sessionId) {\n const scope = scopes.get(sessionId);\n const grantId = grants.get(sessionId);\n if (scope !== undefined && grantId !== undefined && host.computerUse?.available) {\n void host.computerUse\n .request(scope, { operation: 'stop', payload: { grantId } })\n .catch((error: unknown) =>\n host.onNotice(\n `computer-use session cleanup failed (${error instanceof Error ? error.message : String(error)})`,\n ),\n );\n }\n scopes.delete(sessionId);\n latest.delete(sessionId);\n targets.delete(sessionId);\n grants.delete(sessionId);\n processing.delete(sessionId);\n unavailableUntil.delete(sessionId);\n if (activeSessionId === sessionId) activeSessionId = undefined;\n },\n close() {\n closed = true;\n clearInterval(timer);\n if (host.computerUse?.available) {\n for (const [sessionId, grantId] of grants) {\n const scope = scopes.get(sessionId);\n if (scope !== undefined)\n void host.computerUse\n .request(scope, { operation: 'stop', payload: { grantId } })\n .catch(() => undefined);\n }\n }\n scopes.clear();\n latest.clear();\n targets.clear();\n grants.clear();\n unavailableUntil.clear();\n },\n };\n return source;\n },\n receive(scope, payload) {\n receiveCommand?.(scope, payload);\n },\n };\n}\n\nexport const webHubChannels: readonly WebHubChannel[] = [createComputerUseChannel()];\n"],"mappings":"iQAoBA,SAAS,EAAO,EAAqD,CACnE,OAAO,OAAO,GAAU,UAAY,GAAkB,CAAC,MAAM,QAAQ,CAAK,EACrE,EACD,IAAA,EACN,CAEA,SAAS,EAAQ,EAAuD,CACtE,IAAM,EAAQ,EAAO,CAAK,EAC1B,OAAO,GAAO,SAAW,UACvB,GAAO,SAAW,WAClB,GAAO,SAAW,QAClB,GAAO,SAAW,YAChB,CAAE,OAAQ,EAAM,MAAO,EACvB,IAAA,EACN,CAEA,eAAe,EAAa,EAAsC,CAChE,IAAM,EAAQ,MAAM,EAAS,KAAK,EAClC,GAAI,CAAC,EAAS,GAAI,MAAM,EAA2B,EAAS,OAAQ,CAAK,EACzE,OAAO,CACT,CAEA,SAAgB,EAAyB,EAA+B,CAAC,EAAkB,CACzF,IAAI,EACJ,MAAO,CACL,UAAW,EACX,UAAW,MACX,MAAM,EAAM,CACV,IAAM,EAAS,IAAI,IACb,EAAS,IAAI,IACb,EAAU,IAAI,IACd,EAAS,IAAI,IACb,EAAa,IAAI,IACjB,EAAmB,IAAI,IACzB,EACA,EAAS,GAEP,EAAiB,MAAO,EAAwB,EAAc,EAAS,MAAO,IAClF,EAAK,kBAAkB,EAAO,CAC5B,SAAU,EACV,OACA,SACA,GAAI,IAAU,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,KAAK,UAAU,CAAK,CAAE,CAC/D,CAAC,EAEG,GAAW,EAAwB,IAAwC,CAC/E,IAAM,EAAqC,CACzC,QACA,QAAS,EAAQ,IAAI,EAAM,SAAS,GAAK,CAAC,EAC1C,GAAI,IAAoB,IAAA,IAAa,IAAoB,EAAM,UAAY,CAAE,KAAM,EAAK,EAAI,CAAC,CAC/F,EACA,EAAO,IAAI,EAAM,UAAW,CAAO,EACnC,EAAK,QAAQ,EAAM,UAAW,CAAO,CACvC,EAEM,EAAU,KAAO,IAA4D,CACjF,IAAM,EAAS,MAAM,EACnB,MAAM,EAAe,EAAO,EAAoB,QAAQ,CAC1D,EACA,GAAI,EAAM,QAAU,UAAY,EAAM,QAAU,cAAgB,EAAM,QAAU,WAE9E,IADA,EAAkB,EAAM,UACpB,EAAM,QAAU,UAAY,CAAC,EAAO,IAAI,EAAM,SAAS,EAAG,CAC5D,IAAM,EAAiB,MAAM,EAC3B,MAAM,EAAe,EAAO,EAAoB,gBAAgB,CAClE,EACI,IAAkB,MAAM,EAAO,IAAI,EAAM,UAAW,EAAc,OAAO,CAC/E,OAEI,IAAoB,EAAM,YAAW,EAAkB,IAAA,IAC3D,EAAO,OAAO,EAAM,SAAS,EAI/B,OAFA,EAAiB,OAAO,EAAM,SAAS,EACvC,EAAQ,EAAO,CAAK,EACb,CACT,EAEM,EAAkB,MAAO,EAAwB,IAAqD,CAC1G,GAAI,CAAC,EAAK,aAAa,UAAW,MAAU,MAAM,6CAA6C,EAC/F,GAAI,CACF,IAAM,EAAS,MAAM,EAAK,YAAY,QAAQ,EAAO,CACnD,UAAW,EAAQ,UACnB,QACE,EAAQ,YAAc,MAClB,CAAE,QAAS,EAAQ,QAAS,SAAU,EAAQ,SAAU,OAAQ,EAAQ,OAAQ,EAChF,CAAE,QAAS,EAAQ,OAAQ,CACnC,CAAC,EACD,MAAM,EACJ,MAAM,EAAe,EAAO,EAAoB,YAAa,OAAQ,CAAE,GAAI,EAAQ,GAAI,QAAO,CAAC,CACjG,CACF,OAAS,EAAO,CACd,MAAM,EACJ,MAAM,EAAe,EAAO,EAAoB,YAAa,OAAQ,CACnE,GAAI,EAAQ,GACZ,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,CAC9D,CAAC,CACH,CACF,CACF,EAEM,EAAc,KAAO,IAA0C,CACnE,IAAM,EAAiB,MAAM,EAC3B,MAAM,EAAe,EAAO,EAAoB,gBAAgB,CAClE,EACI,EACJ,GAAI,IAAkB,MAAQ,EAAK,aAAa,UAC9C,GAAI,CACF,EAAW,MAAM,EAAK,YAAY,QAAQ,EAAO,CAC/C,UAAW,OACX,QAAS,CAAE,QAAS,EAAc,OAAQ,CAC5C,CAAC,CACH,OAAS,EAAO,CACd,EAAK,SACH,sDAAsD,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAE,EAC/G,CACF,CAEF,MAAM,EAAa,MAAM,EAAe,EAAO,EAAoB,QAAS,OAAQ,CAAE,UAAS,CAAC,CAAC,EACjG,EAAO,OAAO,EAAM,SAAS,EACzB,IAAoB,EAAM,YAAW,EAAkB,IAAA,GAC7D,EACM,EAAY,KAAO,IAA0C,CAC7D,QAAU,EAAW,IAAI,EAAM,SAAS,IAC5C,GAAK,EAAiB,IAAI,EAAM,SAAS,GAAK,GAAK,KAAK,IAAI,GAC5D,GAAW,IAAI,EAAM,SAAS,EAC9B,GAAI,CACF,IAAM,EAAQ,MAAM,EAAQ,CAAK,EACjC,GAAI,EAAM,QAAU,SAAU,CAC5B,IAAM,EAAU,OAAO,EAAM,WAAc,UAAY,EAAM,WAAa,KAAK,IAAI,EAC/E,EAAQ,GACZ,GAAI,CAAC,GAAW,EAAK,aAAa,UAChC,GAAI,CAEF,EADmB,EAAO,MAAM,EAAK,YAAY,QAAQ,EAAO,CAAE,UAAW,QAAS,CAAC,CACtE,CAAC,EAAE,iBAAmB,EACzC,MAAQ,CACN,EAAQ,EACV,CAEF,GAAI,GAAW,CAAC,EAAO,CACrB,MAAM,EAAa,MAAM,EAAe,EAAO,EAAoB,QAAS,MAAM,CAAC,EACnF,EAAO,OAAO,EAAM,SAAS,EACzB,IAAoB,EAAM,YAAW,EAAkB,IAAA,IAC3D,MAAM,EAAQ,CAAK,EACnB,MACF,CACF,CACA,GACE,EAAM,QAAU,0BACf,IAAoB,IAAA,IAAa,IAAoB,EAAM,WAC5D,CACA,GAAI,CAAC,EAAK,aAAa,UAAW,MAAU,MAAM,6CAA6C,EAC/F,IAAM,EAAc,MAAM,EACxB,MAAM,EAAe,EAAO,EAAoB,aAAa,CAC/D,EACA,GAAI,IAAe,KAAM,CACvB,EAAkB,EAAM,UACxB,GAAI,CACF,IAAM,EAAa,MAAM,EAAK,YAAY,QAAQ,EAAO,CACvD,UAAW,WACX,QAAS,CACX,CAAC,EACD,MAAM,EACJ,MAAM,EAAe,EAAO,EAAoB,QAAS,OAAQ,CAAE,KAAM,CAAW,CAAC,CACvF,EACA,IAAM,EAAU,EAAO,CAAU,CAAC,EAAE,QAChC,OAAO,GAAY,UAAU,EAAO,IAAI,EAAM,UAAW,CAAO,CACtE,OAAS,EAAO,CACd,EAAkB,IAAA,GAClB,MAAM,EACJ,MAAM,EAAe,EAAO,EAAoB,QAAS,OAAQ,CAC/D,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,CAC9D,CAAC,CACH,CACF,CACA,MAAM,EAAQ,CAAK,CACrB,CACF,CACI,EAAM,QAAU,aAClB,MAAM,EAAY,CAAK,EACvB,MAAM,EAAQ,CAAK,GAErB,IAAM,EAAW,MAAM,EACrB,MAAM,EAAe,EAAO,EAAoB,OAAO,CACzD,EACI,IAAY,MAAM,MAAM,EAAgB,EAAO,CAAO,CAC5D,OAAS,EAAO,CACV,aAAiB,GACnB,EAAiB,IAAI,EAAM,UAAW,EAA6B,KAAK,IAAI,CAAC,CAAC,EAC9E,EAAO,OAAO,EAAM,SAAS,GAE7B,EAAK,SACH,gCAAgC,EAAM,UAAU,IAAI,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAE,EAC7G,CAEJ,QAAU,CACR,EAAW,OAAO,EAAM,SAAS,CACnC,CAxE8B,CAyEhC,EAEA,GAAkB,EAAO,IAAY,CACnC,IAAM,EAAS,EAAQ,CAAO,EAC1B,IAAW,IAAA,KACf,EAAiB,OAAO,EAAM,SAAS,GACjC,SAAY,CAChB,GAAI,CACF,GAAI,EAAO,SAAW,UAAW,CAC/B,GAAI,CAAC,EAAK,aAAa,UAAW,MAAU,MAAM,6CAA6C,EAC/F,IAAM,EAAS,MAAM,EAAK,YAAY,QAAQ,EAAO,CAAE,UAAW,SAAU,CAAC,EAC7E,EAAQ,IACN,EAAM,UACN,MAAM,QAAQ,CAAM,EAChB,EAAO,OAAQ,GAA0C,EAAO,CAAI,IAAM,IAAA,EAAS,EACnF,CAAC,CACP,CACF,MAAW,EAAO,SAAW,QAC3B,MAAM,EAAY,CAAK,EAEzB,MAAM,EAAQ,CAAK,CACrB,OAAS,EAAO,CACV,aAAiB,GACnB,EAAiB,IAAI,EAAM,UAAW,EAA6B,KAAK,IAAI,CAAC,CAAC,EAC9E,EAAO,OAAO,EAAM,SAAS,GAE7B,EAAK,SACH,mCAAmC,EAAM,UAAU,IAAI,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAE,EAChH,CAEJ,CACF,EAAA,CAAG,EACL,EAEA,IAAM,EAAwC,gBAAkB,CAC9D,IAAK,IAAM,KAAS,EAAO,OAAO,EAAG,EAAe,CAAK,CAC3D,EAAG,EAAQ,QAAU,GAAO,EA+C5B,MAAO,CA5CL,WAAa,GAAU,EAAO,IAAI,EAAM,SAAS,EACjD,aAAa,EAAO,CAClB,EAAO,IAAI,EAAM,UAAW,CAAK,EACjC,EAAe,CAAK,CACtB,EACA,eAAe,EAAW,CACxB,IAAM,EAAQ,EAAO,IAAI,CAAS,EAC5B,EAAU,EAAO,IAAI,CAAS,EAChC,IAAU,IAAA,IAAa,IAAY,IAAA,IAAa,EAAK,aAAa,WACpE,EAAU,YACP,QAAQ,EAAO,CAAE,UAAW,OAAQ,QAAS,CAAE,SAAQ,CAAE,CAAC,CAAC,CAC3D,MAAO,GACN,EAAK,SACH,wCAAwC,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAE,EACjG,CACF,EAEJ,EAAO,OAAO,CAAS,EACvB,EAAO,OAAO,CAAS,EACvB,EAAQ,OAAO,CAAS,EACxB,EAAO,OAAO,CAAS,EACvB,EAAW,OAAO,CAAS,EAC3B,EAAiB,OAAO,CAAS,EAC7B,IAAoB,IAAW,EAAkB,IAAA,GACvD,EACA,OAAQ,CAGN,GAFA,EAAS,GACT,cAAc,CAAK,EACf,EAAK,aAAa,UACpB,IAAK,GAAM,CAAC,EAAW,KAAY,EAAQ,CACzC,IAAM,EAAQ,EAAO,IAAI,CAAS,EAC9B,IAAU,IAAA,IACZ,EAAU,YACP,QAAQ,EAAO,CAAE,UAAW,OAAQ,QAAS,CAAE,SAAQ,CAAE,CAAC,CAAC,CAC3D,UAAY,IAAA,EAAS,CAC5B,CAEF,EAAO,MAAM,EACb,EAAO,MAAM,EACb,EAAQ,MAAM,EACd,EAAO,MAAM,EACb,EAAiB,MAAM,CACzB,CAEU,CACd,EACA,QAAQ,EAAO,EAAS,CACtB,IAAiB,EAAO,CAAO,CACjC,CACF,CACF,CAEA,MAAa,EAA2C,CAAC,EAAyB,CAAC"}
@@ -1,2 +1,2 @@
1
- const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../adapters/pi/sessionApiClient.cjs"),n=require("../adapters/pi/computerScriptRunner.cjs"),r=require("../services/extensionService.cjs");let i=require("node:path");i=e.__toESM(i,1);let a=require("@agimon-ai/doompi-config");function o(e={}){let o=e.client??t.createComputerUseSessionClient(),s=(process.env.DOOMPI_COMPUTER_USE_SCRIPT_PATHS??``).split(i.default.delimiter).filter(e=>e.length>0);return{service:e.service??new r.DefaultComputerUseExtensionService(o),enabled:e.enabled??(()=>(0,a.loadDoomConfig)(process.env.PI_PROJECT_ROOT??process.cwd()).computerUse?.enabled===!0),...o===void 0?{}:{client:o},...e.scriptRunner===void 0?o===void 0?{}:{scriptRunner:new n.ComputerScriptRunner({client:o,allowedScriptPaths:s})}:{scriptRunner:e.scriptRunner}}}exports.COMPUTER_USE_SCRIPT_PATHS_ENV=`DOOMPI_COMPUTER_USE_SCRIPT_PATHS`,exports.createComputerUseContainer=o;
1
+ const e=require("../adapters/pi/sessionApiClient.cjs"),t=require("../services/extensionService.cjs");function n(n={}){let r=n.client??e.createComputerUseSessionClient();return{service:n.service??new t.DefaultComputerUseExtensionService(r),...r===void 0?{}:{client:r}}}exports.createComputerUseContainer=n;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["createComputerUseSessionClient","path","DefaultComputerUseExtensionService","loadDoomConfig","ComputerScriptRunner"],"sources":["../../src/container/index.ts"],"sourcesContent":["import path from 'node:path';\nimport { loadDoomConfig } from '@agimon-ai/doompi-config';\nimport { createComputerUseSessionClient } from '../adapters/pi/sessionApiClient.ts';\nimport { ComputerScriptRunner } from '../adapters/pi/computerScriptRunner.ts';\nimport { DefaultComputerUseExtensionService } from '../services/extensionService.ts';\nimport type { ComputerUseExtensionDependencies } from '../types/extension.ts';\n\nexport const COMPUTER_USE_SCRIPT_PATHS_ENV = 'DOOMPI_COMPUTER_USE_SCRIPT_PATHS';\nexport function createComputerUseContainer(\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 (() => loadDoomConfig(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":"+RAQA,SAAgB,EACd,EAAuD,CAAC,EACtB,CAClC,IAAM,EAAS,EAAU,QAAUA,EAAAA,+BAA+B,EAC5D,GAAsB,QAAQ,IAAA,kCAAsC,GAAA,CACvE,MAAMC,EAAAA,QAAK,SAAS,CAAC,CACrB,OAAQ,GAAU,EAAM,OAAS,CAAC,EACrC,MAAO,CACL,QAAS,EAAU,SAAW,IAAIC,EAAAA,mCAAmC,CAAM,EAC3E,QACE,EAAU,eAAA,EACHC,EAAAA,eAAAA,CAAe,QAAQ,IAAI,iBAAmB,QAAQ,IAAI,CAAC,CAAC,CAAC,aAAa,UAAY,IAC/F,GAAI,IAAW,IAAA,GAAY,CAAC,EAAI,CAAE,QAAO,EACzC,GAAI,EAAU,eAAiB,IAAA,GAE3B,IAAW,IAAA,GACT,CAAC,EACD,CAAE,aAAc,IAAIC,EAAAA,qBAAqB,CAAE,SAAQ,oBAAmB,CAAC,CAAE,EAH3E,CAAE,aAAc,EAAU,YAAa,CAI7C,CACF"}
1
+ {"version":3,"file":"index.cjs","names":["createComputerUseSessionClient","DefaultComputerUseExtensionService"],"sources":["../../src/container/index.ts"],"sourcesContent":["import { createComputerUseSessionClient } from '../adapters/pi/sessionApiClient.ts';\nimport { DefaultComputerUseExtensionService } from '../services/extensionService.ts';\nimport type { ComputerUseExtensionDependencies } from '../types/extension.ts';\n\nexport function createComputerUseContainer(\n overrides: Partial<ComputerUseExtensionDependencies> = {},\n): ComputerUseExtensionDependencies {\n const client = overrides.client ?? createComputerUseSessionClient();\n return {\n service: overrides.service ?? new DefaultComputerUseExtensionService(client),\n ...(client === undefined ? {} : { client }),\n };\n}\n"],"mappings":"qGAIA,SAAgB,EACd,EAAuD,CAAC,EACtB,CAClC,IAAM,EAAS,EAAU,QAAUA,EAAAA,+BAA+B,EAClE,MAAO,CACL,QAAS,EAAU,SAAW,IAAIC,EAAAA,mCAAmC,CAAM,EAC3E,GAAI,IAAW,IAAA,GAAY,CAAC,EAAI,CAAE,QAAO,CAC3C,CACF"}
@@ -1,6 +1,6 @@
1
1
  import { ComputerUseExtensionDependencies } from "../types/extension.cjs";
2
2
  //#region src/container/index.d.ts
3
- export declare const COMPUTER_USE_SCRIPT_PATHS_ENV = "DOOMPI_COMPUTER_USE_SCRIPT_PATHS";
4
- export declare function createComputerUseContainer(overrides?: Partial<ComputerUseExtensionDependencies>): ComputerUseExtensionDependencies;
3
+ declare function createComputerUseContainer(overrides?: Partial<ComputerUseExtensionDependencies>): ComputerUseExtensionDependencies;
5
4
  //#endregion
5
+ export { createComputerUseContainer };
6
6
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/container/index.ts"],"mappings":";;qBAOa;wBACG,2BACd,YAAW,QAAQ,oCAClB"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/container/index.ts"],"mappings":";;iBAIgB,2BACd,YAAW,QAAQ,oCAClB"}
@@ -1,6 +1,6 @@
1
1
  import { ComputerUseExtensionDependencies } from "../types/extension.mjs";
2
2
  //#region src/container/index.d.ts
3
- export declare const COMPUTER_USE_SCRIPT_PATHS_ENV = "DOOMPI_COMPUTER_USE_SCRIPT_PATHS";
4
- export declare function createComputerUseContainer(overrides?: Partial<ComputerUseExtensionDependencies>): ComputerUseExtensionDependencies;
3
+ declare function createComputerUseContainer(overrides?: Partial<ComputerUseExtensionDependencies>): ComputerUseExtensionDependencies;
5
4
  //#endregion
5
+ export { createComputerUseContainer };
6
6
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/container/index.ts"],"mappings":";;qBAOa;wBACG,2BACd,YAAW,QAAQ,oCAClB"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/container/index.ts"],"mappings":";;iBAIgB,2BACd,YAAW,QAAQ,oCAClB"}
@@ -1,2 +1,2 @@
1
- import{createComputerUseSessionClient as e}from"../adapters/pi/sessionApiClient.mjs";import{ComputerScriptRunner as t}from"../adapters/pi/computerScriptRunner.mjs";import{DefaultComputerUseExtensionService as n}from"../services/extensionService.mjs";import r from"node:path";import{loadDoomConfig as i}from"@agimon-ai/doompi-config";const a=`DOOMPI_COMPUTER_USE_SCRIPT_PATHS`;function o(a={}){let o=a.client??e(),s=(process.env.DOOMPI_COMPUTER_USE_SCRIPT_PATHS??``).split(r.delimiter).filter(e=>e.length>0);return{service:a.service??new n(o),enabled:a.enabled??(()=>i(process.env.PI_PROJECT_ROOT??process.cwd()).computerUse?.enabled===!0),...o===void 0?{}:{client:o},...a.scriptRunner===void 0?o===void 0?{}:{scriptRunner:new t({client:o,allowedScriptPaths:s})}:{scriptRunner:a.scriptRunner}}}export{a as COMPUTER_USE_SCRIPT_PATHS_ENV,o as createComputerUseContainer};
1
+ import{createComputerUseSessionClient as e}from"../adapters/pi/sessionApiClient.mjs";import{DefaultComputerUseExtensionService as t}from"../services/extensionService.mjs";function n(n={}){let r=n.client??e();return{service:n.service??new t(r),...r===void 0?{}:{client:r}}}export{n as createComputerUseContainer};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/container/index.ts"],"sourcesContent":["import path from 'node:path';\nimport { loadDoomConfig } from '@agimon-ai/doompi-config';\nimport { createComputerUseSessionClient } from '../adapters/pi/sessionApiClient.ts';\nimport { ComputerScriptRunner } from '../adapters/pi/computerScriptRunner.ts';\nimport { DefaultComputerUseExtensionService } from '../services/extensionService.ts';\nimport type { ComputerUseExtensionDependencies } from '../types/extension.ts';\n\nexport const COMPUTER_USE_SCRIPT_PATHS_ENV = 'DOOMPI_COMPUTER_USE_SCRIPT_PATHS';\nexport function createComputerUseContainer(\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 (() => loadDoomConfig(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":"6UAOA,MAAa,EAAgC,mCAC7C,SAAgB,EACd,EAAuD,CAAC,EACtB,CAClC,IAAM,EAAS,EAAU,QAAU,EAA+B,EAC5D,GAAsB,QAAQ,IAAA,kCAAsC,GAAA,CACvE,MAAM,EAAK,SAAS,CAAC,CACrB,OAAQ,GAAU,EAAM,OAAS,CAAC,EACrC,MAAO,CACL,QAAS,EAAU,SAAW,IAAI,EAAmC,CAAM,EAC3E,QACE,EAAU,cACH,EAAe,QAAQ,IAAI,iBAAmB,QAAQ,IAAI,CAAC,CAAC,CAAC,aAAa,UAAY,IAC/F,GAAI,IAAW,IAAA,GAAY,CAAC,EAAI,CAAE,QAAO,EACzC,GAAI,EAAU,eAAiB,IAAA,GAE3B,IAAW,IAAA,GACT,CAAC,EACD,CAAE,aAAc,IAAI,EAAqB,CAAE,SAAQ,oBAAmB,CAAC,CAAE,EAH3E,CAAE,aAAc,EAAU,YAAa,CAI7C,CACF"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/container/index.ts"],"sourcesContent":["import { createComputerUseSessionClient } from '../adapters/pi/sessionApiClient.ts';\nimport { DefaultComputerUseExtensionService } from '../services/extensionService.ts';\nimport type { ComputerUseExtensionDependencies } from '../types/extension.ts';\n\nexport function createComputerUseContainer(\n overrides: Partial<ComputerUseExtensionDependencies> = {},\n): ComputerUseExtensionDependencies {\n const client = overrides.client ?? createComputerUseSessionClient();\n return {\n service: overrides.service ?? new DefaultComputerUseExtensionService(client),\n ...(client === undefined ? {} : { client }),\n };\n}\n"],"mappings":"2KAIA,SAAgB,EACd,EAAuD,CAAC,EACtB,CAClC,IAAM,EAAS,EAAU,QAAU,EAA+B,EAClE,MAAO,CACL,QAAS,EAAU,SAAW,IAAI,EAAmC,CAAM,EAC3E,GAAI,IAAW,IAAA,GAAY,CAAC,EAAI,CAAE,QAAO,CAC3C,CACF"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./types/computerUseApi.cjs"),t=require("./adapters/pi/sessionApiClient.cjs"),n=require("./adapters/pi/computerScriptRunner.cjs"),r=require("./services/extensionService.cjs"),i=require("./container/index.cjs"),a=require("./adapters/pi/extension.cjs"),o=require("./services/sessionController.cjs"),s=require("./services/traceRedaction.cjs");exports.COMPUTER_USE_GUIDANCE=a.COMPUTER_USE_GUIDANCE,exports.COMPUTER_USE_MODE_ID=e.COMPUTER_USE_MODE_ID,exports.COMPUTER_USE_SCRIPT_PATHS_ENV=i.COMPUTER_USE_SCRIPT_PATHS_ENV,exports.COMPUTER_USE_TOOL_NAMES=a.COMPUTER_USE_TOOL_NAMES,exports.ComputerScriptRunner=n.ComputerScriptRunner,exports.DefaultComputerUseExtensionService=r.DefaultComputerUseExtensionService,exports.UnixComputerUseSessionClient=t.UnixComputerUseSessionClient,exports.activateComputerUseExtension=a.activateComputerUseExtension,exports.createComputerUseContainer=i.createComputerUseContainer,exports.createComputerUseSessionClient=t.createComputerUseSessionClient,exports.initialComputerUseState=o.initialComputerUseState,exports.redactComputerUseTrace=s.redactComputerUseTrace,exports.reduceComputerUseState=o.reduceComputerUseState;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./types/computerUseApi.cjs"),t=require("./adapters/pi/sessionApiClient.cjs"),n=require("./services/extensionService.cjs"),r=require("./container/index.cjs"),i=require("./adapters/pi/extension.cjs"),a=require("./services/sessionController.cjs"),o=require("./services/traceRedaction.cjs");exports.COMPUTER_USE_GUIDANCE=i.COMPUTER_USE_GUIDANCE,exports.COMPUTER_USE_MODE_ID=e.COMPUTER_USE_MODE_ID,exports.COMPUTER_USE_TOOL_NAMES=i.COMPUTER_USE_TOOL_NAMES,exports.DefaultComputerUseExtensionService=n.DefaultComputerUseExtensionService,exports.UnixComputerUseSessionClient=t.UnixComputerUseSessionClient,exports.activateComputerUseExtension=i.activateComputerUseExtension,exports.createComputerUseContainer=r.createComputerUseContainer,exports.createComputerUseSessionClient=t.createComputerUseSessionClient,exports.initialComputerUseState=a.initialComputerUseState,exports.redactComputerUseTrace=o.redactComputerUseTrace,exports.reduceComputerUseState=a.reduceComputerUseState;