@xopcai/xopc 0.0.205 → 0.0.206

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 (151) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-DJBadfSX.js → activity-store-URW-e_me.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Br6C32BX.js → agent-avatar-dicebear-BLK6kRCJ.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-D5HVmdNx.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-B5O7fKXa.js → api-C_MS4arC.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-Le1vJ1OO.js → app-management-settings-panel-CnUN6BJk.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-CZlAU60t.js → appearance-settings-C8Nx8hZE.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-DKCA_LFY.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-CRzXRXPE.js → archive-plugin-C7FqeJZD.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-CYAAQ6Qi.js → attachment-load-DCYQgsYE.js} +1 -1
  12. package/dist/gateway/static/root/assets/automations-page-BEOE4ZKM.js +6 -0
  13. package/dist/gateway/static/root/assets/{binary-plugins-CVR5cUmS.js → binary-plugins-Bf1WROsh.js} +1 -1
  14. package/dist/gateway/static/root/assets/{block-editor-CFe74rWi.js → block-editor-BPK08Pjv.js} +46 -46
  15. package/dist/gateway/static/root/assets/browser-settings-page-CLRmMdU9.js +8 -0
  16. package/dist/gateway/static/root/assets/{browser-workflow-inputs-Bd68yluo.js → browser-workflow-inputs-cqVoDHyp.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-workflows-page-B0uiDLga.js → browser-workflows-page-Des1UTsS.js} +2 -2
  18. package/dist/gateway/static/root/assets/capabilities-settings-panel-BNcVi4ar.js +7 -0
  19. package/dist/gateway/static/root/assets/{capability-presets-api-BerPMp6f.js → capability-presets-api-D4MjqV2a.js} +1 -1
  20. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-DJjVOCJY.js → capability-presets-settings-panel-uFwW2ah5.js} +2 -2
  21. package/dist/gateway/static/root/assets/{channel-recipient-api-D2d21_XA.js → channel-recipient-api-CcimZduy.js} +1 -1
  22. package/dist/gateway/static/root/assets/channels-settings-DSLP8OjS.js +1 -0
  23. package/dist/gateway/static/root/assets/channels-status-swr-D0OR6Ylw.js +1 -0
  24. package/dist/gateway/static/root/assets/chat-terminal-dock-B1njb2Cr.css +1 -0
  25. package/dist/gateway/static/root/assets/chat-terminal-dock-wpi7abPg.js +38 -0
  26. package/dist/gateway/static/root/assets/{connectors-api-Bq_vUzxP.js → connectors-api-CUvFu8jh.js} +1 -1
  27. package/dist/gateway/static/root/assets/connectors-page-BJoHjWnu.js +2 -0
  28. package/dist/gateway/static/root/assets/{cron-expression-DZBxmKGR.js → cron-expression-hFSZZpvM.js} +1 -1
  29. package/dist/gateway/static/root/assets/{date-picker-BNHd7HT7.js → date-picker-CKZ0gc-Y.js} +1 -1
  30. package/dist/gateway/static/root/assets/{dependency-picker-D1kJBknt.js → dependency-picker-zv1oHtg4.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-Di75oHkC.js → desktop-pet-DY9ykMtD.js} +1 -1
  32. package/dist/gateway/static/root/assets/{desktop-pet-settings-D6tD1uym.js → desktop-pet-settings-XiSmmt26.js} +1 -1
  33. package/dist/gateway/static/root/assets/directory-picker-path-field-CZkgk15r.js +1 -0
  34. package/dist/gateway/static/root/assets/{extension-debug-page-D91_S7NQ.js → extension-debug-page-CTppsTEi.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-page-DHzmmr_N.js → extension-page-CHRTUvAa.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-settings-page-BpJNtePi.js → extension-settings-page-z2UBx25A.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-api-BAzLYTKZ.js → gateway-config-api-DzFPJTnm.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-config-swr-VVcfd3sG.js → gateway-config-swr-CGpoH1gU.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-settings-C5-aKkTp.js → gateway-settings-DBa2I6VM.js} +1 -1
  40. package/dist/gateway/static/root/assets/{gateway-startup-retry-qAX_T2t2.js → gateway-startup-retry-Te-TREBt.js} +1 -1
  41. package/dist/gateway/static/root/assets/heartbeat-settings-DyQGGdBu.js +1 -0
  42. package/dist/gateway/static/root/assets/home-page-EkT4eGeP.js +3 -0
  43. package/dist/gateway/static/root/assets/index-BpLqHdfz.css +2 -0
  44. package/dist/gateway/static/root/assets/index-CrwXzRpA.js +85 -0
  45. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-fpNjXnJK.js → keyboard-shortcuts-settings-fb0zS8pk.js} +1 -1
  46. package/dist/gateway/static/root/assets/local-app-workbench-page-CCC3Cvb8.js +2 -0
  47. package/dist/gateway/static/root/assets/{local-apps-page-DBpQIfNd.js → local-apps-page-DFdheruU.js} +1 -1
  48. package/dist/gateway/static/root/assets/{locale-store-CbPVxonP.js → locale-store-CieddUjx.js} +1 -1
  49. package/dist/gateway/static/root/assets/{logs-page-BmXcJCKz.js → logs-page-B6jfkNDF.js} +2 -2
  50. package/dist/gateway/static/root/assets/{management-settings-CiK7Xkvi.js → management-settings-D3PsQ612.js} +1 -1
  51. package/dist/gateway/static/root/assets/{markdown-split-DVgpcOze.js → markdown-split-x5K52Thz.js} +1 -1
  52. package/dist/gateway/static/root/assets/{markdown-view-Dl-0_9JR.js → markdown-view-Cjjey5Y6.js} +1 -1
  53. package/dist/gateway/static/root/assets/{media-plugins-DMj1lW-n.js → media-plugins-DNtEkRAh.js} +1 -1
  54. package/dist/gateway/static/root/assets/messages-CySMn8WL.js +3 -0
  55. package/dist/gateway/static/root/assets/{notes-page-DvX1sTlf.js → notes-page-nWEqlwDw.js} +1 -1
  56. package/dist/gateway/static/root/assets/notes-workbench-QstkgWsW.js +4 -0
  57. package/dist/gateway/static/root/assets/{preview-open-alternatives-DvsLigha.js → preview-open-alternatives-CXcIKVi9.js} +1 -1
  58. package/dist/gateway/static/root/assets/{product-open-page-DbCraAI3.js → product-open-page-CZLJudPk.js} +1 -1
  59. package/dist/gateway/static/root/assets/project-detail-page-Cf1v94LO.js +1 -0
  60. package/dist/gateway/static/root/assets/projects-page-BRMZkNht.js +1 -0
  61. package/dist/gateway/static/root/assets/remote-access-hub-D55FTXZw.js +1 -0
  62. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DzuUglQo.js → runtime-tools-settings-panel-RYjduQV6.js} +1 -1
  63. package/dist/gateway/static/root/assets/{schema-form-plDnazVj.js → schema-form--1ZXg4qC.js} +1 -1
  64. package/dist/gateway/static/root/assets/sessions-page-C5Yy6eIn.js +1 -0
  65. package/dist/gateway/static/root/assets/settings-advanced-gate-BqO_8bUh.js +1 -0
  66. package/dist/gateway/static/root/assets/{settings-form-section-BwAxX_7e.js → settings-form-section-71-8j3zt.js} +1 -1
  67. package/dist/gateway/static/root/assets/{settings-loading-skeleton-B3OiTnF9.js → settings-loading-skeleton-C5Jn1l0q.js} +1 -1
  68. package/dist/gateway/static/root/assets/{settings-page-DvIWXBvp.js → settings-page-TYYGe6kZ.js} +1 -1
  69. package/dist/gateway/static/root/assets/{setup-status-panel-DThKKjLV.js → setup-status-panel-jA5I-17g.js} +1 -1
  70. package/dist/gateway/static/root/assets/{share-preview-page-CFnoGHJb.js → share-preview-page-BMUQIGfk.js} +1 -1
  71. package/dist/gateway/static/root/assets/shares-settings-Dru1a2rZ.js +1 -0
  72. package/dist/gateway/static/root/assets/skill-reload-api-C8iqS6kF.js +1 -0
  73. package/dist/gateway/static/root/assets/{skills-page-B38fY22S.js → skills-page-BzZT1SKg.js} +1 -1
  74. package/dist/gateway/static/root/assets/{skills-page.utils-vLIlk1c3.js → skills-page.utils-DnaBw5Ji.js} +1 -1
  75. package/dist/gateway/static/root/assets/{system-settings-panel-DRV2wljT.js → system-settings-panel-DqiPQgVI.js} +1 -1
  76. package/dist/gateway/static/root/assets/task-detail-page-DQP5vDr-.js +1 -0
  77. package/dist/gateway/static/root/assets/{theme-store-Bc_eRUev.js → theme-store-BP3_RpaY.js} +1 -1
  78. package/dist/gateway/static/root/assets/{use-autosave-DTu23D9J.js → use-autosave-BJkQ-vpu.js} +1 -1
  79. package/dist/gateway/static/root/assets/{user-context-page-DCwqzN03.js → user-context-page-BP8-sOPi.js} +1 -1
  80. package/dist/gateway/static/root/assets/{voice-api-key-field-CVDMesWc.js → voice-api-key-field-C6c8e7Mx.js} +1 -1
  81. package/dist/gateway/static/root/assets/{work-discovery-overlay-cyt93k0V.js → work-discovery-overlay-CCNjWKql.js} +1 -1
  82. package/dist/gateway/static/root/assets/work-discovery-page-DL_Ie0s2.js +1 -0
  83. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DrdcfX_N.js → workflow-run-setup-panel-DLO-dMSN.js} +2 -2
  84. package/dist/gateway/static/root/assets/workflows-page-B4-k2FHB.js +5 -0
  85. package/dist/gateway/static/root/assets/{working-directory-picker-modal-CYWdZUJ5.js → working-directory-picker-modal-vWi33CZJ.js} +1 -1
  86. package/dist/gateway/static/root/index.html +10 -10
  87. package/dist/package.js +1 -1
  88. package/dist/src/agent/agent-manager.d.ts +11 -0
  89. package/dist/src/agent/agent-manager.js +36 -6
  90. package/dist/src/agent/service.d.ts +4 -1
  91. package/dist/src/agent/service.js +12 -0
  92. package/dist/src/agent/tools/xopc-use-tool.js +6 -2
  93. package/dist/src/automations/api/routes.js +8 -0
  94. package/dist/src/automations/domain/index.js +2 -2
  95. package/dist/src/automations/domain/types.d.ts +17 -12
  96. package/dist/src/automations/domain/validation.d.ts +30 -32
  97. package/dist/src/automations/domain/validation.js +8 -10
  98. package/dist/src/automations/draft/automation-draft-prompt.js +9 -5
  99. package/dist/src/automations/draft/automation-draft-validator.d.ts +3 -8
  100. package/dist/src/automations/draft/automation-draft-validator.js +3 -3
  101. package/dist/src/automations/index.js +2 -2
  102. package/dist/src/automations/service/action-executor.js +13 -4
  103. package/dist/src/automations/service/automation-service.d.ts +5 -1
  104. package/dist/src/automations/service/automation-service.js +19 -12
  105. package/dist/src/automations/storage/automation-repository.js +8 -4
  106. package/dist/src/automations/storage/automation-run-repository.d.ts +5 -0
  107. package/dist/src/automations/storage/automation-run-repository.js +24 -8
  108. package/dist/src/automations/storage/index.js +2 -2
  109. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  110. package/dist/src/gateway/automation-agent-session.d.ts +4 -0
  111. package/dist/src/gateway/automation-agent-session.js +40 -0
  112. package/dist/src/gateway/dreaming-automation-reconciler.js +3 -2
  113. package/dist/src/gateway/hono/routes/commands-skills.js +36 -2
  114. package/dist/src/gateway/hono/routes/lazy-bundles.js +1 -0
  115. package/dist/src/gateway/service/marketplace-service.d.ts +4 -1
  116. package/dist/src/gateway/service/marketplace-service.js +9 -0
  117. package/dist/src/gateway/service.js +19 -2
  118. package/dist/src/mobile/notification-service.js +7 -4
  119. package/dist/src/storage/sqlite/migrations/121_automation_inbox.sql +24 -0
  120. package/dist/src/storage/sqlite/migrations/122_automation_session_projects.sql +18 -0
  121. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  122. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  123. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  124. package/dist/src/storage/sqlite/schema.js +1 -1
  125. package/package.json +3 -2
  126. package/dist/gateway/static/root/assets/agents-DnFIy8Ye.js +0 -68
  127. package/dist/gateway/static/root/assets/apps-page-CONlVc-f.js +0 -1
  128. package/dist/gateway/static/root/assets/automations-page-DuG69tIj.js +0 -6
  129. package/dist/gateway/static/root/assets/browser-settings-page-Cvt-8fqE.js +0 -8
  130. package/dist/gateway/static/root/assets/capabilities-settings-panel-yk3QkGBP.js +0 -7
  131. package/dist/gateway/static/root/assets/channels-settings-CaNnYUQo.js +0 -1
  132. package/dist/gateway/static/root/assets/channels-status-swr-CZ5P9jbB.js +0 -1
  133. package/dist/gateway/static/root/assets/connectors-page-DTpCnOsQ.js +0 -2
  134. package/dist/gateway/static/root/assets/directory-picker-path-field-Ly0TUflq.js +0 -1
  135. package/dist/gateway/static/root/assets/heartbeat-settings-CMZr1_Op.js +0 -1
  136. package/dist/gateway/static/root/assets/home-page-CBG9Bk-1.js +0 -3
  137. package/dist/gateway/static/root/assets/index-BBw9QL0p.js +0 -85
  138. package/dist/gateway/static/root/assets/index-Dm-cvIpl.css +0 -2
  139. package/dist/gateway/static/root/assets/local-app-workbench-page-Bi_0Sknt.js +0 -2
  140. package/dist/gateway/static/root/assets/messages-9zCa8KkW.js +0 -3
  141. package/dist/gateway/static/root/assets/notes-workbench-CMyosgjY.js +0 -4
  142. package/dist/gateway/static/root/assets/project-detail-page-DkS-kbpj.js +0 -1
  143. package/dist/gateway/static/root/assets/projects-page-B3NxP6S4.js +0 -1
  144. package/dist/gateway/static/root/assets/remote-access-hub-DwhrMhjl.js +0 -1
  145. package/dist/gateway/static/root/assets/sessions-page-BOfXXmBL.js +0 -1
  146. package/dist/gateway/static/root/assets/settings-advanced-gate-sPrZfZVR.js +0 -1
  147. package/dist/gateway/static/root/assets/shares-settings-Dvl13Udt.js +0 -1
  148. package/dist/gateway/static/root/assets/skill-reload-api-D9elkZOz.js +0 -1
  149. package/dist/gateway/static/root/assets/task-detail-page-Xd8PlB24.js +0 -1
  150. package/dist/gateway/static/root/assets/work-discovery-page--DTi90d5.js +0 -1
  151. package/dist/gateway/static/root/assets/workflows-page-DXyButkm.js +0 -5
@@ -1 +1 @@
1
- import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{a as t,t as n}from"./vendor-react-BOUWij0V.js";import{t as r}from"./createLucideIcon-DPHK1VkS.js";import{t as i}from"./loader-circle-CifKLtgG.js";import{t as a}from"./cn-JdwAhgNB.js";import{t as o}from"./button-CSEbl4zT.js";import{s}from"./form-field-width-DJw_jULe.js";import{n as c}from"./interaction-BmQogeqz.js";import{r as l,s as u}from"./locale-store-CbPVxonP.js";import{a as d,i as f,o as p,r as m,s as h,t as g}from"./dist-BPoKqzeH.js";import{r as _}from"./settings-form-draft-Dy10ldo8.js";var v=r(`chevron-up`,[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]),y=r(`folder-input`,[[`path`,{d:`M2 9V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-1`,key:`fm4g5t`}],[`path`,{d:`M2 13h10`,key:`pgb2dq`}],[`path`,{d:`m9 16 3-3-3-3`,key:`6m91ic`}]]),b=e(t(),1),x=`xopc.recentWorkspaceDirs.v1`,S=10;function C(){try{let e=localStorage.getItem(x);if(!e)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>typeof e==`string`&&e.trim().length>0):[]}catch{return[]}}function w(e){let t=e.trim();if(t)try{let e=[t,...C().filter(e=>e!==t)].slice(0,S);localStorage.setItem(x,JSON.stringify(e))}catch{}}function T(e){let t=e.trim().replace(/[/\\]+$/,``);if(!t)return e;let n=t.split(/[/\\]/);return n[n.length-1]||t}async function E(e){let t=typeof window<`u`?window.electronAPI?.file?.openDirectory:void 0;if(!t)return null;let n=e?.trim();return n?t({defaultPath:n}):t()}function D(e={}){let{initialPath:t,onPicked:n,trackRecent:r=!0}=e,[i,a]=(0,b.useState)(!1),[o,s]=(0,b.useState)(!1),c=typeof window<`u`&&!!window.electronAPI?.file?.openDirectory,l=(0,b.useCallback)(async e=>{let t=e.trim();t&&(r&&w(t),await n?.(t))},[n,r]);return{hasNativePicker:c,modalOpen:i,setModalOpen:a,pick:(0,b.useCallback)(()=>{if(c){(async()=>{s(!0);try{let e=await E(t);e&&await l(e)}finally{s(!1)}})();return}a(!0)},[l,c,t]),confirmPick:l,picking:o}}async function O(e){let t=new URLSearchParams;e!=null&&e!==``&&t.set(`path`,e);let n=t.toString();return(await u(l(`/api/host/fs/list${n?`?${n}`:``}`))).payload}async function k(){return(await u(l(`/api/host/fs/meta`))).payload}var A=n();function j(){return a(`w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 font-mono text-sm text-fg`,`placeholder:text-fg-subtle`,s,`dark:border-edge`)}function M(e){return/^[A-Za-z]:\\?$/.test(e.replace(/\\$/,`\\`))}function N(e){return!e||e.currentPath===``?!1:e.parentPath===null?e.currentPath===`/`?!1:!!M(e.currentPath):!0}var P={metaHostname:null,listState:null,listLoading:!1,listError:null,manualPath:``};function F({open:e,onOpenChange:t,initialAbsolutePath:n,onConfirm:r,wd:s}){let l=(0,b.useId)(),[u,x]=(0,b.useReducer)(_,P),{metaHostname:S,listState:C,listLoading:w,listError:T,manualPath:E}=u,D=(0,b.useCallback)(async e=>{x({type:`patch`,patch:{listLoading:!0,listError:null}});try{x({type:`patch`,patch:{listState:await O(e)}})}catch(e){x({type:`patch`,patch:{listError:e instanceof Error?e.message:String(e),listState:null}})}finally{x({type:`patch`,patch:{listLoading:!1}})}},[]);(0,b.useEffect)(()=>{if(!e)return;let t=!1;return(async()=>{try{let e=await k();t||x({type:`patch`,patch:{metaHostname:e.hostname}})}catch{t||x({type:`patch`,patch:{metaHostname:null}})}})(),()=>{t=!0}},[e]),(0,b.useEffect)(()=>{if(!e)return;let t=n?.trim()??``;x({type:`patch`,patch:{manualPath:t}});let r=!1;return(async()=>{x({type:`patch`,patch:{listLoading:!0,listError:null}});try{if(t)try{let e=await O(t);r||x({type:`patch`,patch:{listState:e}})}catch{let e=await O();r||x({type:`patch`,patch:{listState:e}})}else{let e=await O();r||x({type:`patch`,patch:{listState:e}})}}catch(e){let t=e instanceof Error?e.message:String(e);r||x({type:`patch`,patch:{listError:t,listState:null}})}finally{r||x({type:`patch`,patch:{listLoading:!1}})}})(),()=>{r=!0}},[e,n]);let F=e=>{e.isDirectory&&D(e.absolutePath)},I=()=>{if(!C)return;let{parentPath:e,currentPath:t}=C;if(e!==null){D(e);return}t===`/`||t===``||M(t)&&D(void 0)},L=C?.currentPath===``?s.pickerDrives:C?.currentPath??``,R=!!C&&C.currentPath!==``&&!w&&!T,z=async()=>{if(!(!C||C.currentPath===``))try{await r(C.currentPath),t(!1)}catch{}},B=async()=>{let e=E.trim();if(e)try{await r(e),t(!1)}catch{}},V=w&&C;return(0,A.jsx)(g,{open:e,onOpenChange:t,children:(0,A.jsxs)(p,{children:[(0,A.jsx)(d,{className:`fixed inset-0 z-[100] bg-scrim backdrop-blur-[2px]`}),(0,A.jsxs)(m,{className:a(`fixed left-1/2 top-1/2 z-[101] flex max-h-[min(90vh,32rem)] w-[min(100%-2rem,28rem)] -translate-x-1/2 -translate-y-1/2 flex-col rounded-xl border border-edge bg-surface-panel p-4 shadow-popover`,`dark:border-edge`),onOpenAutoFocus:e=>e.preventDefault(),children:[(0,A.jsx)(h,{className:`text-base font-semibold text-fg`,children:s.pathModalTitle}),(0,A.jsx)(f,{className:`mt-1 text-sm leading-relaxed text-fg-muted`,children:s.pathModalDescription}),S?(0,A.jsx)(`p`,{className:`mt-2 text-xs text-fg-muted`,children:s.pickerHostHint.replace(`{{hostname}}`,S)}):null,(0,A.jsxs)(`div`,{className:`mt-3 flex min-h-0 flex-1 flex-col gap-2`,children:[(0,A.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,A.jsxs)(o,{type:`button`,variant:`secondary`,className:`shrink-0 gap-1 px-2 py-1.5 text-xs`,disabled:w||!N(C)||!!T,onClick:()=>I(),title:s.pickerUp,children:[(0,A.jsx)(v,{className:`size-4`,"aria-hidden":!0}),s.pickerUp]}),(0,A.jsx)(`div`,{className:`min-w-0 flex-1 truncate rounded-md border border-edge-subtle/80 bg-surface-hover/30 px-2 py-1.5 font-mono text-xs text-fg`,title:L,children:w&&!C?s.pickerLoading:L||`—`})]}),(0,A.jsxs)(`div`,{className:a(`relative min-h-[12rem] overflow-y-auto rounded-lg border border-edge-subtle/80 bg-surface-hover/20 p-1 dark:border-edge-subtle`,c.focusRingPanel),role:`listbox`,"aria-label":s.pathModalTitle,children:[V?(0,A.jsx)(`div`,{className:`absolute inset-0 z-[1] flex items-center justify-center rounded-lg bg-surface-panel/60`,"aria-hidden":!0,children:(0,A.jsx)(i,{className:`size-6 animate-spin text-fg-muted`})}):null,w&&!C?(0,A.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-12 text-sm text-fg-muted`,children:[(0,A.jsx)(i,{className:`size-4 animate-spin`,"aria-hidden":!0}),s.pickerLoading]}):null,T?(0,A.jsx)(`p`,{className:`px-2 py-8 text-center text-sm text-fg-muted`,children:s.pickerListError}):null,!w&&C&&!T&&C.entries.length===0?(0,A.jsx)(`p`,{className:`px-2 py-8 text-center text-sm text-fg-muted`,children:s.pickerEmptyFolder}):null,C?.entries.map(e=>(0,A.jsxs)(`button`,{type:`button`,role:`option`,"aria-selected":!1,disabled:!e.isDirectory,className:a(`flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm`,e.isDirectory?`cursor-pointer text-fg hover:bg-surface-hover`:`cursor-default text-fg-muted opacity-60`),onClick:()=>F(e),children:[(0,A.jsx)(y,{className:`size-4 shrink-0 text-fg-muted`,"aria-hidden":!0}),(0,A.jsx)(`span`,{className:`min-w-0 truncate`,children:e.name})]},e.absolutePath))]}),(0,A.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,A.jsx)(`label`,{htmlFor:l,className:`text-xs text-fg-muted`,children:s.pickerManualPath}),(0,A.jsx)(`input`,{id:l,type:`text`,value:E,onChange:e=>x({type:`patch`,patch:{manualPath:e.target.value}}),placeholder:s.pathInputPlaceholder,className:j(),autoComplete:`off`,spellCheck:!1,onKeyDown:e=>{e.key===`Enter`&&E.trim()&&(e.preventDefault(),B())}})]})]}),(0,A.jsxs)(`div`,{className:`mt-4 flex flex-wrap items-center justify-end gap-2 border-t border-edge-subtle/60 pt-3`,children:[(0,A.jsx)(o,{type:`button`,variant:`ghost`,onClick:()=>t(!1),children:s.pathModalCancel}),(0,A.jsx)(o,{type:`button`,variant:`secondary`,disabled:!E.trim(),onClick:()=>void B(),children:s.pickerApplyManual}),(0,A.jsx)(o,{type:`button`,disabled:!R,onClick:()=>void z(),children:s.pickerUseThisFolder})]})]})]})})}export{v as a,y as i,D as n,T as r,F as t};
1
+ import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{a as t,t as n}from"./vendor-react-BOUWij0V.js";import{t as r}from"./createLucideIcon-DPHK1VkS.js";import{t as i}from"./loader-circle-CifKLtgG.js";import{t as a}from"./cn-JdwAhgNB.js";import{t as o}from"./button-CSEbl4zT.js";import{s}from"./form-field-width-DJw_jULe.js";import{n as c}from"./interaction-BmQogeqz.js";import{r as l,s as u}from"./locale-store-CieddUjx.js";import{a as d,i as f,o as p,r as m,s as h,t as g}from"./dist-BPoKqzeH.js";import{r as _}from"./settings-form-draft-Dy10ldo8.js";var v=r(`chevron-up`,[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]),y=r(`folder-input`,[[`path`,{d:`M2 9V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-1`,key:`fm4g5t`}],[`path`,{d:`M2 13h10`,key:`pgb2dq`}],[`path`,{d:`m9 16 3-3-3-3`,key:`6m91ic`}]]),b=e(t(),1),x=`xopc.recentWorkspaceDirs.v1`,S=10;function C(){try{let e=localStorage.getItem(x);if(!e)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>typeof e==`string`&&e.trim().length>0):[]}catch{return[]}}function w(e){let t=e.trim();if(t)try{let e=[t,...C().filter(e=>e!==t)].slice(0,S);localStorage.setItem(x,JSON.stringify(e))}catch{}}function T(e){let t=e.trim().replace(/[/\\]+$/,``);if(!t)return e;let n=t.split(/[/\\]/);return n[n.length-1]||t}async function E(e){let t=typeof window<`u`?window.electronAPI?.file?.openDirectory:void 0;if(!t)return null;let n=e?.trim();return n?t({defaultPath:n}):t()}function D(e={}){let{initialPath:t,onPicked:n,trackRecent:r=!0}=e,[i,a]=(0,b.useState)(!1),[o,s]=(0,b.useState)(!1),c=typeof window<`u`&&!!window.electronAPI?.file?.openDirectory,l=(0,b.useCallback)(async e=>{let t=e.trim();t&&(r&&w(t),await n?.(t))},[n,r]);return{hasNativePicker:c,modalOpen:i,setModalOpen:a,pick:(0,b.useCallback)(()=>{if(c){(async()=>{s(!0);try{let e=await E(t);e&&await l(e)}finally{s(!1)}})();return}a(!0)},[l,c,t]),confirmPick:l,picking:o}}async function O(e){let t=new URLSearchParams;e!=null&&e!==``&&t.set(`path`,e);let n=t.toString();return(await u(l(`/api/host/fs/list${n?`?${n}`:``}`))).payload}async function k(){return(await u(l(`/api/host/fs/meta`))).payload}var A=n();function j(){return a(`w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 font-mono text-sm text-fg`,`placeholder:text-fg-subtle`,s,`dark:border-edge`)}function M(e){return/^[A-Za-z]:\\?$/.test(e.replace(/\\$/,`\\`))}function N(e){return!e||e.currentPath===``?!1:e.parentPath===null?e.currentPath===`/`?!1:!!M(e.currentPath):!0}var P={metaHostname:null,listState:null,listLoading:!1,listError:null,manualPath:``};function F({open:e,onOpenChange:t,initialAbsolutePath:n,onConfirm:r,wd:s}){let l=(0,b.useId)(),[u,x]=(0,b.useReducer)(_,P),{metaHostname:S,listState:C,listLoading:w,listError:T,manualPath:E}=u,D=(0,b.useCallback)(async e=>{x({type:`patch`,patch:{listLoading:!0,listError:null}});try{x({type:`patch`,patch:{listState:await O(e)}})}catch(e){x({type:`patch`,patch:{listError:e instanceof Error?e.message:String(e),listState:null}})}finally{x({type:`patch`,patch:{listLoading:!1}})}},[]);(0,b.useEffect)(()=>{if(!e)return;let t=!1;return(async()=>{try{let e=await k();t||x({type:`patch`,patch:{metaHostname:e.hostname}})}catch{t||x({type:`patch`,patch:{metaHostname:null}})}})(),()=>{t=!0}},[e]),(0,b.useEffect)(()=>{if(!e)return;let t=n?.trim()??``;x({type:`patch`,patch:{manualPath:t}});let r=!1;return(async()=>{x({type:`patch`,patch:{listLoading:!0,listError:null}});try{if(t)try{let e=await O(t);r||x({type:`patch`,patch:{listState:e}})}catch{let e=await O();r||x({type:`patch`,patch:{listState:e}})}else{let e=await O();r||x({type:`patch`,patch:{listState:e}})}}catch(e){let t=e instanceof Error?e.message:String(e);r||x({type:`patch`,patch:{listError:t,listState:null}})}finally{r||x({type:`patch`,patch:{listLoading:!1}})}})(),()=>{r=!0}},[e,n]);let F=e=>{e.isDirectory&&D(e.absolutePath)},I=()=>{if(!C)return;let{parentPath:e,currentPath:t}=C;if(e!==null){D(e);return}t===`/`||t===``||M(t)&&D(void 0)},L=C?.currentPath===``?s.pickerDrives:C?.currentPath??``,R=!!C&&C.currentPath!==``&&!w&&!T,z=async()=>{if(!(!C||C.currentPath===``))try{await r(C.currentPath),t(!1)}catch{}},B=async()=>{let e=E.trim();if(e)try{await r(e),t(!1)}catch{}},V=w&&C;return(0,A.jsx)(g,{open:e,onOpenChange:t,children:(0,A.jsxs)(p,{children:[(0,A.jsx)(d,{className:`fixed inset-0 z-[100] bg-scrim backdrop-blur-[2px]`}),(0,A.jsxs)(m,{className:a(`fixed left-1/2 top-1/2 z-[101] flex max-h-[min(90vh,32rem)] w-[min(100%-2rem,28rem)] -translate-x-1/2 -translate-y-1/2 flex-col rounded-xl border border-edge bg-surface-panel p-4 shadow-popover`,`dark:border-edge`),onOpenAutoFocus:e=>e.preventDefault(),children:[(0,A.jsx)(h,{className:`text-base font-semibold text-fg`,children:s.pathModalTitle}),(0,A.jsx)(f,{className:`mt-1 text-sm leading-relaxed text-fg-muted`,children:s.pathModalDescription}),S?(0,A.jsx)(`p`,{className:`mt-2 text-xs text-fg-muted`,children:s.pickerHostHint.replace(`{{hostname}}`,S)}):null,(0,A.jsxs)(`div`,{className:`mt-3 flex min-h-0 flex-1 flex-col gap-2`,children:[(0,A.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,A.jsxs)(o,{type:`button`,variant:`secondary`,className:`shrink-0 gap-1 px-2 py-1.5 text-xs`,disabled:w||!N(C)||!!T,onClick:()=>I(),title:s.pickerUp,children:[(0,A.jsx)(v,{className:`size-4`,"aria-hidden":!0}),s.pickerUp]}),(0,A.jsx)(`div`,{className:`min-w-0 flex-1 truncate rounded-md border border-edge-subtle/80 bg-surface-hover/30 px-2 py-1.5 font-mono text-xs text-fg`,title:L,children:w&&!C?s.pickerLoading:L||`—`})]}),(0,A.jsxs)(`div`,{className:a(`relative min-h-[12rem] overflow-y-auto rounded-lg border border-edge-subtle/80 bg-surface-hover/20 p-1 dark:border-edge-subtle`,c.focusRingPanel),role:`listbox`,"aria-label":s.pathModalTitle,children:[V?(0,A.jsx)(`div`,{className:`absolute inset-0 z-[1] flex items-center justify-center rounded-lg bg-surface-panel/60`,"aria-hidden":!0,children:(0,A.jsx)(i,{className:`size-6 animate-spin text-fg-muted`})}):null,w&&!C?(0,A.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-12 text-sm text-fg-muted`,children:[(0,A.jsx)(i,{className:`size-4 animate-spin`,"aria-hidden":!0}),s.pickerLoading]}):null,T?(0,A.jsx)(`p`,{className:`px-2 py-8 text-center text-sm text-fg-muted`,children:s.pickerListError}):null,!w&&C&&!T&&C.entries.length===0?(0,A.jsx)(`p`,{className:`px-2 py-8 text-center text-sm text-fg-muted`,children:s.pickerEmptyFolder}):null,C?.entries.map(e=>(0,A.jsxs)(`button`,{type:`button`,role:`option`,"aria-selected":!1,disabled:!e.isDirectory,className:a(`flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm`,e.isDirectory?`cursor-pointer text-fg hover:bg-surface-hover`:`cursor-default text-fg-muted opacity-60`),onClick:()=>F(e),children:[(0,A.jsx)(y,{className:`size-4 shrink-0 text-fg-muted`,"aria-hidden":!0}),(0,A.jsx)(`span`,{className:`min-w-0 truncate`,children:e.name})]},e.absolutePath))]}),(0,A.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,A.jsx)(`label`,{htmlFor:l,className:`text-xs text-fg-muted`,children:s.pickerManualPath}),(0,A.jsx)(`input`,{id:l,type:`text`,value:E,onChange:e=>x({type:`patch`,patch:{manualPath:e.target.value}}),placeholder:s.pathInputPlaceholder,className:j(),autoComplete:`off`,spellCheck:!1,onKeyDown:e=>{e.key===`Enter`&&E.trim()&&(e.preventDefault(),B())}})]})]}),(0,A.jsxs)(`div`,{className:`mt-4 flex flex-wrap items-center justify-end gap-2 border-t border-edge-subtle/60 pt-3`,children:[(0,A.jsx)(o,{type:`button`,variant:`ghost`,onClick:()=>t(!1),children:s.pathModalCancel}),(0,A.jsx)(o,{type:`button`,variant:`secondary`,disabled:!E.trim(),onClick:()=>void B(),children:s.pickerApplyManual}),(0,A.jsx)(o,{type:`button`,disabled:!R,onClick:()=>void z(),children:s.pickerUseThisFolder})]})]})]})})}export{v as a,y as i,D as n,T as r,F as t};
@@ -11,7 +11,7 @@
11
11
  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=20260713-1" />
12
12
  <link rel="manifest" href="/site.webmanifest?v=20260713-1" />
13
13
  <title>XOPC — Turn goals into loops. Keep what matters moving.</title>
14
- <script type="module" crossorigin src="/assets/index-BBw9QL0p.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-CrwXzRpA.js"></script>
15
15
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-aKtaBQYM.js">
16
16
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-zJ_50EbN.js">
17
17
  <link rel="modulepreload" crossorigin href="/assets/vendor-react-BOUWij0V.js">
@@ -24,13 +24,13 @@
24
24
  <link rel="modulepreload" crossorigin href="/assets/download-Dk-ZjtO6.js">
25
25
  <link rel="modulepreload" crossorigin href="/assets/plus-Q2yW6OE7.js">
26
26
  <link rel="modulepreload" crossorigin href="/assets/x-B_N4OPjy.js">
27
- <link rel="modulepreload" crossorigin href="/assets/messages-9zCa8KkW.js">
28
- <link rel="modulepreload" crossorigin href="/assets/locale-store-CbPVxonP.js">
27
+ <link rel="modulepreload" crossorigin href="/assets/messages-CySMn8WL.js">
28
+ <link rel="modulepreload" crossorigin href="/assets/locale-store-CieddUjx.js">
29
29
  <link rel="modulepreload" crossorigin href="/assets/cn-JdwAhgNB.js">
30
30
  <link rel="modulepreload" crossorigin href="/assets/schemas-zIBW3wiV.js">
31
31
  <link rel="modulepreload" crossorigin href="/assets/product-delivery-tRr-7IxY.js">
32
32
  <link rel="modulepreload" crossorigin href="/assets/copy-to-clipboard-HOJ79TWv.js">
33
- <link rel="modulepreload" crossorigin href="/assets/markdown-view-Dl-0_9JR.js">
33
+ <link rel="modulepreload" crossorigin href="/assets/markdown-view-Cjjey5Y6.js">
34
34
  <link rel="modulepreload" crossorigin href="/assets/dist-DY4Af0fY.js">
35
35
  <link rel="modulepreload" crossorigin href="/assets/vendor-swr-BIWyz7Rc.js">
36
36
  <link rel="modulepreload" crossorigin href="/assets/check-DUBLcKHA.js">
@@ -39,7 +39,7 @@
39
39
  <link rel="modulepreload" crossorigin href="/assets/form-field-width-DJw_jULe.js">
40
40
  <link rel="modulepreload" crossorigin href="/assets/interaction-BmQogeqz.js">
41
41
  <link rel="modulepreload" crossorigin href="/assets/settings-form-draft-Dy10ldo8.js">
42
- <link rel="modulepreload" crossorigin href="/assets/working-directory-picker-modal-CYWdZUJ5.js">
42
+ <link rel="modulepreload" crossorigin href="/assets/working-directory-picker-modal-vWi33CZJ.js">
43
43
  <link rel="modulepreload" crossorigin href="/assets/settings-shell-dialog-layer-BU3UuiJr.js">
44
44
  <link rel="modulepreload" crossorigin href="/assets/popover-select-BzdnTy3h.js">
45
45
  <link rel="modulepreload" crossorigin href="/assets/copy-Dv6d4Dvw.js">
@@ -48,12 +48,12 @@
48
48
  <link rel="modulepreload" crossorigin href="/assets/middleware-Pd0e8Igk.js">
49
49
  <link rel="modulepreload" crossorigin href="/assets/tool-activity-R8V9l6nk.js">
50
50
  <link rel="modulepreload" crossorigin href="/assets/config-reload-event-Bjh2zoKp.js">
51
- <link rel="modulepreload" crossorigin href="/assets/gateway-config-swr-VVcfd3sG.js">
52
- <link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-qAX_T2t2.js">
53
- <link rel="modulepreload" crossorigin href="/assets/activity-store-DJBadfSX.js">
54
- <link rel="modulepreload" crossorigin href="/assets/theme-store-Bc_eRUev.js">
51
+ <link rel="modulepreload" crossorigin href="/assets/gateway-config-swr-CGpoH1gU.js">
52
+ <link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-Te-TREBt.js">
53
+ <link rel="modulepreload" crossorigin href="/assets/activity-store-URW-e_me.js">
54
+ <link rel="modulepreload" crossorigin href="/assets/theme-store-BP3_RpaY.js">
55
55
  <link rel="stylesheet" crossorigin href="/assets/markdown-view-B12xeflb.css">
56
- <link rel="stylesheet" crossorigin href="/assets/index-Dm-cvIpl.css">
56
+ <link rel="stylesheet" crossorigin href="/assets/index-BpLqHdfz.css">
57
57
  </head>
58
58
  <body>
59
59
  <div id="root"></div>
package/dist/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.0.205";
2
+ var version = "0.0.206";
3
3
  //#endregion
4
4
  export { version };
@@ -56,6 +56,7 @@ export interface AgentSkillAvailabilityEntry extends SkillCatalogEntry {
56
56
  }
57
57
  export interface AgentSkillAvailabilityPayload {
58
58
  agentId: string;
59
+ workspacePath: string;
59
60
  version: string;
60
61
  loadedAt: number;
61
62
  diagnostics: SkillDiagnostic[];
@@ -65,6 +66,12 @@ export interface AgentSkillAvailabilityPayload {
65
66
  effectiveAllowlist?: string[];
66
67
  skills: AgentSkillAvailabilityEntry[];
67
68
  }
69
+ export interface WorkspaceTrustState {
70
+ workspacePath: string;
71
+ required: boolean;
72
+ decision: boolean | null;
73
+ trusted: boolean;
74
+ }
68
75
  export interface AgentManagerConfig {
69
76
  workspace: string;
70
77
  model?: string;
@@ -223,7 +230,11 @@ export declare class AgentManager implements AgentInstanceGateway {
223
230
  private skillCatalogEntryFromSkill;
224
231
  getSkillCatalog(): SkillCatalogEntry[];
225
232
  getSkillCatalogSnapshot(): SkillCatalogSnapshot;
233
+ private buildAgentSkillAvailability;
226
234
  getAgentSkillAvailability(agentId: string): AgentSkillAvailabilityPayload;
235
+ getSessionSkillAvailability(sessionKey: string): AgentSkillAvailabilityPayload;
236
+ getSessionWorkspaceTrust(sessionKey: string): WorkspaceTrustState;
237
+ setSessionWorkspaceTrust(sessionKey: string, trusted: boolean): WorkspaceTrustState;
227
238
  /**
228
239
  * After ~/.xopc/skills.json changes (enable/disable), refresh `<available_skills>` on active agents.
229
240
  */
@@ -503,14 +503,13 @@ var AgentManager = class {
503
503
  status: rt.skillManager.getStatus()
504
504
  };
505
505
  }
506
- getAgentSkillAvailability(agentId) {
506
+ buildAgentSkillAvailability(profile, workspaceDir) {
507
507
  const cfg = this.config.config;
508
- const entry = Array.isArray(cfg.agents?.list) ? cfg.agents.list.find((a) => a && a.enabled !== false && a.id.toLowerCase() === agentId.toLowerCase()) : void 0;
509
- const profile = resolveEffectiveAgentProfile(cfg, agentId);
510
- const rt = this.workspaceRuntimes.getOrCreate(profile.resolvedWorkspacePath, profile.agentId);
508
+ const entry = Array.isArray(cfg.agents?.list) ? cfg.agents.list.find((a) => a && a.enabled !== false && a.id.toLowerCase() === profile.agentId.toLowerCase()) : void 0;
509
+ const rt = this.workspaceRuntimes.getOrCreate(workspaceDir, profile.agentId);
511
510
  const skillsConfig = createSkillConfigManager(resolveStateDir()).load();
512
511
  const lock = loadSkillsLock();
513
- const workspaceLock = loadSkillsLock(resolveWorkspaceSkillsLockPath(profile.resolvedWorkspacePath));
512
+ const workspaceLock = loadSkillsLock(resolveWorkspaceSkillsLockPath(workspaceDir));
514
513
  const allow = profile.skillsAllowlist === void 0 ? void 0 : new Set(profile.skillsAllowlist.map((s) => s.toLowerCase()));
515
514
  const skills = rt.skillManager.getSkills().map((s) => {
516
515
  let unavailableReason = null;
@@ -519,13 +518,14 @@ var AgentManager = class {
519
518
  else if (!isSkillEnabled(s, skillsConfig)) unavailableReason = "requirements-unmet";
520
519
  else if (allow !== void 0 && !allow.has(s.name.toLowerCase())) unavailableReason = "agent-denied";
521
520
  return {
522
- ...this.skillCatalogEntryFromSkill(s, skillsConfig, lock, workspaceLock, profile.resolvedWorkspacePath),
521
+ ...this.skillCatalogEntryFromSkill(s, skillsConfig, lock, workspaceLock, workspaceDir),
523
522
  availableForCurrentAgent: unavailableReason === null,
524
523
  unavailableReason
525
524
  };
526
525
  });
527
526
  return {
528
527
  agentId: profile.agentId,
528
+ workspacePath: workspaceDir,
529
529
  version: rt.skillManager.getVersion(),
530
530
  loadedAt: rt.skillManager.getLoadedAt(),
531
531
  diagnostics: rt.skillManager.getDiagnostics(),
@@ -535,6 +535,36 @@ var AgentManager = class {
535
535
  skills
536
536
  };
537
537
  }
538
+ getAgentSkillAvailability(agentId) {
539
+ const profile = resolveEffectiveAgentProfile(this.config.config, agentId);
540
+ return this.buildAgentSkillAvailability(profile, profile.resolvedWorkspacePath);
541
+ }
542
+ getSessionSkillAvailability(sessionKey) {
543
+ const profile = resolveEffectiveAgentProfileForSession(this.config.config, sessionKey);
544
+ return this.buildAgentSkillAvailability(profile, this.getResolvedWorkspaceForSession(sessionKey));
545
+ }
546
+ getSessionWorkspaceTrust(sessionKey) {
547
+ const workspacePath = this.getResolvedWorkspaceForSession(sessionKey);
548
+ const required = hasTrustRequiringProjectResources(workspacePath);
549
+ return {
550
+ workspacePath,
551
+ required,
552
+ decision: required ? this.projectTrustStore.get(workspacePath) : null,
553
+ trusted: required && this.isProjectWorkspaceTrusted(workspacePath)
554
+ };
555
+ }
556
+ setSessionWorkspaceTrust(sessionKey, trusted) {
557
+ const workspacePath = this.getResolvedWorkspaceForSession(sessionKey);
558
+ if (!hasTrustRequiringProjectResources(workspacePath)) return {
559
+ workspacePath,
560
+ required: false,
561
+ decision: null,
562
+ trusted: false
563
+ };
564
+ this.projectTrustStore.set(workspacePath, trusted);
565
+ this.refreshSkillsAfterTrustChange();
566
+ return this.getSessionWorkspaceTrust(sessionKey);
567
+ }
538
568
  /**
539
569
  * After ~/.xopc/skills.json changes (enable/disable), refresh `<available_skills>` on active agents.
540
570
  */
@@ -8,7 +8,7 @@ import type { EmbeddedTranscriptRuntime } from './embedded/transcript-runtime.js
8
8
  import { OutboundCoordinator } from './messaging/index.js';
9
9
  import { TurnDispatcher } from './inbound/turn-dispatcher.js';
10
10
  import { SessionConfigService, SessionHydrator, SessionInspector } from './session/index.js';
11
- import { type AgentSkillAvailabilityPayload, type SkillCatalogEntry, type SkillCatalogSnapshot } from './agent-manager.js';
11
+ import { type AgentSkillAvailabilityPayload, type SkillCatalogEntry, type SkillCatalogSnapshot, type WorkspaceTrustState } from './agent-manager.js';
12
12
  import type { SkillMarkdownPreviewPayload } from './skills/types.js';
13
13
  import type { AgentCapabilityCatalogEntry } from './capabilities/index.js';
14
14
  import type { AgentServiceConfig, StreamHandle } from './service.types.js';
@@ -106,6 +106,9 @@ export declare class AgentService {
106
106
  getSkillCatalog(): SkillCatalogEntry[];
107
107
  getSkillCatalogSnapshot(): SkillCatalogSnapshot;
108
108
  getAgentSkillAvailability(agentId: string): AgentSkillAvailabilityPayload;
109
+ getSessionSkillAvailability(sessionKey: string): Promise<AgentSkillAvailabilityPayload>;
110
+ getSessionWorkspaceTrust(sessionKey: string): Promise<WorkspaceTrustState>;
111
+ setSessionWorkspaceTrust(sessionKey: string, trusted: boolean): Promise<WorkspaceTrustState>;
109
112
  getCapabilityCatalog(sessionKey?: string): AgentCapabilityCatalogEntry[];
110
113
  getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null;
111
114
  refreshSkillsAfterDiskChange(): void;
@@ -501,6 +501,18 @@ var AgentService = class {
501
501
  getAgentSkillAvailability(agentId) {
502
502
  return this.agentManager.getAgentSkillAvailability(agentId);
503
503
  }
504
+ async getSessionSkillAvailability(sessionKey) {
505
+ await this.sessionHydrator.workspace(sessionKey);
506
+ return this.agentManager.getSessionSkillAvailability(sessionKey);
507
+ }
508
+ async getSessionWorkspaceTrust(sessionKey) {
509
+ await this.sessionHydrator.workspace(sessionKey);
510
+ return this.agentManager.getSessionWorkspaceTrust(sessionKey);
511
+ }
512
+ async setSessionWorkspaceTrust(sessionKey, trusted) {
513
+ await this.sessionHydrator.workspace(sessionKey);
514
+ return this.agentManager.setSessionWorkspaceTrust(sessionKey, trusted);
515
+ }
504
516
  getCapabilityCatalog(sessionKey) {
505
517
  return this.agentManager.getCapabilityCatalogForSession(sessionKey);
506
518
  }
@@ -747,7 +747,9 @@ async function handleAutomation(command, args, deps, dryRun) {
747
747
  "trigger",
748
748
  "action",
749
749
  "safety",
750
- "afterRun",
750
+ "conversationMode",
751
+ "notificationPolicy",
752
+ "completionWebhookUrl",
751
753
  "reliability",
752
754
  "state"
753
755
  ]),
@@ -781,7 +783,9 @@ async function handleAutomation(command, args, deps, dryRun) {
781
783
  "trigger",
782
784
  "action",
783
785
  "safety",
784
- "afterRun",
786
+ "conversationMode",
787
+ "notificationPolicy",
788
+ "completionWebhookUrl",
785
789
  "reliability",
786
790
  "state"
787
791
  ]));
@@ -115,6 +115,14 @@ function registerAutomationRoutes(authenticated, deps) {
115
115
  const events = await service.automationServiceInstance.listRunEvents(runId);
116
116
  return c.json({ events });
117
117
  });
118
+ authenticated.post("/api/automation-runs/:runId/read", async (c) => {
119
+ if (!await service.automationServiceInstance.markRunRead(c.req.param("runId"))) return c.json({ error: "Run not found" }, 404);
120
+ return c.json({ marked: true });
121
+ });
122
+ authenticated.post("/api/automation-runs/read-all", async (c) => {
123
+ const count = await service.automationServiceInstance.markAllRunsRead({ projectId: c.req.query("projectId") });
124
+ return c.json({ count });
125
+ });
118
126
  authenticated.post("/api/automation-runs/:runId/rerun", async (c) => {
119
127
  try {
120
128
  const run = await service.automationServiceInstance.rerunFromRun(c.req.param("runId"));
@@ -1,4 +1,4 @@
1
1
  import { DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds } from "./defaults.js";
2
2
  import { computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil } from "./schedule.js";
3
- import { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./validation.js";
4
- export { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds, timerDelayUntil };
3
+ import { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./validation.js";
4
+ export { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds, timerDelayUntil };
@@ -55,14 +55,8 @@ export type AutomationAction = {
55
55
  taskId: string;
56
56
  command: TaskCommand;
57
57
  };
58
- export type AutomationAfterRun = {
59
- kind: 'none';
60
- } | {
61
- kind: 'saveToSession';
62
- } | {
63
- kind: 'webhook';
64
- url: string;
65
- };
58
+ export type AutomationConversationMode = 'new_session' | 'continuous';
59
+ export type AutomationNotificationPolicy = 'attention' | 'all' | 'none';
66
60
  export interface AutomationReliability {
67
61
  /** Overall run deadline. `timeoutSeconds` remains a read-only legacy fallback. */
68
62
  executionTimeoutSeconds?: number;
@@ -71,7 +65,7 @@ export interface AutomationReliability {
71
65
  maxConcurrentRuns?: number;
72
66
  disableAfterConsecutiveFailures?: number;
73
67
  }
74
- export type AutomationRunPhase = 'queued' | 'action' | 'after_run' | 'cancelling' | 'completed';
68
+ export type AutomationRunPhase = 'queued' | 'action' | 'completion_hook' | 'cancelling' | 'completed';
75
69
  export interface AutomationRunTermination {
76
70
  reason: 'completed' | 'failed' | 'user_cancelled' | 'deadline_exceeded';
77
71
  component?: 'automation' | 'agent_turn' | 'tool' | 'mcp' | 'process';
@@ -99,7 +93,9 @@ export interface Automation {
99
93
  trigger: AutomationTrigger;
100
94
  action: AutomationAction;
101
95
  safety?: AutomationSafetyPolicy;
102
- afterRun?: AutomationAfterRun;
96
+ conversationMode: AutomationConversationMode;
97
+ notificationPolicy: AutomationNotificationPolicy;
98
+ completionWebhookUrl?: string;
103
99
  reliability?: AutomationReliability;
104
100
  state: AutomationState;
105
101
  createdAtMs: number;
@@ -133,8 +129,9 @@ export interface AutomationRun {
133
129
  leaseExpiresAtMs?: number;
134
130
  attemptNumber?: number;
135
131
  rootRunId?: string;
132
+ readAtMs?: number;
136
133
  }
137
- export type AutomationRunEventType = 'run.queued' | 'run.started' | 'run.deadline_resolved' | 'run.cancel_requested' | 'run.cancel_confirmed' | 'run.cancellation_unconfirmed' | 'run.recovered' | 'action.started' | 'action.retry_scheduled' | 'action.completed' | 'action.failed' | 'after_run.started' | 'after_run.completed' | 'after_run.failed' | 'run.completed';
134
+ export type AutomationRunEventType = 'run.queued' | 'run.started' | 'run.deadline_resolved' | 'run.cancel_requested' | 'run.cancel_confirmed' | 'run.cancellation_unconfirmed' | 'run.recovered' | 'action.started' | 'action.retry_scheduled' | 'action.completed' | 'action.failed' | 'completion_hook.started' | 'completion_hook.completed' | 'completion_hook.failed' | 'run.completed';
138
135
  export interface AutomationRunEvent {
139
136
  id: string;
140
137
  runId: string;
@@ -165,6 +162,14 @@ export interface AutomationMetrics {
165
162
  runAtMs: number;
166
163
  };
167
164
  }
165
+ export interface PrepareAutomationAgentSessionInput {
166
+ sessionKey: string;
167
+ projectId?: string;
168
+ agentId: string;
169
+ peerId: string;
170
+ automationId: string;
171
+ runId: string;
172
+ }
168
173
  export interface AutomationDeps {
169
174
  agentService?: {
170
175
  sessionConfig?: {
@@ -181,7 +186,7 @@ export interface AutomationDeps {
181
186
  getModelForSession?: (sessionKey: string) => string | undefined;
182
187
  };
183
188
  getDefaultAgentId?: () => string;
184
- getProjectWorkspaceRoot?: (projectId: string) => string | undefined;
189
+ prepareAgentSession?: (input: PrepareAutomationAgentSessionInput) => Promise<void>;
185
190
  workflowRunService?: WorkflowRunServiceLike;
186
191
  browserRecipeService?: {
187
192
  runAndWait(recipeId: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<{
@@ -152,14 +152,6 @@ export declare const AutomationActionSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
152
152
  }, z.core.$strip>;
153
153
  }, z.core.$strip>], "type">;
154
154
  }, z.core.$strict>], "kind">;
155
- export declare const AutomationAfterRunSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
156
- kind: z.ZodLiteral<"none">;
157
- }, z.core.$strict>, z.ZodObject<{
158
- kind: z.ZodLiteral<"saveToSession">;
159
- }, z.core.$strict>, z.ZodObject<{
160
- kind: z.ZodLiteral<"webhook">;
161
- url: z.ZodString;
162
- }, z.core.$strict>], "kind">;
163
155
  export declare const AutomationReliabilitySchema: z.ZodObject<{
164
156
  executionTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
165
157
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
@@ -344,14 +336,16 @@ export declare const AutomationSchema: z.ZodObject<{
344
336
  auto_apply: "auto_apply";
345
337
  }>;
346
338
  }, z.core.$strict>>;
347
- afterRun: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
348
- kind: z.ZodLiteral<"none">;
349
- }, z.core.$strict>, z.ZodObject<{
350
- kind: z.ZodLiteral<"saveToSession">;
351
- }, z.core.$strict>, z.ZodObject<{
352
- kind: z.ZodLiteral<"webhook">;
353
- url: z.ZodString;
354
- }, z.core.$strict>], "kind">>;
339
+ conversationMode: z.ZodDefault<z.ZodEnum<{
340
+ new_session: "new_session";
341
+ continuous: "continuous";
342
+ }>>;
343
+ notificationPolicy: z.ZodDefault<z.ZodEnum<{
344
+ none: "none";
345
+ all: "all";
346
+ attention: "attention";
347
+ }>>;
348
+ completionWebhookUrl: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
355
349
  reliability: z.ZodOptional<z.ZodObject<{
356
350
  executionTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
357
351
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
@@ -530,14 +524,6 @@ export declare const CreateAutomationSchema: z.ZodObject<{
530
524
  source: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
531
525
  payloadMatch: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>>;
532
526
  }, z.core.$strict>], "kind">;
533
- afterRun: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
534
- kind: z.ZodLiteral<"none">;
535
- }, z.core.$strict>, z.ZodObject<{
536
- kind: z.ZodLiteral<"saveToSession">;
537
- }, z.core.$strict>, z.ZodObject<{
538
- kind: z.ZodLiteral<"webhook">;
539
- url: z.ZodString;
540
- }, z.core.$strict>], "kind">>;
541
527
  reliability: z.ZodOptional<z.ZodObject<{
542
528
  executionTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
543
529
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
@@ -545,6 +531,16 @@ export declare const CreateAutomationSchema: z.ZodObject<{
545
531
  maxConcurrentRuns: z.ZodOptional<z.ZodNumber>;
546
532
  disableAfterConsecutiveFailures: z.ZodOptional<z.ZodNumber>;
547
533
  }, z.core.$strict>>;
534
+ conversationMode: z.ZodDefault<z.ZodEnum<{
535
+ new_session: "new_session";
536
+ continuous: "continuous";
537
+ }>>;
538
+ notificationPolicy: z.ZodDefault<z.ZodEnum<{
539
+ none: "none";
540
+ all: "all";
541
+ attention: "attention";
542
+ }>>;
543
+ completionWebhookUrl: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
548
544
  id: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
549
545
  enabled: z.ZodOptional<z.ZodBoolean>;
550
546
  state: z.ZodOptional<z.ZodObject<{
@@ -733,14 +729,6 @@ export declare const UpdateAutomationSchema: z.ZodObject<{
733
729
  lastError: z.ZodOptional<z.ZodString>;
734
730
  consecutiveFailures: z.ZodOptional<z.ZodNumber>;
735
731
  }, z.core.$strict>>>;
736
- afterRun: z.ZodOptional<z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
737
- kind: z.ZodLiteral<"none">;
738
- }, z.core.$strict>, z.ZodObject<{
739
- kind: z.ZodLiteral<"saveToSession">;
740
- }, z.core.$strict>, z.ZodObject<{
741
- kind: z.ZodLiteral<"webhook">;
742
- url: z.ZodString;
743
- }, z.core.$strict>], "kind">>>;
744
732
  reliability: z.ZodOptional<z.ZodOptional<z.ZodObject<{
745
733
  executionTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
746
734
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
@@ -748,6 +736,16 @@ export declare const UpdateAutomationSchema: z.ZodObject<{
748
736
  maxConcurrentRuns: z.ZodOptional<z.ZodNumber>;
749
737
  disableAfterConsecutiveFailures: z.ZodOptional<z.ZodNumber>;
750
738
  }, z.core.$strict>>>;
739
+ conversationMode: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
740
+ new_session: "new_session";
741
+ continuous: "continuous";
742
+ }>>>;
743
+ notificationPolicy: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
744
+ none: "none";
745
+ all: "all";
746
+ attention: "attention";
747
+ }>>>;
748
+ completionWebhookUrl: z.ZodOptional<z.ZodPreprocess<z.ZodOptional<z.ZodString>>>;
751
749
  }, z.core.$strict>;
752
750
  export type CreateAutomationInput = z.infer<typeof CreateAutomationSchema>;
753
751
  export type UpdateAutomationInput = z.infer<typeof UpdateAutomationSchema>;
@@ -94,14 +94,6 @@ const AutomationActionSchema = z.discriminatedUnion("kind", [
94
94
  command: TaskCommandSchema
95
95
  }).strict()
96
96
  ]);
97
- const AutomationAfterRunSchema = z.discriminatedUnion("kind", [
98
- z.object({ kind: z.literal("none") }).strict(),
99
- z.object({ kind: z.literal("saveToSession") }).strict(),
100
- z.object({
101
- kind: z.literal("webhook"),
102
- url: nonEmptyString.max(2e3)
103
- }).strict()
104
- ]);
105
97
  const AutomationReliabilitySchema = z.object({
106
98
  executionTimeoutSeconds: z.number().int().min(1).max(86400).optional(),
107
99
  timeoutSeconds: z.number().int().min(1).max(86400).optional(),
@@ -139,7 +131,13 @@ const AutomationSchema = z.object({
139
131
  trigger: AutomationTriggerSchema,
140
132
  action: AutomationActionSchema,
141
133
  safety: AutomationSafetyPolicySchema.optional(),
142
- afterRun: AutomationAfterRunSchema.optional(),
134
+ conversationMode: z.enum(["new_session", "continuous"]).default("new_session"),
135
+ notificationPolicy: z.enum([
136
+ "attention",
137
+ "all",
138
+ "none"
139
+ ]).default("attention"),
140
+ completionWebhookUrl: optionalTrimmedString(2e3),
143
141
  reliability: AutomationReliabilitySchema.optional(),
144
142
  state: AutomationStateSchema.default({}),
145
143
  createdAtMs: z.number().int().nonnegative(),
@@ -162,4 +160,4 @@ const UpdateAutomationSchema = AutomationSchema.omit({
162
160
  updatedAtMs: true
163
161
  }).partial().refine((data) => Object.keys(data).length > 0, { message: "At least one field must be provided" });
164
162
  //#endregion
165
- export { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema };
163
+ export { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema };
@@ -10,8 +10,9 @@ JSON shape:
10
10
  "trigger": { "kind": "manual" },
11
11
  "action": { "kind": "agent", "instruction": "clear instruction for the agent" },
12
12
  "safety": { "mode": "suggest_only" },
13
- "afterRun": { "kind": "none" },
14
- "reliability": { "timeoutSeconds": 300, "disableAfterConsecutiveFailures": 3 }
13
+ "conversationMode": "new_session",
14
+ "notificationPolicy": "attention",
15
+ "reliability": { "executionTimeoutSeconds": 300, "disableAfterConsecutiveFailures": 3 }
15
16
  },
16
17
  "explanation": "Short explanation",
17
18
  "assumptions": ["..."],
@@ -49,8 +50,9 @@ Rules:
49
50
  - Default to safety { "mode": "suggest_only" } unless the user explicitly asks for fully automatic execution.
50
51
  - Do not invent destructive actions. For deletion, external sending, or irreversible changes, include a risk and make the instruction ask for confirmation.
51
52
  - Use cron for daily/weekly schedules. Use standard 5-field cron.
52
- - Keep timeoutSeconds between 60 and 1800.
53
- - afterRun should usually be { "kind": "none" }.
53
+ - Keep executionTimeoutSeconds between 60 and 1800.
54
+ - Use conversationMode "new_session" unless the user explicitly wants each run to continue the same conversation.
55
+ - Use notificationPolicy "attention" unless the user explicitly requests every-run notifications or no notifications.
54
56
  - Language for user-facing copy: ${params.language ?? "en"}.
55
57
 
56
58
  User request:
@@ -82,7 +84,9 @@ JSON shape:
82
84
  "trigger": "optional complete trigger object",
83
85
  "action": "optional complete action object",
84
86
  "safety": "optional complete safety object",
85
- "afterRun": "optional complete afterRun object",
87
+ "conversationMode": "optional new_session or continuous",
88
+ "notificationPolicy": "optional attention, all, or none",
89
+ "completionWebhookUrl": "optional HTTPS URL",
86
90
  "reliability": "optional complete reliability object",
87
91
  "enabled": true
88
92
  },
@@ -11,6 +11,8 @@ export declare function buildAutomationDraftResponse(draft: GeneratedAutomationD
11
11
  draftId: `${string}-${string}-${string}-${string}-${string}`;
12
12
  automation: {
13
13
  name: string;
14
+ conversationMode: "new_session" | "continuous";
15
+ notificationPolicy: "none" | "all" | "attention";
14
16
  projectId?: string;
15
17
  action?: {
16
18
  kind: "agent";
@@ -130,14 +132,6 @@ export declare function buildAutomationDraftResponse(draft: GeneratedAutomationD
130
132
  source?: string;
131
133
  payloadMatch?: Record<string, string | number | boolean>;
132
134
  };
133
- afterRun?: {
134
- kind: "none";
135
- } | {
136
- kind: "saveToSession";
137
- } | {
138
- kind: "webhook";
139
- url: string;
140
- };
141
135
  reliability?: {
142
136
  executionTimeoutSeconds?: number;
143
137
  timeoutSeconds?: number;
@@ -145,6 +139,7 @@ export declare function buildAutomationDraftResponse(draft: GeneratedAutomationD
145
139
  maxConcurrentRuns?: number;
146
140
  disableAfterConsecutiveFailures?: number;
147
141
  };
142
+ completionWebhookUrl?: string;
148
143
  id?: string;
149
144
  enabled?: boolean;
150
145
  state?: {
@@ -54,8 +54,8 @@ function simulateAutomation(input) {
54
54
  const triggerSummary = summarizeTrigger(automation.trigger);
55
55
  const actionSummary = summarizeAction(automation.action);
56
56
  if (automation.action.kind === "agent" && /delete|remove|send|post|publish|付款|删除|发送|发布/i.test(automation.action.instruction)) requiredConfirmations.push("Agent instruction may perform an external or destructive action.");
57
- if (automation.afterRun?.kind === "webhook") {
58
- safetyNotes.push("After-run webhook will call an external URL after each run.");
57
+ if (automation.completionWebhookUrl) {
58
+ safetyNotes.push("The completion webhook will call an external URL after each run.");
59
59
  requiredConfirmations.push("External webhook call should be reviewed before publishing.");
60
60
  }
61
61
  const safetyMode = automation.safety?.mode ?? "auto_apply";
@@ -96,7 +96,7 @@ function summarizeAction(action) {
96
96
  }
97
97
  function repairPatchNeedsApproval(patch) {
98
98
  if (patch.safety?.mode === "auto_apply") return true;
99
- if (patch.afterRun?.kind === "webhook") return true;
99
+ if (patch.completionWebhookUrl) return true;
100
100
  if (patch.trigger?.kind === "webhook") return true;
101
101
  if (patch.action?.kind === "agent") return /delete|remove|send|post|publish|付款|删除|发送|发布/i.test(patch.action.instruction);
102
102
  return false;
@@ -1,9 +1,9 @@
1
1
  import { DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds } from "./domain/defaults.js";
2
2
  import { computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil } from "./domain/schedule.js";
3
- import { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./domain/validation.js";
3
+ import { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./domain/validation.js";
4
4
  import "./domain/index.js";
5
5
  import { AutomationActionExecutor } from "./service/action-executor.js";
6
6
  import { AutomationAlreadyRunningError, AutomationService } from "./service/automation-service.js";
7
7
  import "./service/index.js";
8
8
  import { onAutomationProductEvent, publishAutomationProductEvent } from "./product-events.js";
9
- export { AutomationActionExecutor, AutomationActionSchema, AutomationAfterRunSchema, AutomationAlreadyRunningError, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationService, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, onAutomationProductEvent, publishAutomationProductEvent, resolveAutomationTimeoutSeconds, timerDelayUntil };
9
+ export { AutomationActionExecutor, AutomationActionSchema, AutomationAlreadyRunningError, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationService, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, onAutomationProductEvent, publishAutomationProductEvent, resolveAutomationTimeoutSeconds, timerDelayUntil };