@powerhousedao/ph-clint-app 0.1.0-dev.89 → 0.1.0-dev.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/{editor-BuHwuzRa.js → editor-Bp2wUo8R.js} +748 -522
- package/dist/browser/editor-Bp2wUo8R.js.map +1 -0
- package/dist/browser/editors/ph-clint-project-editor/module.js +1 -1
- package/dist/connect/assets/{AddDriveModal-BoKLJyUY-DwlVwt2n.js → AddDriveModal-BoKLJyUY-cGJwd_2F.js} +2 -2
- package/dist/connect/assets/{AddDriveModal-BoKLJyUY-DwlVwt2n.js.map → AddDriveModal-BoKLJyUY-cGJwd_2F.js.map} +1 -1
- package/dist/connect/assets/{ClearStorageModal-CXoNWmRe-lBEW3sSH.js → ClearStorageModal-CXoNWmRe-D3ifKRm-.js} +2 -2
- package/dist/connect/assets/{ClearStorageModal-CXoNWmRe-lBEW3sSH.js.map → ClearStorageModal-CXoNWmRe-D3ifKRm-.js.map} +1 -1
- package/dist/connect/assets/{CookiesPolicyModal-1nOh6oN3-BYSDp-5J.js → CookiesPolicyModal-1nOh6oN3-kK_sx5mz.js} +2 -2
- package/dist/connect/assets/{CookiesPolicyModal-1nOh6oN3-BYSDp-5J.js.map → CookiesPolicyModal-1nOh6oN3-kK_sx5mz.js.map} +1 -1
- package/dist/connect/assets/{CreateDocumentModal-nQbLVDq3-DJbJhlYp.js → CreateDocumentModal-nQbLVDq3-DFAye2CX.js} +2 -2
- package/dist/connect/assets/{CreateDocumentModal-nQbLVDq3-DJbJhlYp.js.map → CreateDocumentModal-nQbLVDq3-DFAye2CX.js.map} +1 -1
- package/dist/connect/assets/{DebugSettingsModal-5SDhy5gt-Du3PKhbh.js → DebugSettingsModal-5SDhy5gt-DLMPdDQB.js} +2 -2
- package/dist/connect/assets/{DebugSettingsModal-5SDhy5gt-Du3PKhbh.js.map → DebugSettingsModal-5SDhy5gt-DLMPdDQB.js.map} +1 -1
- package/dist/connect/assets/{DeleteDriveModal-6P0T1QgD-CaEKmseP.js → DeleteDriveModal-6P0T1QgD-CK6cPXbT.js} +2 -2
- package/dist/connect/assets/{DeleteDriveModal-6P0T1QgD-CaEKmseP.js.map → DeleteDriveModal-6P0T1QgD-CK6cPXbT.js.map} +1 -1
- package/dist/connect/assets/{DeleteItemModal-BmV1aQyZ-B01dssV-.js → DeleteItemModal-BmV1aQyZ-Ld9lHNhl.js} +2 -2
- package/dist/connect/assets/{DeleteItemModal-BmV1aQyZ-B01dssV-.js.map → DeleteItemModal-BmV1aQyZ-Ld9lHNhl.js.map} +1 -1
- package/dist/connect/assets/{DisclaimerModal-CVTFfN0_-CfPGYzP1.js → DisclaimerModal-CVTFfN0_-D7N9TDI4.js} +2 -2
- package/dist/connect/assets/{DisclaimerModal-CVTFfN0_-CfPGYzP1.js.map → DisclaimerModal-CVTFfN0_-D7N9TDI4.js.map} +1 -1
- package/dist/connect/assets/{DownloadDocumentWithErrorsModal-CXeFUtaz-UexzRqQT.js → DownloadDocumentWithErrorsModal-CXeFUtaz-CYIIl42M.js} +2 -2
- package/dist/connect/assets/{DownloadDocumentWithErrorsModal-CXeFUtaz-UexzRqQT.js.map → DownloadDocumentWithErrorsModal-CXeFUtaz-CYIIl42M.js.map} +1 -1
- package/dist/connect/assets/{DriveAuthRequiredModal-B3VdLwSH-C5FZCMC5.js → DriveAuthRequiredModal-B3VdLwSH-fqmI_4sF.js} +2 -2
- package/dist/connect/assets/{DriveAuthRequiredModal-B3VdLwSH-C5FZCMC5.js.map → DriveAuthRequiredModal-B3VdLwSH-fqmI_4sF.js.map} +1 -1
- package/dist/connect/assets/{DriveSettingsModal-CsNFEJ9E-BoXSbW1c.js → DriveSettingsModal-CsNFEJ9E-BR2vyeU8.js} +2 -2
- package/dist/connect/assets/{DriveSettingsModal-CsNFEJ9E-BoXSbW1c.js.map → DriveSettingsModal-CsNFEJ9E-BR2vyeU8.js.map} +1 -1
- package/dist/connect/assets/{InspectorModal-BsSihzuc-hukmcBoP.js → InspectorModal-BsSihzuc-B0n5gbGB.js} +2 -2
- package/dist/connect/assets/{InspectorModal-BsSihzuc-hukmcBoP.js.map → InspectorModal-BsSihzuc-B0n5gbGB.js.map} +1 -1
- package/dist/connect/assets/{MissingPackageModal-Bn036mWQ-BOXHWmFa.js → MissingPackageModal-Bn036mWQ-C021G1nV.js} +2 -2
- package/dist/connect/assets/{MissingPackageModal-Bn036mWQ-BOXHWmFa.js.map → MissingPackageModal-Bn036mWQ-C021G1nV.js.map} +1 -1
- package/dist/connect/assets/{SettingsModal-S_A5qf95-Fz0f2CXX.js → SettingsModal-S_A5qf95-uzigz0nk.js} +2 -2
- package/dist/connect/assets/{SettingsModal-S_A5qf95-Fz0f2CXX.js.map → SettingsModal-S_A5qf95-uzigz0nk.js.map} +1 -1
- package/dist/connect/assets/{UpgradeDriveModal-C7lV4rAX-BkeBWpDi.js → UpgradeDriveModal-C7lV4rAX-CTIf4duw.js} +2 -2
- package/dist/connect/assets/{UpgradeDriveModal-C7lV4rAX-BkeBWpDi.js.map → UpgradeDriveModal-C7lV4rAX-CTIf4duw.js.map} +1 -1
- package/dist/connect/assets/build-info-cc1PjSvF-DtAGzh0W.js.map +1 -1
- package/dist/connect/assets/chunk-pbuEa-1d-KEQyMDN_.js.map +1 -1
- package/dist/connect/assets/{components-ByEUkO4U-Mc23VVA-.js → components-ByEUkO4U-xPZUVkzr.js} +4 -4
- package/dist/connect/assets/{components-ByEUkO4U-Mc23VVA-.js.map → components-ByEUkO4U-xPZUVkzr.js.map} +1 -1
- package/dist/connect/assets/{components-HCKyLh9m.js → components-Djrujufg.js} +2 -2
- package/dist/connect/assets/{components-HCKyLh9m.js.map → components-Djrujufg.js.map} +1 -1
- package/dist/connect/assets/{connect-pRAhId57.js → connect-CGvtDtZh.js} +2 -2
- package/dist/connect/assets/{connect-pRAhId57.js.map → connect-CGvtDtZh.js.map} +1 -1
- package/dist/connect/assets/{connect.config-Bt4pvvWV-CAyer5pZ.js → connect.config-Bt4pvvWV-Dj3FkjaZ.js} +2 -2
- package/dist/connect/assets/{connect.config-Bt4pvvWV-CAyer5pZ.js.map → connect.config-Bt4pvvWV-Dj3FkjaZ.js.map} +1 -1
- package/dist/connect/assets/{dist-DmhUSVtT.js → dist-t-ezfpxv.js} +3 -3
- package/dist/connect/assets/{dist-DmhUSVtT.js.map → dist-t-ezfpxv.js.map} +1 -1
- package/dist/connect/assets/{editor-B560eld_-CIE3_3II.js → editor-B560eld_-DLpKHubk.js} +2 -2
- package/dist/connect/assets/{editor-B560eld_-CIE3_3II.js.map → editor-B560eld_-DLpKHubk.js.map} +1 -1
- package/dist/connect/assets/editor-BaQ62r3i.js +2 -0
- package/dist/connect/assets/editor-BaQ62r3i.js.map +1 -0
- package/dist/connect/assets/{editor-CAVHtR-v-ClzvSfK5.js → editor-CAVHtR-v-D33T9vW0.js} +2 -2
- package/dist/connect/assets/{editor-CAVHtR-v-ClzvSfK5.js.map → editor-CAVHtR-v-D33T9vW0.js.map} +1 -1
- package/dist/connect/assets/{editor-CVCLxUhe-C6nP7EPN.js → editor-CVCLxUhe-C9Ftgu1S.js} +2 -2
- package/dist/connect/assets/{editor-CVCLxUhe-C6nP7EPN.js.map → editor-CVCLxUhe-C9Ftgu1S.js.map} +1 -1
- package/dist/connect/assets/{editor-DnG2Zzet-CRhirYbH.js → editor-DnG2Zzet-CQ38uSti.js} +2 -2
- package/dist/connect/assets/{editor-DnG2Zzet-CRhirYbH.js.map → editor-DnG2Zzet-CQ38uSti.js.map} +1 -1
- package/dist/connect/assets/{editor-mor7dV6n-DDigdbLM.js → editor-mor7dV6n-NTU9k1uj.js} +2 -2
- package/dist/connect/assets/{editor-mor7dV6n-DDigdbLM.js.map → editor-mor7dV6n-NTU9k1uj.js.map} +1 -1
- package/dist/connect/assets/{editor-xCnDas6c-CyHuSL7M.js → editor-xCnDas6c-DdGhx--5.js} +2 -2
- package/dist/connect/assets/{editor-xCnDas6c-CyHuSL7M.js.map → editor-xCnDas6c-DdGhx--5.js.map} +1 -1
- package/dist/connect/assets/esm-dD38MHAT.js +10 -0
- package/dist/connect/assets/esm-dD38MHAT.js.map +1 -0
- package/dist/connect/assets/{hooks-Btogj1f0-CMXQZV6d.js → hooks-Btogj1f0-BKAAmyt-.js} +2 -2
- package/dist/connect/assets/{hooks-Btogj1f0-CMXQZV6d.js.map → hooks-Btogj1f0-BKAAmyt-.js.map} +1 -1
- package/dist/connect/assets/index-NB86TKkT.js +3 -0
- package/dist/connect/assets/{index-DS7vbdaR.js.map → index-NB86TKkT.js.map} +1 -1
- package/dist/connect/assets/{load-BWibkoFV-BVilFVpD.js → load-BWibkoFV-CDRjWwYQ.js} +2 -2
- package/dist/connect/assets/{load-BWibkoFV-BVilFVpD.js.map → load-BWibkoFV-CDRjWwYQ.js.map} +1 -1
- package/dist/connect/assets/module-1hr_ne9w-CWAVsMzZ.js.map +1 -1
- package/dist/connect/assets/{module-DP3LMNU7.js → module-7zCQE1MC.js} +2 -2
- package/dist/connect/assets/{module-DP3LMNU7.js.map → module-7zCQE1MC.js.map} +1 -1
- package/dist/connect/assets/module-CRq_lUkG-D61oeRlC.js.map +1 -1
- package/dist/connect/assets/module-DP3bVbak-VbUPIBZP.js.map +1 -1
- package/dist/connect/assets/package-BZLLR0Ma-B7vswMvI.js.map +1 -1
- package/dist/connect/assets/{pglite-seed-BWk7yOwr-T-NGWlGh.js → pglite-seed-BWk7yOwr-b2F0oJiP.js} +2 -2
- package/dist/connect/assets/{pglite-seed-BWk7yOwr-T-NGWlGh.js.map → pglite-seed-BWk7yOwr-b2F0oJiP.js.map} +1 -1
- package/dist/connect/assets/pglite.worker-BuyZ0d7u.js.map +1 -1
- package/dist/connect/assets/pglite.worker.legacy-D5InEf0i.js.map +1 -1
- package/dist/connect/assets/{ph-clint-project-BZ5X7dVQ.js → ph-clint-project-p1zY6e17.js} +2 -2
- package/dist/connect/assets/{ph-clint-project-BZ5X7dVQ.js.map → ph-clint-project-p1zY6e17.js.map} +1 -1
- package/dist/connect/assets/{reactor-BxNvHOKC-DmVBqCt_.js → reactor-BxNvHOKC-CeMF1M2u.js} +4 -4
- package/dist/connect/assets/{reactor-BxNvHOKC-DmVBqCt_.js.map → reactor-BxNvHOKC-CeMF1M2u.js.map} +1 -1
- package/dist/connect/assets/{registerServiceWorker-D9l1kja7-oC4nicB2.js → registerServiceWorker-D9l1kja7-DG3DqQna.js} +2 -2
- package/dist/connect/assets/{registerServiceWorker-D9l1kja7-oC4nicB2.js.map → registerServiceWorker-D9l1kja7-DG3DqQna.js.map} +1 -1
- package/dist/connect/assets/reload-connect-toast-CwvSc6F--BQcqGaN_.js.map +1 -1
- package/dist/connect/assets/runtime-config-DL3QjcfM-D9g4VFtY.js.map +1 -1
- package/dist/connect/assets/toast-BEy42aYx-Dg_jZf6v.js.map +1 -1
- package/dist/connect/assets/{useRegistryPackages-B-gFECmd-CXOBKziY.js → useRegistryPackages-B-gFECmd-C8h2M5qM.js} +2 -2
- package/dist/connect/assets/{useRegistryPackages-B-gFECmd-CXOBKziY.js.map → useRegistryPackages-B-gFECmd-C8h2M5qM.js.map} +1 -1
- package/dist/connect/assets/{useVetraDocument-tpjMF571-DT5T1mNT.js → useVetraDocument-tpjMF571-DxT9GgCx.js} +2 -2
- package/dist/connect/assets/{useVetraDocument-tpjMF571-DT5T1mNT.js.map → useVetraDocument-tpjMF571-DxT9GgCx.js.map} +1 -1
- package/dist/connect/assets/utils-BiV3cs9Y-B7i9WJ1b.js.map +1 -1
- package/dist/connect/assets/{utils-CkWB3DRk-CxqNKFWP.js → utils-CkWB3DRk-BURJYofr.js} +2 -2
- package/dist/connect/assets/{utils-CkWB3DRk-CxqNKFWP.js.map → utils-CkWB3DRk-BURJYofr.js.map} +1 -1
- package/dist/connect/index.html +3 -3
- package/dist/connect/powerhouse.config.json +1 -1
- package/dist/node/{editor-Bev0bZuJ.mjs → editor-BC9t7D3T.mjs} +748 -517
- package/dist/node/editor-BC9t7D3T.mjs.map +1 -0
- package/dist/node/editors/ph-clint-project-editor/module.mjs +1 -1
- package/package.json +2 -2
- package/dist/browser/editor-BuHwuzRa.js.map +0 -1
- package/dist/connect/assets/editor-BrPMvNFl.js +0 -2
- package/dist/connect/assets/editor-BrPMvNFl.js.map +0 -1
- package/dist/connect/assets/esm-mbrYcWED.js +0 -10
- package/dist/connect/assets/esm-mbrYcWED.js.map +0 -1
- package/dist/connect/assets/index-DS7vbdaR.js +0 -3
- package/dist/node/editor-Bev0bZuJ.mjs.map +0 -1
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import"./chunk-BNv3lrIs.js";import{Et as e,_ as t,n,vt as r}from"./dist-DmhUSVtT.js";import{g as i}from"./connect-pRAhId57.js";import{X as a}from"./types-CxSpmNGK-BaNo7EHQ.js";import{O as o,s}from"./ph-clint-project-BZ5X7dVQ.js";import{t as c}from"./__vite-browser-external-Bo8I1g8S.js";import{Fragment as l,jsx as u,jsxs as d}from"react/jsx-runtime";import{useCallback as f,useEffect as p,useMemo as m,useRef as h,useState as g}from"react";c();var _=class extends Error{constructor(e){super(`Attachment not found: ${e}`),this.name=`AttachmentNotFound`}},v=class extends Error{constructor(e){super(`Reservation not found: ${e}`),this.name=`ReservationNotFound`}},y=class extends Error{constructor(e){super(`Invalid attachment ref: ${e}`),this.name=`InvalidAttachmentRef`}},b=/^attachment:\/\/v(\d+):(.+)$/;function x(e){let t=b.exec(e);if(!t)throw new y(e);return{version:Number(t[1]),hash:t[2]}}var S=class{constructor(e,t,n){this.store=e,this.reservations=t,this.uploadFactory=n}async reserve(e){let t=await this.reservations.create(e);return this.uploadFactory.createUpload(t.reservationId,e)}async stat(e){let{hash:t}=x(e);return this.store.stat(t)}async get(e,t){let{hash:n}=x(e);return this.store.get(n,t)}};async function C(e,t){let n={};if(t){let r=await t(e);r&&(n.Authorization=`Bearer ${r}`)}return n}function w(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function T(e){return!(!w(e)||typeof e.reservationId!=`string`||typeof e.mimeType!=`string`||typeof e.fileName!=`string`||e.extension!==null&&typeof e.extension!=`string`||typeof e.createdAtUtc!=`string`||typeof e.expiresAtUtc!=`string`)}var E=class{remoteUrl;jwtHandler;fetchFn;constructor(e){this.remoteUrl=e.remoteUrl,this.jwtHandler=e.jwtHandler,this.fetchFn=e.fetchFn??globalThis.fetch}async create(e){let t=`${this.remoteUrl}/attachments/reservations`,n=await C(t,this.jwtHandler),r=await this.fetchFn(t,{method:`POST`,headers:{...n,"Content-Type":`application/json`},body:JSON.stringify({mimeType:e.mimeType,fileName:e.fileName,extension:e.extension??null})});if(!r.ok)throw Error(`Reservation create failed: ${r.status} ${r.statusText}`);let i=await r.json(),a=new Date;return{reservationId:i.reservationId,mimeType:e.mimeType,fileName:e.fileName,extension:e.extension??null,createdAtUtc:i.createdAtUtc??a.toISOString(),expiresAtUtc:i.expiresAtUtc??new Date(a.getTime()+1440*60*1e3).toISOString()}}async get(e){let t=`${this.remoteUrl}/attachments/reservations/${encodeURIComponent(e)}`,n=await C(t,this.jwtHandler),r=await this.fetchFn(t,{headers:n});if(r.status===404)throw new v(e);if(!r.ok)throw Error(`Reservation get failed: ${r.status} ${r.statusText}`);let i;try{i=await r.json()}catch{throw Error(`Reservation get returned non-JSON response`)}if(!T(i))throw Error(`Reservation get returned a payload that does not match the Reservation shape`);return i}async delete(e){let t=`${this.remoteUrl}/attachments/reservations/${encodeURIComponent(e)}`,n=await C(t,this.jwtHandler),r=await this.fetchFn(t,{method:`DELETE`,headers:n});if(!r.ok&&r.status!==404&&r.status!==410)throw Error(`Reservation delete failed: ${r.status} ${r.statusText}`)}deleteExpired(){return Promise.reject(Error(`RemoteReservationStore.deleteExpired is not supported`))}},D=class{reservationId;remoteUrl;jwtHandler;fetchFn;options;constructor(e,t,n){this.reservationId=e,this.options=t,this.remoteUrl=n.remoteUrl,this.jwtHandler=n.jwtHandler,this.fetchFn=n.fetchFn??globalThis.fetch}async send(e){let t=`${this.remoteUrl}/attachments/reservations/${this.reservationId}`,n=await C(t,this.jwtHandler),r=await this.fetchFn(t,{method:`PUT`,headers:{...n,"Content-Type":`application/octet-stream`},body:e,duplex:`half`});if(!r.ok)throw Error(`Attachment upload failed: ${r.status} ${r.statusText}`);return await r.json()}},O=class{constructor(e){this.config=e}createUpload(e,t){return new D(e,t,this.config)}};function k(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ee(e){return!(!k(e)||typeof e.mimeType!=`string`||typeof e.fileName!=`string`||typeof e.sizeBytes!=`number`||!Number.isFinite(e.sizeBytes)||e.sizeBytes<0||e.extension!==null&&typeof e.extension!=`string`||typeof e.createdAtUtc!=`string`||e.lastAccessedAtUtc!==void 0&&typeof e.lastAccessedAtUtc!=`string`)}function A(e){let t=e.headers.get(`Content-Length`);if(t===null)throw Error(`Switchboard response missing both Attachment-Metadata and Content-Length headers`);let n=Number(t);if(!Number.isInteger(n)||n<0)throw Error(`Switchboard response has invalid Content-Length header: ${JSON.stringify(t)}`);let r=e.headers.get(`Last-Modified`),i=e.headers.get(`Date`),a=r?new Date(r).toISOString():i?new Date(i).toISOString():new Date().toISOString();return{mimeType:e.headers.get(`Content-Type`)??`application/octet-stream`,fileName:`unknown`,sizeBytes:n,extension:null,createdAtUtc:a,lastAccessedAtUtc:a}}function j(e){let t,n=()=>(t===void 0&&(t=A(e)),t),r=e.headers.get(`Attachment-Metadata`);if(r)try{let e=JSON.parse(r);if(k(e)&&(e.extension===void 0&&(e.extension=null),e.createdAtUtc===void 0&&(e.createdAtUtc=n().createdAtUtc),e.lastAccessedAtUtc===void 0&&(e.lastAccessedAtUtc=n().lastAccessedAtUtc)),ee(e))return e}catch{}return n()}var M=class{remoteUrl;jwtHandler;fetchFn;constructor(e){this.remoteUrl=e.remoteUrl,this.jwtHandler=e.jwtHandler,this.fetchFn=e.fetchFn??globalThis.fetch}async stat(e){let t=`${this.remoteUrl}/attachments/${e}`,n=await C(t,this.jwtHandler),r=await this.fetchFn(t,{method:`HEAD`,headers:n});if(r.status===404)throw new _(e);if(!r.ok)throw Error(`Attachment stat failed: ${r.status} ${r.statusText}`);return N(e,j(r))}async get(e,t){return this.fetchAttachment(e,t)}async fetchAttachment(e,t){let n=`${this.remoteUrl}/attachments/${e}`,r=await C(n,this.jwtHandler),i=await this.fetchFn(n,{signal:t,headers:r});if(i.status===404)throw new _(e);if(!i.ok)throw Error(`Attachment fetch failed: ${i.status} ${i.statusText}`);if(!i.body)throw Error(`Response body is null`);return{header:N(e,j(i)),body:i.body}}};function N(e,t){return{hash:e,mimeType:t.mimeType,fileName:t.fileName,sizeBytes:t.sizeBytes,extension:t.extension,status:`available`,source:`sync`,createdAtUtc:t.createdAtUtc,lastAccessedAtUtc:t.lastAccessedAtUtc??t.createdAtUtc}}function te(e){let t=new E(e),n=new O(e);return new S(new M(e),t,n)}var P=[{value:`Disabled`,description:`No Powerhouse integration`},{value:`Reactor`,description:`Document model runtime`},{value:`Switchboard`,description:`API service (GraphQL + MCP)`},{value:`Connect`,description:`Web UI for document management`}];function F(e){let t=/^(\d+)\.(\d+)\.(\d+)/.exec(e);if(!t)return`${e}.1`;let[,n,r,i]=t;return`${n}.${r}.${Number(i)+1}`}function I(e){return d(`label`,{className:e.compact?`my-1 block`:`my-3 block`,children:[u(`h3`,{className:e.compact?`text-xs text-gray-600`:`text-base`,children:e.label}),u(`input`,{type:`text`,defaultValue:e.value,placeholder:e.placeholder,readOnly:e.readOnly,onBlur:t=>{let n=t.target.value.trim();n!==e.value&&e.onCommit(n)},onKeyDown:e=>{e.key===`Enter`&&e.currentTarget.blur()},className:`w-full font-mono`})]})}function L(e){return d(`label`,{className:`my-2 flex items-center gap-3`,children:[u(`input`,{type:`checkbox`,checked:e.checked,disabled:e.disabled,onChange:t=>e.onChange(t.target.checked)}),u(`span`,{className:`font-semibold`,children:e.label}),e.hint?u(`span`,{className:`text-sm text-gray-600`,children:e.hint}):null]})}var ne=[{value:`cli`,label:`CLI`},{value:`agents`,label:`Agents`},{value:`profiles`,label:`Profiles`},{value:`skills`,label:`Skills`},{value:`powerhouse`,label:`Powerhouse`},{value:`publish`,label:`Publish`}];function R(){let[r,c]=s(),l=r.state.global,{powerhouse:f,mastra:p,routine:h}=l.features,[_,v]=g(`cli`),[y]=e(),b=y?.state?.local?.remoteUrl,x=m(()=>te({remoteUrl:b?t(b):n}),[b]),S=e=>c(o.setPackageIdentifier({identifier:e})),C=e=>c(o.setVersion({version:e})),w=e=>c(o.setDescription({description:e})),T=e=>c(o.setPowerhouseLevel({level:e})),E=e=>{if(e){let e=l.name||`my-agent`,t=`${e}-agent`,n=`${e.charAt(0).toUpperCase()}${e.slice(1).replace(/-([a-z])/g,(e,t)=>` ${t.toUpperCase()}`)} Agent`;c(o.enableMastra({agentId:t,agentName:n}))}else c(o.disableMastra({_:!0}))},D=e=>{c(e?o.enableRoutine({_:!0}):o.disableRoutine({_:!0}))},O=e=>c(o.addPowerhousePackage({id:a(),packageName:e})),k=e=>c(o.removePowerhousePackage({id:e})),ee=(e,t)=>c(o.addPackageDocumentType({packageId:e,documentType:t})),A=(e,t)=>c(o.removePackageDocumentType({packageId:e,documentType:t})),j=(e,t)=>c(o.addExternalSkill({id:a(),name:e,githubUrl:t})),M=e=>c(o.removeExternalSkill({id:e})),N=e=>c(o.bumpVersion({version:e})),P=()=>c(o.publishDev({id:a(),timestamp:new Date().toISOString()})),F=()=>c(o.publishStaging({id:a(),timestamp:new Date().toISOString()})),I=()=>c(o.publishProduction({id:a(),timestamp:new Date().toISOString()})),L=e=>c(o.setMainAgentName({name:e})),R=e=>c(o.setMainAgentDescription({description:e})),z=()=>c(o.clearMainAgentDescription({_:!0})),B=e=>c(o.setMainAgentImage({attachment:e})),V=()=>c(o.clearMainAgentImage({_:!0})),H=(e,t,n,r)=>c(o.addSubAgent({id:e,name:t,description:n,modelId:r})),U=e=>c(o.removeSubAgent({id:e})),W=(e,t)=>c(o.setSubAgentName({id:e,name:t})),G=(e,t)=>c(o.setSubAgentDescription({id:e,description:t})),K=e=>c(o.addModel({id:e})),q=e=>c(o.removeModel({id:e})),J=(e,t,n,r)=>c(o.addProfile({id:e,title:t,content:n,insertBefore:r})),Y=(e,t,n)=>c(o.updateProfile({id:e,title:t,content:n})),X=e=>c(o.removeProfile({id:e})),Z=(e,t)=>c(o.reorderProfiles({ids:e,insertBefore:t})),Q=(e,t)=>c(o.setAgentModel({agentId:e,modelId:t})),$=(e,t,n)=>c(o.addAgentProfileRef({agentId:e,profileId:t,insertBefore:n})),le=(e,t)=>c(o.removeAgentProfileRef({agentId:e,profileId:t})),ue=(e,t,n)=>c(o.reorderAgentProfileRefs({agentId:e,ids:t,insertBefore:n})),de=(e,t)=>c(o.addAgentSkill({agentId:e,name:t})),fe=(e,t)=>c(o.removeAgentSkill({agentId:e,name:t})),pe=(e,t)=>c(o.addAgentToolPattern({agentId:e,pattern:t})),me=(e,t)=>c(o.removeAgentToolPattern({agentId:e,pattern:t})),he=e=>c(o.setEnableChat({enabled:e})),ge=e=>c(o.setProxyEnabled({enabled:e})),_e=e=>c(o.setObservabilityEnabled({enabled:e})),ve=e=>c(o.addSupportedResource({resource:e})),ye=e=>c(o.removeSupportedResource({resource:e})),be=f!==`Disabled`,xe=e=>`px-4 py-2 text-sm font-medium border-b-2 cursor-pointer ${_===e?`border-blue-500 text-blue-600`:`border-transparent text-gray-500 hover:text-gray-700`}`;return d(`div`,{className:`mx-auto max-w-4xl bg-gray-50 p-6`,children:[u(i,{}),d(`div`,{className:`ph-default-styles`,children:[u(`h2`,{className:`mt-4 text-xl font-bold`,children:`ph-clint Project Spec`}),u(`nav`,{className:`my-4 flex border-b border-gray-200`,children:ne.map(e=>u(`button`,{className:xe(e.value),onClick:()=>v(e.value),children:e.label},e.value))}),_===`cli`&&u(re,{state:l,powerhouse:f,mastra:p,routine:h,isAboveDisabled:be,setPackageIdentifier:S,setVersion:C,setDescription:w,setPowerhouseLevel:T,toggleMastra:E,toggleRoutine:D,setEnableChat:he,addModel:K,removeModel:q}),_===`agents`&&u(ie,{mastra:p,attachments:x,setMainAgentName:L,setMainAgentDescription:R,clearMainAgentDescription:z,setMainAgentImage:B,clearMainAgentImage:V,addSubAgent:H,removeSubAgent:U,setSubAgentName:W,setSubAgentDescription:G,setAgentModel:Q,addAgentProfileRef:$,removeAgentProfileRef:le,reorderAgentProfileRefs:ue,addAgentSkill:de,removeAgentSkill:fe,addAgentToolPattern:pe,removeAgentToolPattern:me}),_===`profiles`&&u(ae,{mastra:p,addProfile:J,updateProfile:Y,removeProfile:X,reorderProfiles:Z}),_===`skills`&&u(oe,{skills:l.externalSkills,addSkill:j,removeSkill:M}),_===`powerhouse`&&u(se,{packages:l.packages,isAboveDisabled:be,addPackage:O,removePackage:k,addDocType:ee,removeDocType:A}),_===`publish`&&u(ce,{version:l.version,publishHistory:l.publishHistory,documentHeader:r.header,deployment:l.deployment,bumpVersion:N,publishDev:P,publishStaging:F,publishProduction:I,setProxyEnabled:ge,setObservabilityEnabled:_e,addSupportedResource:ve,removeSupportedResource:ye})]})]})}function re(e){let{state:t,mastra:n}=e,r=`${t.scope?t.scope+`/`:``}${t.name??``}`;return d(l,{children:[d(`section`,{className:`my-6`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`Identity`}),d(`div`,{className:`grid grid-cols-[3fr_1fr] gap-4`,children:[u(I,{label:`Package name`,value:r,placeholder:`@scope/my-tool-cli`,onCommit:e.setPackageIdentifier}),u(I,{label:`Version`,value:t.version,placeholder:`0.1.0`,onCommit:e.setVersion})]}),u(I,{label:`Description`,value:t.description,placeholder:`What this CLI does`,onCommit:e.setDescription})]}),u(`hr`,{}),d(`section`,{className:`my-6`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`Features`}),d(`div`,{className:`my-4 rounded border border-gray-200 bg-white p-4`,children:[u(`h4`,{className:`text-base font-semibold`,children:`Powerhouse`}),e.isAboveDisabled&&u(`p`,{className:`text-sm text-gray-500`,children:`Cannot go back to Disabled once enabled`}),u(`div`,{className:`mt-2 space-y-2`,children:P.map((t,n)=>d(`label`,{className:`flex items-start gap-2`,children:[n>0&&u(`div`,{className:`absolute -mt-3 ml-[7px] h-3 border-l border-gray-300`}),u(`input`,{type:`radio`,name:`powerhouse-level`,checked:e.powerhouse===t.value,disabled:e.isAboveDisabled&&t.value===`Disabled`,onChange:()=>e.setPowerhouseLevel(t.value),className:`mt-0.5`}),d(`div`,{children:[u(`span`,{className:`font-medium`,children:t.value}),u(`span`,{className:`ml-2 text-sm text-gray-500`,children:t.description})]})]},t.value))})]}),d(`div`,{className:`my-4 rounded border border-gray-200 bg-white p-4`,children:[u(L,{label:`Mastra`,checked:n.enabled,hint:`AI agent framework`,onChange:e.toggleMastra}),n.enabled&&d(`div`,{className:`mt-4 space-y-4 border-t border-gray-100 pt-4`,children:[u(q,{models:n.models,main:n.mainAgent,subAgents:n.subAgents,addModel:e.addModel,removeModel:e.removeModel}),d(`div`,{children:[u(`h4`,{className:`text-sm font-semibold text-gray-700`,children:`Common`}),u(L,{label:`Enable Chat`,checked:n.common.enableChat,disabled:!e.isAboveDisabled,hint:e.isAboveDisabled?`Chat session integration via clint-common`:`Requires Powerhouse to be enabled`,onChange:e.setEnableChat})]})]})]}),u(`div`,{className:`my-4 rounded border border-gray-200 bg-white p-4`,children:u(L,{label:`Routine loop`,checked:e.routine.enabled,hint:`tick-based execution loop with triggers`,onChange:e.toggleRoutine})})]})]})}function ie(e){let{mastra:t,attachments:n}=e,r=t.mainAgent,[i,a]=g(!1);if(!t.enabled||!r)return d(`section`,{className:`my-6 rounded border border-dashed border-gray-300 bg-white p-8 text-center text-gray-500`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`Agents`}),u(`p`,{className:`mt-2`,children:`Enable Mastra in the CLI tab to configure agents.`})]});let o=[r.id,...t.subAgents.map(e=>e.id)];return d(l,{children:[u(z,{main:r,models:t.models,profiles:t.profiles,attachments:n,setMainAgentName:e.setMainAgentName,setMainAgentDescription:e.setMainAgentDescription,clearMainAgentDescription:e.clearMainAgentDescription,setMainAgentImage:e.setMainAgentImage,clearMainAgentImage:e.clearMainAgentImage,setAgentModel:e.setAgentModel,addAgentProfileRef:e.addAgentProfileRef,removeAgentProfileRef:e.removeAgentProfileRef,reorderAgentProfileRefs:e.reorderAgentProfileRefs,addAgentSkill:e.addAgentSkill,removeAgentSkill:e.removeAgentSkill,addAgentToolPattern:e.addAgentToolPattern,removeAgentToolPattern:e.removeAgentToolPattern}),t.subAgents.map(n=>u(H,{sub:n,models:t.models,profiles:t.profiles,removeSubAgent:e.removeSubAgent,setSubAgentName:e.setSubAgentName,setSubAgentDescription:e.setSubAgentDescription,setAgentModel:e.setAgentModel,addAgentProfileRef:e.addAgentProfileRef,removeAgentProfileRef:e.removeAgentProfileRef,reorderAgentProfileRefs:e.reorderAgentProfileRefs,addAgentSkill:e.addAgentSkill,removeAgentSkill:e.removeAgentSkill,addAgentToolPattern:e.addAgentToolPattern,removeAgentToolPattern:e.removeAgentToolPattern},n.id)),u(`section`,{className:`my-6`,children:i?u(V,{models:t.models,existingAgentIds:o,onAdd:(t,n,r,i)=>{e.addSubAgent(t,n,r,i),a(!1)},onCancel:()=>a(!1)}):u(`button`,{className:`rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:cursor-not-allowed disabled:opacity-50`,disabled:t.models.length===0,title:t.models.length===0?`Add a model first (CLI tab → Mastra)`:``,onClick:()=>a(!0),children:`+ Add Sub-agent`})})]})}function z(e){let{main:t}=e,[n,r]=g(!0);return d(`div`,{className:`my-3 rounded border border-gray-200 bg-white p-4`,children:[u(`div`,{className:`flex items-center justify-between`,children:d(`div`,{className:`flex items-center gap-3`,children:[u(`button`,{className:`text-sm text-gray-400 hover:text-gray-700`,onClick:()=>r(!n),title:n?`Collapse`:`Expand`,children:n?`▾`:`▸`}),u(`span`,{className:`rounded bg-gray-100 px-2 py-0.5 font-mono text-xs text-gray-500`,children:t.id}),u(`span`,{className:`font-semibold`,children:t.name}),u(`span`,{className:`rounded bg-blue-100 px-2 py-0.5 text-xs font-semibold text-blue-700`,children:`Main`})]})}),t.description&&u(`p`,{className:`ml-7 text-sm text-gray-600`,children:t.description}),n&&d(`div`,{className:`mt-4 space-y-3 border-t border-gray-100 pt-4`,children:[d(`div`,{style:{display:`flex`,gap:`1.5rem`},children:[u(`div`,{style:{flexShrink:0,width:`7rem`},children:u(K,{attachmentRef:t.attachment??null,attachments:e.attachments,onSetImage:e.setMainAgentImage,onClearImage:e.clearMainAgentImage})}),d(`div`,{style:{flex:1,minWidth:0},children:[d(`div`,{className:`grid grid-cols-[1fr_2fr] gap-4`,children:[u(I,{compact:!0,readOnly:!0,label:`Agent ID`,value:t.id,onCommit:()=>{}}),u(I,{compact:!0,label:`Agent Name`,value:t.name,placeholder:`My Agent`,onCommit:e.setMainAgentName})]}),u(B,{value:t.description,placeholder:`A brief description of what this agent does`,onSet:e.setMainAgentDescription,onClear:e.clearMainAgentDescription})]})]}),u(U,{agentId:t.id,isMain:!0,modelId:t.modelId,profileIds:t.profileIds,skills:t.skills,toolPatterns:t.toolPatterns,models:e.models,profiles:e.profiles,setAgentModel:e.setAgentModel,addAgentProfileRef:e.addAgentProfileRef,removeAgentProfileRef:e.removeAgentProfileRef,reorderAgentProfileRefs:e.reorderAgentProfileRefs,addAgentSkill:e.addAgentSkill,removeAgentSkill:e.removeAgentSkill,addAgentToolPattern:e.addAgentToolPattern,removeAgentToolPattern:e.removeAgentToolPattern})]})]})}function B(e){return d(`label`,{className:`my-1 block`,children:[u(`h3`,{className:`text-xs text-gray-600`,children:`Description`}),u(`div`,{className:`flex items-center gap-2`,children:u(`input`,{type:`text`,defaultValue:e.value??``,placeholder:e.placeholder,onBlur:t=>{let n=t.target.value.trim();n&&n!==(e.value??``)?e.onSet(n):!n&&e.value!==null&&e.onClear()},onKeyDown:e=>{e.key===`Enter`&&e.currentTarget.blur()},className:`w-full font-mono`})})]})}function V(e){let[t,n]=g(``),[r,i]=g(``),[a,o]=g(``),[s,c]=g(e.models[0]?.id??``),l=/^[a-z][a-z0-9-]*$/.test(t)&&!e.existingAgentIds.includes(t)&&r.trim()&&a.trim()&&s;return d(`div`,{className:`my-3 rounded border border-blue-200 bg-blue-50 p-4`,children:[d(`div`,{className:`grid grid-cols-2 gap-3`,children:[d(`label`,{className:`block`,children:[u(`span`,{className:`text-xs text-gray-600`,children:`Sub-agent ID`}),u(`input`,{type:`text`,value:t,placeholder:`summarizer`,onChange:e=>n(e.target.value.trim()),className:`w-full rounded border p-2 font-mono text-sm`})]}),d(`label`,{className:`block`,children:[u(`span`,{className:`text-xs text-gray-600`,children:`Display name`}),u(`input`,{type:`text`,value:r,placeholder:`Summarizer`,onChange:e=>i(e.target.value),className:`w-full rounded border p-2 text-sm`})]})]}),d(`label`,{className:`my-2 block`,children:[u(`span`,{className:`text-xs text-gray-600`,children:`Description (the main agent uses this to decide when to delegate)`}),u(`input`,{type:`text`,value:a,placeholder:`Summarizes long documents into bullet points`,onChange:e=>o(e.target.value),className:`w-full rounded border p-2 text-sm`})]}),d(`label`,{className:`my-2 block`,children:[u(`span`,{className:`text-xs text-gray-600`,children:`Model`}),u(`select`,{value:s,onChange:e=>c(e.target.value),className:`w-full rounded border p-2 font-mono text-sm`,children:e.models.map(e=>u(`option`,{value:e.id,children:e.id},e.id))})]}),d(`div`,{className:`mt-2 flex items-center gap-2`,children:[u(`button`,{className:`rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:cursor-not-allowed disabled:opacity-50`,disabled:!l,onClick:()=>e.onAdd(t,r.trim(),a.trim(),s),children:`Add`}),u(`button`,{className:`text-sm text-gray-500 hover:text-gray-700`,onClick:e.onCancel,children:`Cancel`})]})]})}function H(e){let{sub:t}=e,[n,r]=g(!1);return d(`div`,{className:`my-3 rounded border border-gray-200 bg-white p-4`,children:[d(`div`,{className:`flex items-center justify-between`,children:[d(`div`,{className:`flex items-center gap-3`,children:[u(`button`,{className:`text-sm text-gray-400 hover:text-gray-700`,onClick:()=>r(!n),title:n?`Collapse`:`Expand`,children:n?`▾`:`▸`}),u(`span`,{className:`rounded bg-gray-100 px-2 py-0.5 font-mono text-xs text-gray-500`,children:t.id}),u(`span`,{className:`font-semibold`,children:t.name})]}),u(`button`,{className:`text-sm text-red-500 hover:text-red-700`,onClick:()=>e.removeSubAgent(t.id),children:`Remove`})]}),u(`p`,{className:`ml-7 text-sm text-gray-600`,children:t.description}),n&&d(`div`,{className:`mt-4 space-y-3 border-t border-gray-100 pt-4`,children:[d(`div`,{className:`grid grid-cols-2 gap-3`,children:[u(I,{compact:!0,label:`Name`,value:t.name,onCommit:n=>e.setSubAgentName(t.id,n)}),u(I,{compact:!0,label:`Description`,value:t.description,onCommit:n=>e.setSubAgentDescription(t.id,n)})]}),u(U,{agentId:t.id,isMain:!1,modelId:t.modelId,profileIds:t.profileIds,skills:t.skills,toolPatterns:t.toolPatterns,models:e.models,profiles:e.profiles,setAgentModel:e.setAgentModel,addAgentProfileRef:e.addAgentProfileRef,removeAgentProfileRef:e.removeAgentProfileRef,reorderAgentProfileRefs:e.reorderAgentProfileRefs,addAgentSkill:e.addAgentSkill,removeAgentSkill:e.removeAgentSkill,addAgentToolPattern:e.addAgentToolPattern,removeAgentToolPattern:e.removeAgentToolPattern})]})]})}function U(e){return d(`div`,{className:`space-y-3`,children:[d(`label`,{className:`block`,children:[u(`span`,{className:`text-xs text-gray-600`,children:`Model`}),u(`select`,{value:e.modelId,onChange:t=>e.setAgentModel(e.agentId,t.target.value),className:`mt-1 w-full rounded border p-2 font-mono text-sm`,children:e.models.map(e=>u(`option`,{value:e.id,children:e.id},e.id))})]}),u(W,{agentId:e.agentId,profileIds:e.profileIds,allProfiles:e.profiles,onAdd:t=>e.addAgentProfileRef(e.agentId,t),onRemove:t=>e.removeAgentProfileRef(e.agentId,t),onReorder:(t,n)=>e.reorderAgentProfileRefs(e.agentId,t,n)}),u(G,{label:`Skills`,hint:`Reference skills by name. tpl wins over ext if both exist.`,values:e.skills,placeholder:`skill-name`,validator:e=>/^[a-z][a-z0-9-]*$/.test(e),onAdd:t=>e.addAgentSkill(e.agentId,t),onRemove:t=>e.removeAgentSkill(e.agentId,t)}),u(G,{label:`Tool patterns`,hint:e.isMain?`Glob patterns over tool names (e.g. clint-project-*, *-mcp__*). Empty = all tools.`:`Glob patterns over tool names. Empty = no tools.`,values:e.toolPatterns,placeholder:`pattern*`,validator:e=>e.length>0,onAdd:t=>e.addAgentToolPattern(e.agentId,t),onRemove:t=>e.removeAgentToolPattern(e.agentId,t)})]})}function W(e){let t=e.allProfiles.filter(t=>!e.profileIds.includes(t.id)),n=t=>{if(t===0)return;let n=e.profileIds[t],r=e.profileIds[t-1];e.onReorder([n],r)},r=t=>{if(t>=e.profileIds.length-1)return;let n=e.profileIds[t],r=t+2<e.profileIds.length?e.profileIds[t+2]:null;e.onReorder([n],r)};return d(`div`,{children:[u(`span`,{className:`text-xs text-gray-600`,children:`Profiles (instructions, in order)`}),d(`ul`,{className:`my-1 space-y-1`,children:[e.profileIds.map((t,i)=>{let a=e.allProfiles.find(e=>e.id===t);return d(`li`,{className:`flex items-center gap-2 rounded bg-gray-50 px-2 py-1`,children:[u(`button`,{className:`text-gray-400 hover:text-gray-600 disabled:opacity-30`,disabled:i===0,onClick:()=>n(i),title:`Move up`,children:`↑`}),u(`button`,{className:`text-gray-400 hover:text-gray-600 disabled:opacity-30`,disabled:i===e.profileIds.length-1,onClick:()=>r(i),title:`Move down`,children:`↓`}),u(`span`,{className:`font-mono text-xs text-gray-500`,children:t}),u(`span`,{className:`flex-1 text-sm`,children:a?.title??u(`em`,{className:`text-red-500`,children:`(missing in library)`})}),u(`button`,{className:`text-sm text-red-500 hover:text-red-700`,onClick:()=>e.onRemove(t),children:`Remove`})]},t)}),e.profileIds.length===0&&u(`li`,{className:`px-2 py-1 text-sm italic text-gray-400`,children:`No profiles assigned`})]}),t.length>0&&d(`select`,{value:``,onChange:t=>{t.target.value&&e.onAdd(t.target.value)},className:`rounded border p-1 text-sm`,children:[u(`option`,{value:``,children:`+ Add profile…`}),t.map(e=>d(`option`,{value:e.id,children:[e.title,` (`,e.id,`)`]},e.id))]})]})}function G(e){let[t,n]=g(``),r=e.validator(t.trim());return d(`div`,{children:[u(`span`,{className:`text-xs text-gray-600`,children:e.label}),u(`p`,{className:`text-xs text-gray-500`,children:e.hint}),u(`div`,{className:`my-1 flex flex-wrap items-center gap-1`,children:e.values.map(t=>d(`span`,{className:`flex items-center gap-1 rounded bg-gray-100 px-2 py-1 font-mono text-xs`,children:[t,u(`button`,{className:`text-red-500 hover:text-red-700`,onClick:()=>e.onRemove(t),title:`Remove`,children:`×`})]},t))}),d(`div`,{className:`flex items-center gap-2`,children:[u(`input`,{type:`text`,placeholder:e.placeholder,value:t,onChange:e=>n(e.target.value),onKeyDown:i=>{i.key===`Enter`&&r&&(e.onAdd(t.trim()),n(``))},className:`flex-1 rounded border p-1 font-mono text-sm`}),u(`button`,{className:`rounded bg-blue-500 px-2 py-1 text-xs text-white hover:bg-blue-600 disabled:cursor-not-allowed disabled:opacity-50`,disabled:!r,onClick:()=>{e.onAdd(t.trim()),n(``)},children:`Add`})]})]})}function K(e){let[t,n]=g(!1),[i,a]=g(void 0),o=h(0),s=r();p(()=>{if(!e.attachmentRef||!e.attachments){a(void 0);return}let t=!1,n;return(async()=>{try{let{body:r,header:i}=await e.attachments.get(e.attachmentRef),o=[],s=r.getReader();for(;;){let{done:e,value:n}=await s.read();if(t||e)break;n&&o.push(n)}if(t)return;let c=new Blob(o,{type:i.mimeType}),l=URL.createObjectURL(c);n=l,a(l)}catch{}})(),()=>{t=!0,n&&URL.revokeObjectURL(n)}},[e.attachmentRef,e.attachments]);let c=async t=>{if(t.type.startsWith(`image/`)){if(!e.attachments){s?.(`Attachment service unavailable — cannot upload image`,{type:`error`});return}try{let{ref:n}=await(await e.attachments.reserve({mimeType:t.type,fileName:t.name})).send(t.stream());e.onSetImage(n)}catch(e){s?.(`Failed to upload image: ${e instanceof Error?e.message:String(e)}`,{type:`error`})}}},m=f(e=>{e.dataTransfer.types.includes(`Files`)&&(e.preventDefault(),e.stopPropagation())},[]),_=f(e=>{e.dataTransfer.types.includes(`Files`)&&(e.stopPropagation(),o.current+=1,o.current===1&&n(!0))},[]),v=f(e=>{e.dataTransfer.types.includes(`Files`)&&(e.stopPropagation(),o.current=Math.max(0,o.current-1),o.current===0&&n(!1))},[]),y=f(e=>{if(e.dataTransfer.types.includes(`Files`)){e.preventDefault(),e.stopPropagation(),o.current=0,n(!1);let t=e.dataTransfer.files[0];t&&c(t)}},[]),b=`7rem`;return u(`div`,{style:{width:b,height:b,flexShrink:0},className:`relative my-3`,children:e.attachmentRef?d(l,{children:[i&&u(`img`,{src:i,alt:`Agent`,style:{width:b,height:b},className:`rounded border border-gray-200 object-cover`}),!i&&u(`div`,{style:{width:b,height:b},className:`rounded border border-gray-200 bg-gray-100`}),d(`div`,{className:`mt-1 flex justify-center gap-1`,children:[d(`label`,{className:`cursor-pointer rounded bg-gray-100 px-2 py-0.5 text-xs hover:bg-gray-200`,children:[`Replace`,u(`input`,{type:`file`,accept:`image/*`,className:`hidden`,onChange:e=>{e.target.files?.[0]&&c(e.target.files[0])}})]}),u(`button`,{className:`rounded bg-gray-100 px-2 py-0.5 text-xs text-red-600 hover:bg-gray-200`,onClick:e.onClearImage,children:`Remove`})]})]}):u(`div`,{style:{width:b,height:b},className:`flex flex-col items-center justify-center rounded border-2 border-dashed text-center ${t?`border-blue-400 bg-blue-50`:`border-gray-300 bg-white`}`,onDragOver:m,onDragEnter:_,onDragLeave:v,onDrop:y,children:d(`label`,{className:`cursor-pointer p-2 text-xs text-gray-500 hover:text-blue-600`,children:[`Drop image or click`,u(`input`,{type:`file`,accept:`image/*`,className:`hidden`,onChange:e=>{e.target.files?.[0]&&c(e.target.files[0])}})]})})})}function q(e){let[t,n]=g(``),r=t=>{let n=[];e.main?.modelId===t&&n.push(e.main.id);for(let r of e.subAgents)r.modelId===t&&n.push(r.id);return n},i=()=>{let r=t.trim();r&&(e.addModel(r),n(``))};return d(`div`,{children:[u(`h4`,{className:`text-sm font-semibold text-gray-700`,children:`Models`}),d(`p`,{className:`text-xs text-gray-500`,children:[`Provider/model format (e.g. `,u(`code`,{children:`anthropic/claude-sonnet-4-5`}),`). Each agent picks one from this list.`]}),e.models.length>0&&d(`table`,{className:`mt-2 w-full text-sm`,children:[u(`thead`,{children:d(`tr`,{className:`border-b text-left text-gray-500`,children:[u(`th`,{className:`py-1`,children:`Model`}),u(`th`,{className:`py-1`,children:`Used by`}),u(`th`,{className:`py-1`})]})}),u(`tbody`,{children:e.models.map(t=>{let n=r(t.id),i=n.length>0;return d(`tr`,{className:`border-b border-gray-100`,children:[u(`td`,{className:`py-2 font-mono`,children:t.id}),u(`td`,{className:`py-2 text-xs text-gray-500`,children:n.length===0?u(`em`,{children:`—`}):n.join(`, `)}),u(`td`,{className:`py-2 text-right`,children:u(`button`,{className:`text-red-500 hover:text-red-700 disabled:cursor-not-allowed disabled:text-gray-300`,disabled:i,title:i?`In use by ${n.join(`, `)}`:``,onClick:()=>e.removeModel(t.id),children:`Remove`})})]},t.id)})})]}),d(`div`,{className:`mt-2 flex items-center gap-2`,children:[u(`input`,{type:`text`,placeholder:`provider/model-name`,value:t,onChange:e=>n(e.target.value),onKeyDown:e=>{e.key===`Enter`&&i()},className:`flex-1 rounded border p-2 font-mono text-sm`}),u(`button`,{className:`rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:opacity-50`,disabled:!t.trim(),onClick:i,children:`Add Model`})]})]})}function ae(e){return e.mastra.enabled?u(J,{profiles:e.mastra.profiles,main:e.mastra.mainAgent,subAgents:e.mastra.subAgents,addProfile:e.addProfile,updateProfile:e.updateProfile,removeProfile:e.removeProfile,reorderProfiles:e.reorderProfiles}):d(`section`,{className:`my-6 rounded border border-dashed border-gray-300 bg-white p-8 text-center text-gray-500`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`Profiles`}),u(`p`,{className:`mt-2`,children:`Enable Mastra in the CLI tab to manage agent profiles.`})]})}function J(e){let[t,n]=g(!1),[r,i]=g(``),[a,o]=g(``),s=t=>{let n=[];e.main?.profileIds.includes(t)&&n.push(e.main.id);for(let r of e.subAgents)r.profileIds.includes(t)&&n.push(r.id);return n},c=()=>{let t=r.trim(),s=a.trim();t&&s&&(e.addProfile(t,s,``),i(``),o(``),n(!1))},l=t=>{if(t===0)return;let n=e.profiles[t].id,r=e.profiles[t-1].id;e.reorderProfiles([n],r)},f=t=>{if(t>=e.profiles.length-1)return;let n=e.profiles[t].id,r=t+2<e.profiles.length?e.profiles[t+2].id:null;e.reorderProfiles([n],r)};return d(`section`,{className:`my-6`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`Agent Profiles`}),u(`p`,{className:`text-sm text-gray-600`,children:`Markdown sections that compose into agents' instructions. Reference these from each agent's profile list.`}),e.profiles.map((t,n)=>{let r=s(t.id),i=r.length>0;return d(`div`,{className:`my-3 rounded border border-gray-200 bg-white p-4`,children:[d(`div`,{className:`flex items-center justify-between`,children:[d(`div`,{className:`flex items-center gap-2`,children:[u(`span`,{className:`rounded bg-gray-100 px-2 py-0.5 font-mono text-xs text-gray-500`,children:t.id}),u(`input`,{type:`text`,defaultValue:t.title,onBlur:n=>{let r=n.target.value.trim();r&&r!==t.title&&e.updateProfile(t.id,r)},onKeyDown:e=>{e.key===`Enter`&&e.currentTarget.blur()},className:`border-b border-transparent font-semibold hover:border-gray-300 focus:border-blue-500`}),r.length>0&&d(`span`,{className:`rounded bg-blue-50 px-2 py-0.5 text-xs text-blue-700`,title:r.join(`, `),children:[`used by: `,r.join(`, `)]})]}),d(`div`,{className:`flex items-center gap-1`,children:[u(`button`,{className:`px-1 text-gray-400 hover:text-gray-600 disabled:opacity-30`,disabled:n===0,onClick:()=>l(n),title:`Move up`,children:`↑`}),u(`button`,{className:`px-1 text-gray-400 hover:text-gray-600 disabled:opacity-30`,disabled:n===e.profiles.length-1,onClick:()=>f(n),title:`Move down`,children:`↓`}),u(`button`,{className:`ml-2 text-sm text-red-500 hover:text-red-700 disabled:cursor-not-allowed disabled:text-gray-300`,disabled:i,title:i?`In use by ${r.join(`, `)}`:``,onClick:()=>e.removeProfile(t.id),children:`Remove`})]})]}),u(`textarea`,{defaultValue:t.content,onBlur:n=>{let r=n.target.value;r!==t.content&&e.updateProfile(t.id,void 0,r)},placeholder:`Markdown content for this profile section...`,rows:4,className:`mt-2 w-full rounded border border-gray-200 p-2 font-mono text-sm`})]},t.id)}),t?u(`div`,{className:`my-3 rounded border border-blue-200 bg-blue-50 p-4`,children:d(`div`,{className:`flex items-center gap-2`,children:[u(`input`,{type:`text`,placeholder:`section-id`,value:r,onChange:e=>i(e.target.value),className:`w-40 rounded border p-2 font-mono text-sm`}),u(`input`,{type:`text`,placeholder:`Section Title`,value:a,onChange:e=>o(e.target.value),onKeyDown:e=>{e.key===`Enter`&&c()},className:`flex-1 rounded border p-2 text-sm`}),u(`button`,{className:`rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:opacity-50`,disabled:!r.trim()||!a.trim(),onClick:c,children:`Add`}),u(`button`,{className:`text-sm text-gray-500 hover:text-gray-700`,onClick:()=>{n(!1),i(``),o(``)},children:`Cancel`})]})}):u(`button`,{className:`mt-3 rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600`,onClick:()=>n(!0),children:`+ Add Profile`})]})}function oe(e){return d(l,{children:[d(`section`,{className:`my-6 rounded border border-dashed border-gray-300 bg-white p-8 text-center text-gray-500`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`Skill Templates`}),u(`p`,{className:`mt-2`,children:`Coming soon`})]}),u(`hr`,{}),u(Y,{skills:e.skills,addSkill:e.addSkill,removeSkill:e.removeSkill})]})}function Y(e){let[t,n]=g(``),[r,i]=g(``),a=()=>{t.trim()&&r.trim()&&(e.addSkill(t.trim(),r.trim()),n(``),i(``))};return d(`section`,{className:`my-6`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`External Skills`}),u(`p`,{className:`text-sm text-gray-600`,children:`Skills from the skills.sh ecosystem, installed via GitHub URL.`}),e.skills.length>0&&u(`ul`,{className:`mt-3 space-y-2`,children:e.skills.map(t=>d(`li`,{className:`flex items-center justify-between rounded border border-gray-200 bg-white p-3`,children:[d(`div`,{children:[u(`span`,{className:`font-mono font-semibold`,children:t.name}),u(`span`,{className:`ml-2 text-sm text-gray-500`,children:t.githubUrl})]}),u(`button`,{className:`text-sm text-red-500 hover:text-red-700`,onClick:()=>e.removeSkill(t.id),children:`Remove`})]},t.id))}),d(`div`,{className:`mt-3 flex items-center gap-2`,children:[u(`input`,{type:`text`,placeholder:`skill-name`,value:t,onChange:e=>n(e.target.value),className:`w-40 rounded border p-2 font-mono text-sm`}),u(`input`,{type:`text`,placeholder:`https://github.com/org/repo`,value:r,onChange:e=>i(e.target.value),onKeyDown:e=>{e.key===`Enter`&&a()},className:`flex-1 rounded border p-2 font-mono text-sm`}),u(`button`,{className:`rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:opacity-50`,disabled:!t.trim()||!r.trim(),onClick:a,children:`Add Skill`})]})]})}function se(e){return e.isAboveDisabled?u(Z,{packages:e.packages,addPackage:e.addPackage,removePackage:e.removePackage,addDocType:e.addDocType,removeDocType:e.removeDocType}):d(`section`,{className:`my-6 rounded border border-dashed border-gray-300 bg-white p-8 text-center text-gray-500`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`Powerhouse`}),u(`p`,{className:`mt-2`,children:`Enable Powerhouse in the CLI tab (set level to Reactor or above) to manage packages.`})]})}function ce(e){let t=e.publishHistory.slice(-5).reverse(),n=F(e.version);return d(l,{children:[d(`section`,{className:`my-6`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`Publishing`}),d(`div`,{className:`my-3 rounded border border-gray-200 bg-white p-4`,children:[d(`div`,{className:`flex items-center gap-4`,children:[u(`span`,{className:`text-sm text-gray-600`,children:`Current version:`}),u(`span`,{className:`font-mono font-semibold`,children:e.version})]}),d(`div`,{className:`mt-3 flex items-center gap-2`,children:[u(`span`,{className:`text-sm text-gray-600`,children:`Bump version to:`}),u(`input`,{type:`text`,placeholder:n,onKeyDown:t=>{if(t.key===`Enter`){let n=t.currentTarget.value.trim();n&&e.bumpVersion(n),t.currentTarget.value=``}},className:`rounded border p-1 font-mono text-sm`})]}),d(`div`,{className:`mt-4 flex items-center gap-2`,children:[u(`button`,{className:`rounded bg-gray-600 px-3 py-2 text-sm text-white hover:bg-gray-700`,onClick:e.publishDev,children:`Publish Dev`}),u(`button`,{className:`rounded bg-amber-600 px-3 py-2 text-sm text-white hover:bg-amber-700`,onClick:e.publishStaging,children:`Publish Staging`}),u(`button`,{className:`rounded bg-green-600 px-3 py-2 text-sm text-white hover:bg-green-700`,onClick:e.publishProduction,children:`Publish Production`})]})]}),t.length>0&&d(`div`,{className:`mt-3`,children:[u(`h4`,{className:`text-sm font-semibold text-gray-600`,children:`Recent publish history`}),u(`ul`,{className:`mt-2 space-y-1`,children:t.map(e=>d(`li`,{className:`flex items-center gap-3 text-sm`,children:[u($,{status:e.status}),u(`span`,{className:`font-mono`,children:e.version}),u(`span`,{className:`text-gray-500`,children:e.tag}),u(`span`,{className:`text-gray-400`,children:e.timestamp})]},e.id))})]})]}),u(`hr`,{}),u(X,{deployment:e.deployment,setProxyEnabled:e.setProxyEnabled,setObservabilityEnabled:e.setObservabilityEnabled,addSupportedResource:e.addSupportedResource,removeSupportedResource:e.removeSupportedResource}),u(`hr`,{}),d(`section`,{className:`my-6`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`Document`}),d(`div`,{className:`my-3 rounded border border-gray-200 bg-white p-4`,children:[d(`p`,{className:`text-sm text-gray-600`,children:[`Document ID: `,u(`span`,{className:`font-mono`,children:e.documentHeader.id})]}),d(`p`,{className:`text-sm text-gray-600`,children:[`Type: `,u(`span`,{className:`font-mono`,children:e.documentHeader.documentType})]})]})]})]})}function X(e){let[t,n]=g(``);return d(`section`,{className:`my-6`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`Deployment`}),d(`div`,{className:`my-3 rounded border border-gray-200 bg-white p-4`,children:[u(L,{label:`Proxy enabled`,checked:e.deployment.proxyEnabled,onChange:e.setProxyEnabled,hint:`Embedded reverse proxy`}),u(L,{label:`Observability enabled`,checked:e.deployment.observabilityEnabled,onChange:e.setObservabilityEnabled,hint:`Sentry + OpenTelemetry`})]}),d(`div`,{className:`my-3 rounded border border-gray-200 bg-white p-4`,children:[u(`h4`,{className:`text-base font-semibold`,children:`Supported resources`}),u(`ul`,{className:`my-2 space-y-1`,children:e.deployment.supportedResources.map(t=>d(`li`,{className:`flex items-center justify-between text-sm`,children:[u(`span`,{className:`font-mono`,children:t}),u(`button`,{className:`text-red-500 hover:text-red-700`,onClick:()=>e.removeSupportedResource(t),children:`Remove`})]},t))}),d(`div`,{className:`mt-2 flex items-center gap-2`,children:[u(`input`,{type:`text`,placeholder:`vetra-agent-...`,value:t,onChange:e=>n(e.target.value),onKeyDown:r=>{r.key===`Enter`&&t.trim()&&(e.addSupportedResource(t.trim()),n(``))},className:`flex-1 rounded border p-1 font-mono text-sm`}),u(`button`,{className:`rounded bg-blue-500 px-2 py-1 text-xs text-white hover:bg-blue-600 disabled:opacity-50`,disabled:!t.trim(),onClick:()=>{e.addSupportedResource(t.trim()),n(``)},children:`Add`})]})]})]})}function Z(e){let[t,n]=g(``);return d(`section`,{className:`my-6`,children:[u(`h3`,{className:`text-lg font-semibold`,children:`Reactor Packages`}),e.packages.map(t=>u(Q,{pkg:t,addDocType:e.addDocType,removeDocType:e.removeDocType,removePackage:e.removePackage},t.id)),d(`div`,{className:`my-3 flex items-center gap-2`,children:[u(`input`,{type:`text`,placeholder:`@scope/package-name`,value:t,onChange:e=>n(e.target.value),onKeyDown:r=>{r.key===`Enter`&&t.trim()&&(e.addPackage(t.trim()),n(``))},className:`flex-1 rounded border p-2 font-mono text-sm`}),u(`button`,{className:`rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:opacity-50`,disabled:!t.trim(),onClick:()=>{e.addPackage(t.trim()),n(``)},children:`Add Package`})]})]})}function Q(e){let[t,n]=g(``);return d(`div`,{className:`my-3 rounded border border-gray-200 bg-white p-4`,children:[d(`div`,{className:`flex items-center justify-between`,children:[d(`div`,{children:[u(`span`,{className:`font-mono font-semibold`,children:e.pkg.packageName}),e.pkg.managed&&u(`span`,{className:`ml-2 rounded bg-blue-100 px-2 py-0.5 text-xs text-blue-700`,children:`managed`}),e.pkg.version&&d(`span`,{className:`ml-2 text-sm text-gray-500`,children:[`v`,e.pkg.version]})]}),!e.pkg.managed&&u(`button`,{className:`text-sm text-red-500 hover:text-red-700`,onClick:()=>e.removePackage(e.pkg.id),children:`Remove Package`})]}),u(`ul`,{className:`my-2 space-y-1`,children:e.pkg.documentTypes.map(t=>d(`li`,{className:`flex items-center justify-between text-sm`,children:[u(`span`,{className:`font-mono`,children:t}),u(`button`,{className:`text-red-500 hover:text-red-700`,onClick:()=>e.removeDocType(e.pkg.id,t),children:`×`})]},t))}),d(`div`,{className:`mt-2 flex items-center gap-2`,children:[u(`input`,{type:`text`,placeholder:`org/doc-type or */*`,value:t,onChange:e=>n(e.target.value),onKeyDown:r=>{r.key===`Enter`&&t.trim()&&(e.addDocType(e.pkg.id,t.trim()),n(``))},className:`flex-1 rounded border p-1 font-mono text-sm`}),u(`button`,{className:`rounded bg-blue-500 px-2 py-1 text-xs text-white hover:bg-blue-600 disabled:opacity-50`,disabled:!t.trim(),onClick:()=>{e.addDocType(e.pkg.id,t.trim()),n(``)},children:`Add Doc Type`})]})]})}function $(e){return u(`span`,{className:`rounded px-2 py-0.5 text-xs ${e.status===`Succeeded`?`bg-green-100 text-green-700`:e.status===`Failed`?`bg-red-100 text-red-700`:e.status===`InProgress`?`bg-amber-100 text-amber-700`:`bg-gray-100 text-gray-700`}`,children:e.status})}export{R as default};
|
|
2
|
-
//# sourceMappingURL=editor-BrPMvNFl.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor-BrPMvNFl.js","names":[],"sources":["../../../../../node_modules/.pnpm/@powerhousedao+reactor-attachments@6.0.0-dev.257_@emnapi+core@1.10.0_@emnapi+runtime@1._ac8ae047337833ca71dd21474a1e3e5f/node_modules/@powerhousedao/reactor-attachments/dist/index.js","../../../editors/ph-clint-project-editor/editor.tsx"],"sourcesContent":["import { dirname, join } from \"node:path\";\nimport { Migrator, sql } from \"kysely\";\nimport { mkdir, rename, rm } from \"node:fs/promises\";\nimport { createReadStream, createWriteStream } from \"node:fs\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { Readable } from \"node:stream\";\n//#region \\0rolldown/runtime.js\nvar __defProp = Object.defineProperty;\nvar __exportAll = (all, no_symbols) => {\n\tlet target = {};\n\tfor (var name in all) __defProp(target, name, {\n\t\tget: all[name],\n\t\tenumerable: true\n\t});\n\tif (!no_symbols) __defProp(target, Symbol.toStringTag, { value: \"Module\" });\n\treturn target;\n};\n//#endregion\n//#region src/errors.ts\n/**\n* Thrown when an attachment ref or hash is not known to the store.\n*/\nvar AttachmentNotFound = class extends Error {\n\tconstructor(identifier) {\n\t\tsuper(`Attachment not found: ${identifier}`);\n\t\tthis.name = \"AttachmentNotFound\";\n\t}\n};\n/**\n* Thrown when a reservation ID is not found in the reservation store.\n*/\nvar ReservationNotFound = class extends Error {\n\tconstructor(reservationId) {\n\t\tsuper(`Reservation not found: ${reservationId}`);\n\t\tthis.name = \"ReservationNotFound\";\n\t}\n};\n/**\n* Thrown when an attachment ref string does not match the expected format.\n*/\nvar InvalidAttachmentRef = class extends Error {\n\tconstructor(ref) {\n\t\tsuper(`Invalid attachment ref: ${ref}`);\n\t\tthis.name = \"InvalidAttachmentRef\";\n\t}\n};\n/**\n* Thrown when an upload exceeds the configured maximum byte cap.\n* Route handlers should map this to HTTP 413 Payload Too Large.\n*/\nvar UploadTooLarge = class extends Error {\n\tmaxBytes;\n\tconstructor(maxBytes) {\n\t\tsuper(`Upload exceeds maximum size of ${maxBytes} bytes`);\n\t\tthis.name = \"UploadTooLarge\";\n\t\tthis.maxBytes = maxBytes;\n\t}\n};\n//#endregion\n//#region src/ref.ts\nconst REF_PATTERN = /^attachment:\\/\\/v(\\d+):(.+)$/;\nconst DEFAULT_VERSION = 1;\nfunction parseRef(ref) {\n\tconst match = REF_PATTERN.exec(ref);\n\tif (!match) throw new InvalidAttachmentRef(ref);\n\treturn {\n\t\tversion: Number(match[1]),\n\t\thash: match[2]\n\t};\n}\nfunction createRef(hash, version = DEFAULT_VERSION) {\n\treturn `attachment://v${version}:${hash}`;\n}\n//#endregion\n//#region src/attachment-service.ts\nvar AttachmentService = class {\n\tconstructor(store, reservations, uploadFactory) {\n\t\tthis.store = store;\n\t\tthis.reservations = reservations;\n\t\tthis.uploadFactory = uploadFactory;\n\t}\n\tasync reserve(options) {\n\t\tconst reservation = await this.reservations.create(options);\n\t\treturn this.uploadFactory.createUpload(reservation.reservationId, options);\n\t}\n\tasync stat(ref) {\n\t\tconst { hash } = parseRef(ref);\n\t\treturn this.store.stat(hash);\n\t}\n\tasync get(ref, signal) {\n\t\tconst { hash } = parseRef(ref);\n\t\treturn this.store.get(hash, signal);\n\t}\n};\n//#endregion\n//#region src/storage/fs/attachment-fs.ts\n/**\n* Compute the relative storage path for an attachment hash.\n* This is what gets stored in the database's storage_path column.\n*/\nfunction storageRelativePath(hash) {\n\treturn join(hash.slice(0, 2), hash.slice(2, 4), hash);\n}\n/**\n* Write a ReadableStream to disk. Creates parent directories as needed.\n* Returns the number of bytes written.\n*/\nasync function writeAttachmentBytes(path, data) {\n\tawait mkdir(dirname(path), { recursive: true });\n\tconst writer = createWriteStream(path);\n\tconst reader = data.getReader();\n\tlet bytesWritten = 0;\n\ttry {\n\t\tfor (;;) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tbytesWritten += value.byteLength;\n\t\t\tif (!writer.write(value)) await new Promise((resolve) => writer.once(\"drain\", resolve));\n\t\t}\n\t} finally {\n\t\treader.releaseLock();\n\t\tawait new Promise((resolve, reject) => {\n\t\t\twriter.end(() => resolve());\n\t\t\twriter.on(\"error\", reject);\n\t\t});\n\t}\n\treturn bytesWritten;\n}\n/**\n* Open a ReadableStream from a file on disk.\n*/\nfunction readAttachmentStream(path) {\n\tconst nodeStream = createReadStream(path);\n\treturn Readable.toWeb(nodeStream);\n}\n/**\n* Delete a file from disk. No-op if the file does not exist.\n*/\nasync function deleteAttachmentBytes(path) {\n\tawait rm(path, { force: true });\n}\n/**\n* Stream bytes to a temp file under `${basePath}/.tmp/` while computing the\n* SHA-256 hash, returning the temp path, hex hash, and total bytes written.\n*\n* Bytes are never buffered in memory beyond the current chunk. The caller is\n* responsible for renaming the temp file to its final hash-derived location\n* (or removing it if the content is a duplicate).\n*\n* If `maxBytes` is set and the input exceeds it, the temp file is removed and\n* `UploadTooLarge` is thrown.\n*/\nasync function streamHashAndWrite(basePath, data, options = {}) {\n\tconst { maxBytes } = options;\n\tconst tmpDir = join(basePath, \".tmp\");\n\tawait mkdir(tmpDir, { recursive: true });\n\tconst tempPath = join(tmpDir, randomUUID());\n\tconst hasher = createHash(\"sha256\");\n\tconst writer = createWriteStream(tempPath);\n\tconst reader = data.getReader();\n\tlet sizeBytes = 0;\n\tlet caughtError;\n\ttry {\n\t\tfor (;;) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tsizeBytes += value.byteLength;\n\t\t\tif (maxBytes !== void 0 && sizeBytes > maxBytes) throw new UploadTooLarge(maxBytes);\n\t\t\thasher.update(value);\n\t\t\tif (!writer.write(value)) await new Promise((resolve, reject) => {\n\t\t\t\tconst onDrain = () => {\n\t\t\t\t\twriter.off(\"error\", onError);\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t\tconst onError = (err) => {\n\t\t\t\t\twriter.off(\"drain\", onDrain);\n\t\t\t\t\treject(err);\n\t\t\t\t};\n\t\t\t\twriter.once(\"drain\", onDrain);\n\t\t\t\twriter.once(\"error\", onError);\n\t\t\t});\n\t\t}\n\t} catch (err) {\n\t\tcaughtError = err instanceof Error ? err : new Error(String(err));\n\t} finally {\n\t\treader.releaseLock();\n\t}\n\tawait new Promise((resolve, reject) => {\n\t\twriter.end((err) => {\n\t\t\tif (err) reject(err);\n\t\t\telse resolve();\n\t\t});\n\t\twriter.on(\"error\", reject);\n\t});\n\tif (caughtError) {\n\t\tawait rm(tempPath, { force: true });\n\t\tthrow caughtError;\n\t}\n\treturn {\n\t\ttempPath,\n\t\thash: hasher.digest(\"hex\"),\n\t\tsizeBytes\n\t};\n}\n//#endregion\n//#region src/storage/kysely/attachment-store.ts\nfunction rowToHeader$1(row) {\n\treturn {\n\t\thash: row.hash,\n\t\tmimeType: row.mime_type,\n\t\tfileName: row.file_name,\n\t\tsizeBytes: Number(row.size_bytes),\n\t\textension: row.extension,\n\t\tstatus: row.status,\n\t\tsource: row.source,\n\t\tcreatedAtUtc: row.created_at_utc,\n\t\tlastAccessedAtUtc: row.last_accessed_at_utc\n\t};\n}\nfunction wrapStreamWithCleanup(source, cleanup) {\n\tlet cleaned = false;\n\tconst doCleanup = () => {\n\t\tif (!cleaned) {\n\t\t\tcleaned = true;\n\t\t\tcleanup();\n\t\t}\n\t};\n\tconst reader = source.getReader();\n\treturn new ReadableStream({\n\t\tasync pull(controller) {\n\t\t\ttry {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) {\n\t\t\t\t\tdoCleanup();\n\t\t\t\t\tcontroller.close();\n\t\t\t\t} else controller.enqueue(value);\n\t\t\t} catch (err) {\n\t\t\t\tdoCleanup();\n\t\t\t\tcontroller.error(err);\n\t\t\t}\n\t\t},\n\t\tcancel() {\n\t\t\tdoCleanup();\n\t\t\treader.cancel().catch(() => {});\n\t\t}\n\t});\n}\nvar KyselyAttachmentStore = class {\n\tactiveReaders = /* @__PURE__ */ new Map();\n\tconstructor(db, transport, basePath) {\n\t\tthis.db = db;\n\t\tthis.transport = transport;\n\t\tthis.basePath = basePath;\n\t}\n\tasync stat(hash) {\n\t\tconst row = await this.db.selectFrom(\"attachment\").selectAll().where(\"hash\", \"=\", hash).executeTakeFirst();\n\t\tif (!row) throw new AttachmentNotFound(hash);\n\t\treturn rowToHeader$1(row);\n\t}\n\tasync has(hash) {\n\t\treturn (await this.db.selectFrom(\"attachment\").select(\"status\").where(\"hash\", \"=\", hash).executeTakeFirst())?.status === \"available\";\n\t}\n\tasync get(hash, signal) {\n\t\tconst row = await this.db.selectFrom(\"attachment\").selectAll().where(\"hash\", \"=\", hash).executeTakeFirst();\n\t\tif (!row) throw new AttachmentNotFound(hash);\n\t\tif (row.status === \"evicted\") {\n\t\t\tconst remote = await this.transport.fetch(hash, signal);\n\t\t\tif (!remote) throw new AttachmentNotFound(hash);\n\t\t\tawait this.put(hash, remote.metadata, remote.body);\n\t\t\treturn this.get(hash, signal);\n\t\t}\n\t\tconst now = (/* @__PURE__ */ new Date()).toISOString();\n\t\tawait this.db.updateTable(\"attachment\").set({ last_accessed_at_utc: now }).where(\"hash\", \"=\", hash).execute();\n\t\tconst header = rowToHeader$1(row);\n\t\theader.lastAccessedAtUtc = now;\n\t\tthis.acquireReader(hash);\n\t\treturn {\n\t\t\theader,\n\t\t\tbody: wrapStreamWithCleanup(readAttachmentStream(join(this.basePath, row.storage_path)), () => this.releaseReader(hash))\n\t\t};\n\t}\n\tasync put(hash, metadata, data) {\n\t\tconst existing = await this.db.selectFrom(\"attachment\").select([\"hash\", \"status\"]).where(\"hash\", \"=\", hash).executeTakeFirst();\n\t\tif (existing?.status === \"available\") {\n\t\t\tawait data.cancel();\n\t\t\treturn;\n\t\t}\n\t\tconst relPath = storageRelativePath(hash);\n\t\tawait writeAttachmentBytes(join(this.basePath, relPath), data);\n\t\tconst now = (/* @__PURE__ */ new Date()).toISOString();\n\t\tif (!existing) await this.db.insertInto(\"attachment\").values({\n\t\t\thash,\n\t\t\tmime_type: metadata.mimeType,\n\t\t\tfile_name: metadata.fileName,\n\t\t\tsize_bytes: metadata.sizeBytes,\n\t\t\textension: metadata.extension ?? null,\n\t\t\tstatus: \"available\",\n\t\t\tstorage_path: relPath,\n\t\t\tsource: \"sync\",\n\t\t\tcreated_at_utc: metadata.createdAtUtc,\n\t\t\tlast_accessed_at_utc: now\n\t\t}).onConflict((oc) => oc.column(\"hash\").doNothing()).execute();\n\t\telse await this.db.updateTable(\"attachment\").set({\n\t\t\tstatus: \"available\",\n\t\t\tstorage_path: relPath,\n\t\t\tlast_accessed_at_utc: now\n\t\t}).where(\"hash\", \"=\", hash).where(\"status\", \"=\", \"evicted\").execute();\n\t}\n\tasync evict(hash) {\n\t\tif (this.hasActiveReaders(hash)) return;\n\t\tconst row = await this.db.selectFrom(\"attachment\").select([\"storage_path\", \"status\"]).where(\"hash\", \"=\", hash).executeTakeFirst();\n\t\tif (!row || row.status === \"evicted\") return;\n\t\tawait deleteAttachmentBytes(join(this.basePath, row.storage_path));\n\t\tawait this.db.updateTable(\"attachment\").set({ status: \"evicted\" }).where(\"hash\", \"=\", hash).execute();\n\t}\n\tasync storageUsed() {\n\t\tconst result = await this.db.selectFrom(\"attachment\").select(sql`COALESCE(SUM(size_bytes), 0)`.as(\"total\")).where(\"status\", \"=\", \"available\").executeTakeFirst();\n\t\treturn Number(result?.total ?? 0);\n\t}\n\tacquireReader(hash) {\n\t\tthis.activeReaders.set(hash, (this.activeReaders.get(hash) ?? 0) + 1);\n\t}\n\treleaseReader(hash) {\n\t\tconst count = (this.activeReaders.get(hash) ?? 1) - 1;\n\t\tif (count <= 0) this.activeReaders.delete(hash);\n\t\telse this.activeReaders.set(hash, count);\n\t}\n\thasActiveReaders(hash) {\n\t\treturn (this.activeReaders.get(hash) ?? 0) > 0;\n\t}\n};\n//#endregion\n//#region src/storage/kysely/reservation-store.ts\nconst DEFAULT_RESERVATION_TTL_MS = 1440 * 60 * 1e3;\nfunction rowToReservation(row) {\n\treturn {\n\t\treservationId: row.reservation_id,\n\t\tmimeType: row.mime_type,\n\t\tfileName: row.file_name,\n\t\textension: row.extension,\n\t\tcreatedAtUtc: row.created_at_utc,\n\t\texpiresAtUtc: row.expires_at_utc\n\t};\n}\nvar KyselyReservationStore = class {\n\tttlMs;\n\tconstructor(db, ttlMs = DEFAULT_RESERVATION_TTL_MS) {\n\t\tthis.db = db;\n\t\tthis.ttlMs = ttlMs;\n\t}\n\tasync create(options) {\n\t\tconst reservationId = randomUUID();\n\t\tconst nowMs = Date.now();\n\t\tconst now = new Date(nowMs).toISOString();\n\t\tconst expiresAt = new Date(nowMs + this.ttlMs).toISOString();\n\t\treturn rowToReservation(await this.db.insertInto(\"attachment_reservation\").values({\n\t\t\treservation_id: reservationId,\n\t\t\tmime_type: options.mimeType,\n\t\t\tfile_name: options.fileName,\n\t\t\textension: options.extension ?? null,\n\t\t\tcreated_at_utc: now,\n\t\t\texpires_at_utc: expiresAt\n\t\t}).returningAll().executeTakeFirstOrThrow());\n\t}\n\tasync get(reservationId) {\n\t\tconst row = await this.db.selectFrom(\"attachment_reservation\").selectAll().where(\"reservation_id\", \"=\", reservationId).where(\"deleted_at_utc\", \"is\", null).executeTakeFirst();\n\t\tif (!row) throw new ReservationNotFound(reservationId);\n\t\treturn rowToReservation(row);\n\t}\n\tasync delete(reservationId) {\n\t\tawait this.db.updateTable(\"attachment_reservation\").set({ deleted_at_utc: (/* @__PURE__ */ new Date()).toISOString() }).where(\"reservation_id\", \"=\", reservationId).where(\"deleted_at_utc\", \"is\", null).execute();\n\t}\n\tasync deleteExpired(now = /* @__PURE__ */ new Date()) {\n\t\tconst nowIso = now.toISOString();\n\t\tconst result = await this.db.updateTable(\"attachment_reservation\").set({ deleted_at_utc: nowIso }).where(\"expires_at_utc\", \"<=\", nowIso).where(\"deleted_at_utc\", \"is\", null).executeTakeFirst();\n\t\treturn Number(result.numUpdatedRows);\n\t}\n};\n//#endregion\n//#region src/storage/migrations/001_create_attachment_table.ts\nvar _001_create_attachment_table_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$4,\n\tup: () => up$4\n});\nasync function up$4(db) {\n\tawait db.schema.createTable(\"attachment\").addColumn(\"hash\", \"text\", (col) => col.primaryKey()).addColumn(\"mime_type\", \"text\", (col) => col.notNull()).addColumn(\"file_name\", \"text\", (col) => col.notNull()).addColumn(\"size_bytes\", \"bigint\", (col) => col.notNull()).addColumn(\"extension\", \"text\").addColumn(\"status\", \"text\", (col) => col.notNull().defaultTo(\"available\")).addColumn(\"storage_path\", \"text\", (col) => col.notNull()).addColumn(\"source\", \"text\", (col) => col.notNull().defaultTo(\"local\")).addColumn(\"created_at_utc\", \"text\", (col) => col.notNull()).addColumn(\"last_accessed_at_utc\", \"text\", (col) => col.notNull()).execute();\n\tawait db.schema.createIndex(\"idx_attachment_status\").on(\"attachment\").column(\"status\").execute();\n\tawait db.schema.createIndex(\"idx_attachment_lru\").on(\"attachment\").columns([\"status\", \"last_accessed_at_utc\"]).execute();\n}\nasync function down$4(db) {\n\tawait db.schema.dropTable(\"attachment\").ifExists().execute();\n}\n//#endregion\n//#region src/storage/migrations/002_create_reservation_table.ts\nvar _002_create_reservation_table_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$3,\n\tup: () => up$3\n});\nasync function up$3(db) {\n\tawait db.schema.createTable(\"attachment_reservation\").addColumn(\"reservation_id\", \"text\", (col) => col.primaryKey()).addColumn(\"mime_type\", \"text\", (col) => col.notNull()).addColumn(\"file_name\", \"text\", (col) => col.notNull()).addColumn(\"extension\", \"text\").addColumn(\"created_at_utc\", \"text\", (col) => col.notNull()).execute();\n}\nasync function down$3(db) {\n\tawait db.schema.dropTable(\"attachment_reservation\").ifExists().execute();\n}\n//#endregion\n//#region src/storage/migrations/003_add_reservation_expires_at.ts\nvar _003_add_reservation_expires_at_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$2,\n\tup: () => up$2\n});\nasync function up$2(db) {\n\tawait db.schema.alterTable(\"attachment_reservation\").addColumn(\"expires_at_utc\", \"text\").execute();\n\tawait db.updateTable(\"attachment_reservation\").set({ expires_at_utc: sql`created_at_utc` }).where(\"expires_at_utc\", \"is\", null).execute();\n\tawait db.schema.alterTable(\"attachment_reservation\").alterColumn(\"expires_at_utc\", (col) => col.setNotNull()).execute();\n\tawait db.schema.createIndex(\"idx_reservation_expires_at\").on(\"attachment_reservation\").column(\"expires_at_utc\").execute();\n}\nasync function down$2(db) {\n\tawait db.schema.dropIndex(\"idx_reservation_expires_at\").ifExists().execute();\n\tawait db.schema.alterTable(\"attachment_reservation\").dropColumn(\"expires_at_utc\").execute();\n}\n//#endregion\n//#region src/storage/migrations/004_add_reservation_soft_delete.ts\nvar _004_add_reservation_soft_delete_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$1,\n\tup: () => up$1\n});\nasync function up$1(db) {\n\tawait db.schema.alterTable(\"attachment_reservation\").addColumn(\"deleted_at_utc\", \"text\").execute();\n}\nasync function down$1(db) {\n\tawait db.schema.alterTable(\"attachment_reservation\").dropColumn(\"deleted_at_utc\").execute();\n}\n//#endregion\n//#region src/storage/migrations/005_add_reservation_active_index.ts\nvar _005_add_reservation_active_index_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down,\n\tup: () => up\n});\nasync function up(db) {\n\tawait db.schema.dropIndex(\"idx_reservation_expires_at\").ifExists().execute();\n\tawait db.schema.createIndex(\"idx_reservation_expires_at_active\").on(\"attachment_reservation\").column(\"expires_at_utc\").where(sql`deleted_at_utc IS NULL`).execute();\n}\nasync function down(db) {\n\tawait db.schema.dropIndex(\"idx_reservation_expires_at_active\").ifExists().execute();\n\tawait db.schema.createIndex(\"idx_reservation_expires_at\").on(\"attachment_reservation\").column(\"expires_at_utc\").execute();\n}\n//#endregion\n//#region src/storage/migrations/migrator.ts\nconst ATTACHMENT_SCHEMA = \"attachments\";\nconst migrations = {\n\t\"001_create_attachment_table\": _001_create_attachment_table_exports,\n\t\"002_create_reservation_table\": _002_create_reservation_table_exports,\n\t\"003_add_reservation_expires_at\": _003_add_reservation_expires_at_exports,\n\t\"004_add_reservation_soft_delete\": _004_add_reservation_soft_delete_exports,\n\t\"005_add_reservation_active_index\": _005_add_reservation_active_index_exports\n};\nvar ProgrammaticMigrationProvider = class {\n\tgetMigrations() {\n\t\treturn Promise.resolve(migrations);\n\t}\n};\nasync function runAttachmentMigrations(db, schema = ATTACHMENT_SCHEMA) {\n\ttry {\n\t\tawait sql`CREATE SCHEMA IF NOT EXISTS ${sql.id(schema)}`.execute(db);\n\t} catch (error) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmigrationsExecuted: [],\n\t\t\terror: error instanceof Error ? error : /* @__PURE__ */ new Error(\"Failed to create schema\")\n\t\t};\n\t}\n\tconst migrator = new Migrator({\n\t\tdb: db.withSchema(schema),\n\t\tprovider: new ProgrammaticMigrationProvider(),\n\t\tmigrationTableSchema: schema\n\t});\n\tlet error;\n\tlet results;\n\ttry {\n\t\tconst result = await migrator.migrateToLatest();\n\t\terror = result.error;\n\t\tresults = result.results;\n\t} catch (e) {\n\t\terror = e;\n\t\tresults = [];\n\t}\n\tconst migrationsExecuted = results?.map((result) => result.migrationName) ?? [];\n\tif (error) return {\n\t\tsuccess: false,\n\t\tmigrationsExecuted,\n\t\terror: error instanceof Error ? error : /* @__PURE__ */ new Error(\"Unknown migration error\")\n\t};\n\treturn {\n\t\tsuccess: true,\n\t\tmigrationsExecuted\n\t};\n}\n//#endregion\n//#region src/direct/direct-attachment-upload.ts\nfunction rowToHeader(row) {\n\treturn {\n\t\thash: row.hash,\n\t\tmimeType: row.mime_type,\n\t\tfileName: row.file_name,\n\t\tsizeBytes: Number(row.size_bytes),\n\t\textension: row.extension,\n\t\tstatus: row.status,\n\t\tsource: row.source,\n\t\tcreatedAtUtc: row.created_at_utc,\n\t\tlastAccessedAtUtc: row.last_accessed_at_utc\n\t};\n}\nvar DirectAttachmentUpload = class {\n\treservationId;\n\tconstructor(reservationId, options, db, basePath, reservations, maxBytes) {\n\t\tthis.options = options;\n\t\tthis.db = db;\n\t\tthis.basePath = basePath;\n\t\tthis.reservations = reservations;\n\t\tthis.maxBytes = maxBytes;\n\t\tthis.reservationId = reservationId;\n\t}\n\tasync send(data) {\n\t\tconst { tempPath, hash, sizeBytes } = await streamHashAndWrite(this.basePath, data, { maxBytes: this.maxBytes });\n\t\ttry {\n\t\t\tconst existing = await this.db.selectFrom(\"attachment\").select([\"hash\", \"status\"]).where(\"hash\", \"=\", hash).executeTakeFirst();\n\t\t\tif (existing?.status === \"available\") await rm(tempPath, { force: true });\n\t\t\telse {\n\t\t\t\tconst relPath = storageRelativePath(hash);\n\t\t\t\tconst fullPath = join(this.basePath, relPath);\n\t\t\t\tawait mkdir(dirname(fullPath), { recursive: true });\n\t\t\t\tawait rename(tempPath, fullPath);\n\t\t\t\tconst now = (/* @__PURE__ */ new Date()).toISOString();\n\t\t\t\tif (!existing) await this.db.insertInto(\"attachment\").values({\n\t\t\t\t\thash,\n\t\t\t\t\tmime_type: this.options.mimeType,\n\t\t\t\t\tfile_name: this.options.fileName,\n\t\t\t\t\tsize_bytes: sizeBytes,\n\t\t\t\t\textension: this.options.extension ?? null,\n\t\t\t\t\tstatus: \"available\",\n\t\t\t\t\tstorage_path: relPath,\n\t\t\t\t\tsource: \"local\",\n\t\t\t\t\tcreated_at_utc: now,\n\t\t\t\t\tlast_accessed_at_utc: now\n\t\t\t\t}).onConflict((oc) => oc.column(\"hash\").doNothing()).execute();\n\t\t\t\telse await this.db.updateTable(\"attachment\").set({\n\t\t\t\t\tstatus: \"available\",\n\t\t\t\t\tstorage_path: relPath,\n\t\t\t\t\tsource: \"local\",\n\t\t\t\t\tlast_accessed_at_utc: now\n\t\t\t\t}).where(\"hash\", \"=\", hash).where(\"status\", \"=\", \"evicted\").execute();\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tawait rm(tempPath, { force: true });\n\t\t\tthrow err;\n\t\t}\n\t\tawait this.reservations.delete(this.reservationId);\n\t\tconst row = await this.db.selectFrom(\"attachment\").selectAll().where(\"hash\", \"=\", hash).executeTakeFirstOrThrow();\n\t\treturn {\n\t\t\thash,\n\t\t\tref: createRef(hash),\n\t\t\theader: rowToHeader(row)\n\t\t};\n\t}\n};\n//#endregion\n//#region src/direct/direct-attachment-upload-factory.ts\nvar DirectAttachmentUploadFactory = class {\n\tconstructor(db, basePath, reservations, maxBytes) {\n\t\tthis.db = db;\n\t\tthis.basePath = basePath;\n\t\tthis.reservations = reservations;\n\t\tthis.maxBytes = maxBytes;\n\t}\n\tcreateUpload(reservationId, options) {\n\t\treturn new DirectAttachmentUpload(reservationId, options, this.db, this.basePath, this.reservations, this.maxBytes);\n\t}\n};\n//#endregion\n//#region src/switchboard/build-auth-headers.ts\nasync function buildAuthHeaders(url, jwtHandler) {\n\tconst headers = {};\n\tif (jwtHandler) {\n\t\tconst token = await jwtHandler(url);\n\t\tif (token) headers[\"Authorization\"] = `Bearer ${token}`;\n\t}\n\treturn headers;\n}\n//#endregion\n//#region src/switchboard/switchboard-attachment-transport.ts\nvar SwitchboardAttachmentTransport = class {\n\tremoteUrl;\n\tjwtHandler;\n\tfetchFn;\n\tconstructor(config) {\n\t\tthis.remoteUrl = config.remoteUrl;\n\t\tthis.jwtHandler = config.jwtHandler;\n\t\tthis.fetchFn = config.fetchFn ?? globalThis.fetch;\n\t}\n\tasync fetch(hash, signal) {\n\t\tconst url = `${this.remoteUrl}/attachments/${hash}`;\n\t\tconst headers = await buildAuthHeaders(url, this.jwtHandler);\n\t\tconst response = await this.fetchFn(url, {\n\t\t\tsignal,\n\t\t\theaders\n\t\t});\n\t\tif (response.status === 404) return null;\n\t\tif (!response.ok) throw new Error(`Attachment fetch failed: ${response.status} ${response.statusText}`);\n\t\tconst metadata = this.parseMetadataHeaders(response);\n\t\tconst body = response.body;\n\t\tif (!body) throw new Error(\"Response body is null\");\n\t\treturn {\n\t\t\thash,\n\t\t\tmetadata,\n\t\t\tbody\n\t\t};\n\t}\n\tasync announce(_hash) {}\n\tasync push(hash, remote, data) {\n\t\tconst url = `${remote}/attachments/${hash}`;\n\t\tconst headers = await buildAuthHeaders(url, this.jwtHandler);\n\t\tconst response = await this.fetchFn(url, {\n\t\t\tmethod: \"PUT\",\n\t\t\tbody: data,\n\t\t\theaders,\n\t\t\tduplex: \"half\"\n\t\t});\n\t\tif (!response.ok) throw new Error(`Attachment push failed: ${response.status} ${response.statusText}`);\n\t}\n\tparseMetadataHeaders(response) {\n\t\tlet fallbackCache;\n\t\tconst fallback = () => {\n\t\t\tif (fallbackCache === void 0) fallbackCache = contentTypeFallback$1(response);\n\t\t\treturn fallbackCache;\n\t\t};\n\t\tconst metaHeader = response.headers.get(\"Attachment-Metadata\");\n\t\tif (metaHeader) try {\n\t\t\tconst parsed = JSON.parse(metaHeader);\n\t\t\tif (isRecord$2(parsed)) {\n\t\t\t\tif (parsed.extension === void 0) parsed.extension = null;\n\t\t\t\tif (parsed.createdAtUtc === void 0) parsed.createdAtUtc = fallback().createdAtUtc;\n\t\t\t\tif (parsed.lastAccessedAtUtc === void 0) parsed.lastAccessedAtUtc = fallback().lastAccessedAtUtc;\n\t\t\t}\n\t\t\tif (isAttachmentMetadata$1(parsed)) return parsed;\n\t\t} catch {}\n\t\treturn fallback();\n\t}\n};\nfunction isRecord$2(value) {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\nfunction isAttachmentMetadata$1(value) {\n\tif (!isRecord$2(value)) return false;\n\tif (typeof value.mimeType !== \"string\") return false;\n\tif (typeof value.fileName !== \"string\") return false;\n\tif (typeof value.sizeBytes !== \"number\" || !Number.isFinite(value.sizeBytes) || value.sizeBytes < 0) return false;\n\tif (value.extension !== null && typeof value.extension !== \"string\") return false;\n\tif (typeof value.createdAtUtc !== \"string\") return false;\n\tif (value.lastAccessedAtUtc !== void 0 && typeof value.lastAccessedAtUtc !== \"string\") return false;\n\treturn true;\n}\nfunction contentTypeFallback$1(response) {\n\tconst contentLength = response.headers.get(\"Content-Length\");\n\tif (contentLength === null) throw new Error(\"Switchboard response missing both Attachment-Metadata and Content-Length headers\");\n\tconst sizeBytes = Number(contentLength);\n\tif (!Number.isInteger(sizeBytes) || sizeBytes < 0) throw new Error(`Switchboard response has invalid Content-Length header: ${JSON.stringify(contentLength)}`);\n\tconst lastModified = response.headers.get(\"Last-Modified\");\n\tconst dateHeader = response.headers.get(\"Date\");\n\tconst createdAtUtc = lastModified ? new Date(lastModified).toISOString() : dateHeader ? new Date(dateHeader).toISOString() : (/* @__PURE__ */ new Date()).toISOString();\n\treturn {\n\t\tmimeType: response.headers.get(\"Content-Type\") ?? \"application/octet-stream\",\n\t\tfileName: \"unknown\",\n\t\tsizeBytes,\n\t\textension: null,\n\t\tcreatedAtUtc,\n\t\tlastAccessedAtUtc: createdAtUtc\n\t};\n}\n//#endregion\n//#region src/switchboard/remote-reservation-store.ts\nfunction isRecord$1(value) {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\nfunction isReservation(value) {\n\tif (!isRecord$1(value)) return false;\n\tif (typeof value.reservationId !== \"string\") return false;\n\tif (typeof value.mimeType !== \"string\") return false;\n\tif (typeof value.fileName !== \"string\") return false;\n\tif (value.extension !== null && typeof value.extension !== \"string\") return false;\n\tif (typeof value.createdAtUtc !== \"string\") return false;\n\tif (typeof value.expiresAtUtc !== \"string\") return false;\n\treturn true;\n}\nvar RemoteReservationStore = class {\n\tremoteUrl;\n\tjwtHandler;\n\tfetchFn;\n\tconstructor(config) {\n\t\tthis.remoteUrl = config.remoteUrl;\n\t\tthis.jwtHandler = config.jwtHandler;\n\t\tthis.fetchFn = config.fetchFn ?? globalThis.fetch;\n\t}\n\tasync create(options) {\n\t\tconst url = `${this.remoteUrl}/attachments/reservations`;\n\t\tconst authHeaders = await buildAuthHeaders(url, this.jwtHandler);\n\t\tconst response = await this.fetchFn(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t...authHeaders,\n\t\t\t\t\"Content-Type\": \"application/json\"\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tmimeType: options.mimeType,\n\t\t\t\tfileName: options.fileName,\n\t\t\t\textension: options.extension ?? null\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) throw new Error(`Reservation create failed: ${response.status} ${response.statusText}`);\n\t\tconst json = await response.json();\n\t\tconst now = /* @__PURE__ */ new Date();\n\t\treturn {\n\t\t\treservationId: json.reservationId,\n\t\t\tmimeType: options.mimeType,\n\t\t\tfileName: options.fileName,\n\t\t\textension: options.extension ?? null,\n\t\t\tcreatedAtUtc: json.createdAtUtc ?? now.toISOString(),\n\t\t\texpiresAtUtc: json.expiresAtUtc ?? new Date(now.getTime() + 1440 * 60 * 1e3).toISOString()\n\t\t};\n\t}\n\tasync get(reservationId) {\n\t\tconst url = `${this.remoteUrl}/attachments/reservations/${encodeURIComponent(reservationId)}`;\n\t\tconst authHeaders = await buildAuthHeaders(url, this.jwtHandler);\n\t\tconst response = await this.fetchFn(url, { headers: authHeaders });\n\t\tif (response.status === 404) throw new ReservationNotFound(reservationId);\n\t\tif (!response.ok) throw new Error(`Reservation get failed: ${response.status} ${response.statusText}`);\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = await response.json();\n\t\t} catch {\n\t\t\tthrow new Error(\"Reservation get returned non-JSON response\");\n\t\t}\n\t\tif (!isReservation(parsed)) throw new Error(\"Reservation get returned a payload that does not match the Reservation shape\");\n\t\treturn parsed;\n\t}\n\tasync delete(reservationId) {\n\t\tconst url = `${this.remoteUrl}/attachments/reservations/${encodeURIComponent(reservationId)}`;\n\t\tconst authHeaders = await buildAuthHeaders(url, this.jwtHandler);\n\t\tconst response = await this.fetchFn(url, {\n\t\t\tmethod: \"DELETE\",\n\t\t\theaders: authHeaders\n\t\t});\n\t\tif (!response.ok && response.status !== 404 && response.status !== 410) throw new Error(`Reservation delete failed: ${response.status} ${response.statusText}`);\n\t}\n\tdeleteExpired() {\n\t\treturn Promise.reject(/* @__PURE__ */ new Error(\"RemoteReservationStore.deleteExpired is not supported\"));\n\t}\n};\n//#endregion\n//#region src/switchboard/remote-attachment-upload.ts\nvar RemoteAttachmentUpload = class {\n\treservationId;\n\tremoteUrl;\n\tjwtHandler;\n\tfetchFn;\n\toptions;\n\tconstructor(reservationId, options, config) {\n\t\tthis.reservationId = reservationId;\n\t\tthis.options = options;\n\t\tthis.remoteUrl = config.remoteUrl;\n\t\tthis.jwtHandler = config.jwtHandler;\n\t\tthis.fetchFn = config.fetchFn ?? globalThis.fetch;\n\t}\n\tasync send(data) {\n\t\tconst url = `${this.remoteUrl}/attachments/reservations/${this.reservationId}`;\n\t\tconst authHeaders = await buildAuthHeaders(url, this.jwtHandler);\n\t\tconst response = await this.fetchFn(url, {\n\t\t\tmethod: \"PUT\",\n\t\t\theaders: {\n\t\t\t\t...authHeaders,\n\t\t\t\t\"Content-Type\": \"application/octet-stream\"\n\t\t\t},\n\t\t\tbody: data,\n\t\t\tduplex: \"half\"\n\t\t});\n\t\tif (!response.ok) throw new Error(`Attachment upload failed: ${response.status} ${response.statusText}`);\n\t\treturn await response.json();\n\t}\n};\n//#endregion\n//#region src/switchboard/remote-attachment-upload-factory.ts\nvar RemoteAttachmentUploadFactory = class {\n\tconstructor(config) {\n\t\tthis.config = config;\n\t}\n\tcreateUpload(reservationId, options) {\n\t\treturn new RemoteAttachmentUpload(reservationId, options, this.config);\n\t}\n};\n//#endregion\n//#region src/switchboard/remote-attachment-store.ts\nfunction isRecord(value) {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\nfunction isAttachmentMetadata(value) {\n\tif (!isRecord(value)) return false;\n\tif (typeof value.mimeType !== \"string\") return false;\n\tif (typeof value.fileName !== \"string\") return false;\n\tif (typeof value.sizeBytes !== \"number\" || !Number.isFinite(value.sizeBytes) || value.sizeBytes < 0) return false;\n\tif (value.extension !== null && typeof value.extension !== \"string\") return false;\n\tif (typeof value.createdAtUtc !== \"string\") return false;\n\tif (value.lastAccessedAtUtc !== void 0 && typeof value.lastAccessedAtUtc !== \"string\") return false;\n\treturn true;\n}\nfunction contentTypeFallback(response) {\n\tconst contentLength = response.headers.get(\"Content-Length\");\n\tif (contentLength === null) throw new Error(\"Switchboard response missing both Attachment-Metadata and Content-Length headers\");\n\tconst sizeBytes = Number(contentLength);\n\tif (!Number.isInteger(sizeBytes) || sizeBytes < 0) throw new Error(`Switchboard response has invalid Content-Length header: ${JSON.stringify(contentLength)}`);\n\tconst lastModified = response.headers.get(\"Last-Modified\");\n\tconst dateHeader = response.headers.get(\"Date\");\n\tconst createdAtUtc = lastModified ? new Date(lastModified).toISOString() : dateHeader ? new Date(dateHeader).toISOString() : (/* @__PURE__ */ new Date()).toISOString();\n\treturn {\n\t\tmimeType: response.headers.get(\"Content-Type\") ?? \"application/octet-stream\",\n\t\tfileName: \"unknown\",\n\t\tsizeBytes,\n\t\textension: null,\n\t\tcreatedAtUtc,\n\t\tlastAccessedAtUtc: createdAtUtc\n\t};\n}\nfunction parseMetadata(response) {\n\tlet fallbackCache;\n\tconst fallback = () => {\n\t\tif (fallbackCache === void 0) fallbackCache = contentTypeFallback(response);\n\t\treturn fallbackCache;\n\t};\n\tconst metaHeader = response.headers.get(\"Attachment-Metadata\");\n\tif (metaHeader) try {\n\t\tconst parsed = JSON.parse(metaHeader);\n\t\tif (isRecord(parsed)) {\n\t\t\tif (parsed.extension === void 0) parsed.extension = null;\n\t\t\tif (parsed.createdAtUtc === void 0) parsed.createdAtUtc = fallback().createdAtUtc;\n\t\t\tif (parsed.lastAccessedAtUtc === void 0) parsed.lastAccessedAtUtc = fallback().lastAccessedAtUtc;\n\t\t}\n\t\tif (isAttachmentMetadata(parsed)) return parsed;\n\t} catch {}\n\treturn fallback();\n}\nvar RemoteAttachmentStore = class {\n\tremoteUrl;\n\tjwtHandler;\n\tfetchFn;\n\tconstructor(config) {\n\t\tthis.remoteUrl = config.remoteUrl;\n\t\tthis.jwtHandler = config.jwtHandler;\n\t\tthis.fetchFn = config.fetchFn ?? globalThis.fetch;\n\t}\n\tasync stat(hash) {\n\t\tconst url = `${this.remoteUrl}/attachments/${hash}`;\n\t\tconst authHeaders = await buildAuthHeaders(url, this.jwtHandler);\n\t\tconst response = await this.fetchFn(url, {\n\t\t\tmethod: \"HEAD\",\n\t\t\theaders: authHeaders\n\t\t});\n\t\tif (response.status === 404) throw new AttachmentNotFound(hash);\n\t\tif (!response.ok) throw new Error(`Attachment stat failed: ${response.status} ${response.statusText}`);\n\t\treturn buildHeader(hash, parseMetadata(response));\n\t}\n\tasync get(hash, signal) {\n\t\treturn this.fetchAttachment(hash, signal);\n\t}\n\tasync fetchAttachment(hash, signal) {\n\t\tconst url = `${this.remoteUrl}/attachments/${hash}`;\n\t\tconst headers = await buildAuthHeaders(url, this.jwtHandler);\n\t\tconst response = await this.fetchFn(url, {\n\t\t\tsignal,\n\t\t\theaders\n\t\t});\n\t\tif (response.status === 404) throw new AttachmentNotFound(hash);\n\t\tif (!response.ok) throw new Error(`Attachment fetch failed: ${response.status} ${response.statusText}`);\n\t\tif (!response.body) throw new Error(\"Response body is null\");\n\t\treturn {\n\t\t\theader: buildHeader(hash, parseMetadata(response)),\n\t\t\tbody: response.body\n\t\t};\n\t}\n};\nfunction buildHeader(hash, metadata) {\n\treturn {\n\t\thash,\n\t\tmimeType: metadata.mimeType,\n\t\tfileName: metadata.fileName,\n\t\tsizeBytes: metadata.sizeBytes,\n\t\textension: metadata.extension,\n\t\tstatus: \"available\",\n\t\tsource: \"sync\",\n\t\tcreatedAtUtc: metadata.createdAtUtc,\n\t\tlastAccessedAtUtc: metadata.lastAccessedAtUtc ?? metadata.createdAtUtc\n\t};\n}\n//#endregion\n//#region src/switchboard/create-remote-attachment-service.ts\nfunction createRemoteAttachmentService(config) {\n\tconst reservations = new RemoteReservationStore(config);\n\tconst uploadFactory = new RemoteAttachmentUploadFactory(config);\n\treturn new AttachmentService(new RemoteAttachmentStore(config), reservations, uploadFactory);\n}\n//#endregion\n//#region src/null-attachment-transport.ts\n/**\n* No-op transport for deployments without remote sync.\n* fetch() always returns null, announce() and push() are no-ops.\n*/\nvar NullAttachmentTransport = class {\n\tfetch() {\n\t\treturn Promise.resolve(null);\n\t}\n\tannounce() {\n\t\treturn Promise.resolve();\n\t}\n\tpush() {\n\t\treturn Promise.resolve();\n\t}\n};\n//#endregion\n//#region src/attachment-builder.ts\nvar AttachmentBuilder = class {\n\ttransport = new NullAttachmentTransport();\n\tcustomUploadFactory;\n\tmaxUploadBytes;\n\tconstructor(db, storagePath) {\n\t\tthis.db = db;\n\t\tthis.storagePath = storagePath;\n\t}\n\twithTransport(transport) {\n\t\tthis.transport = transport;\n\t\treturn this;\n\t}\n\twithUploadFactory(factory) {\n\t\tthis.customUploadFactory = factory;\n\t\treturn this;\n\t}\n\twithMaxUploadBytes(maxBytes) {\n\t\tthis.maxUploadBytes = maxBytes;\n\t\treturn this;\n\t}\n\tasync build() {\n\t\tconst result = await runAttachmentMigrations(this.db, ATTACHMENT_SCHEMA);\n\t\tif (!result.success && result.error) throw result.error;\n\t\tconst scopedDb = this.db.withSchema(ATTACHMENT_SCHEMA);\n\t\tconst store = new KyselyAttachmentStore(scopedDb, this.transport, this.storagePath);\n\t\tconst reservations = new KyselyReservationStore(scopedDb);\n\t\tconst uploadFactory = this.customUploadFactory ?? new DirectAttachmentUploadFactory(scopedDb, this.storagePath, reservations, this.maxUploadBytes);\n\t\treturn {\n\t\t\tservice: new AttachmentService(store, reservations, uploadFactory),\n\t\t\tstore,\n\t\t\treservations,\n\t\t\tuploadFactory\n\t\t};\n\t}\n};\n//#endregion\nexport { ATTACHMENT_SCHEMA, AttachmentBuilder, AttachmentNotFound, AttachmentService, DirectAttachmentUpload, DirectAttachmentUploadFactory, InvalidAttachmentRef, KyselyAttachmentStore, KyselyReservationStore, NullAttachmentTransport, RemoteAttachmentStore, RemoteAttachmentUpload, RemoteAttachmentUploadFactory, RemoteReservationStore, ReservationNotFound, SwitchboardAttachmentTransport, createRef, createRemoteAttachmentService, parseRef, runAttachmentMigrations };\n\n//# sourceMappingURL=index.js.map","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { generateId } from 'document-model';\nimport { DocumentToolbar } from '@powerhousedao/design-system/connect';\nimport { createRemoteAttachmentService, type IAttachmentService } from '@powerhousedao/reactor-attachments';\nimport { DEFAULT_SWITCHBOARD_URL, getSwitchboardGatewayUrlFromDriveUrl, useSelectedDrive, usePHToast } from '@powerhousedao/reactor-browser';\nimport { useSelectedPhClintProjectDocument, actions } from 'document-models/ph-clint-project';\nimport type {\n PowerhouseLevel,\n PowerhousePackage,\n ExternalSkill,\n PublishRecord,\n PhClintProjectState,\n PhClintMastraFeature,\n PhClintMainAgent,\n PhClintSubAgent,\n PhClintAgentModel,\n PhClintAgentProfile,\n PhClintDeployment,\n} from '../../document-models/ph-clint-project/v1/gen/types.js';\n\nconst POWERHOUSE_LEVELS: { value: PowerhouseLevel; description: string }[] = [\n { value: 'Disabled', description: 'No Powerhouse integration' },\n { value: 'Reactor', description: 'Document model runtime' },\n { value: 'Switchboard', description: 'API service (GraphQL + MCP)' },\n { value: 'Connect', description: 'Web UI for document management' },\n];\n\n/** Patch-bump a semver-ish version string: 0.0.1 → 0.0.2. Falls back to \"<version>.1\" when unparseable. */\nfunction bumpPatch(version: string): string {\n const m = /^(\\d+)\\.(\\d+)\\.(\\d+)/.exec(version);\n if (!m) return `${version}.1`;\n const [, major, minor, patch] = m;\n return `${major}.${minor}.${Number(patch) + 1}`;\n}\n\nfunction TextField(props: { label: string; value: string; placeholder?: string; readOnly?: boolean; compact?: boolean; onCommit: (value: string) => void }) {\n return (\n <label className={props.compact ? 'my-1 block' : 'my-3 block'}>\n <h3 className={props.compact ? 'text-xs text-gray-600' : 'text-base'}>{props.label}</h3>\n <input\n type=\"text\"\n defaultValue={props.value}\n placeholder={props.placeholder}\n readOnly={props.readOnly}\n onBlur={(e) => {\n const next = e.target.value.trim();\n if (next !== props.value) props.onCommit(next);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') e.currentTarget.blur();\n }}\n className=\"w-full font-mono\"\n />\n </label>\n );\n}\n\nfunction Toggle(props: { label: string; checked: boolean; disabled?: boolean; hint?: string; onChange: (next: boolean) => void }) {\n return (\n <label className=\"my-2 flex items-center gap-3\">\n <input type=\"checkbox\" checked={props.checked} disabled={props.disabled} onChange={(e) => props.onChange(e.target.checked)} />\n <span className=\"font-semibold\">{props.label}</span>\n {props.hint ? <span className=\"text-sm text-gray-600\">{props.hint}</span> : null}\n </label>\n );\n}\n\ntype Tab = 'cli' | 'agents' | 'profiles' | 'skills' | 'powerhouse' | 'publish';\n\nconst TAB_LABELS: { value: Tab; label: string }[] = [\n { value: 'cli', label: 'CLI' },\n { value: 'agents', label: 'Agents' },\n { value: 'profiles', label: 'Profiles' },\n { value: 'skills', label: 'Skills' },\n { value: 'powerhouse', label: 'Powerhouse' },\n { value: 'publish', label: 'Publish' },\n];\n\nexport default function Editor() {\n const [document, dispatch] = useSelectedPhClintProjectDocument();\n const state = document.state.global;\n const { powerhouse, mastra, routine } = state.features;\n const [activeTab, setActiveTab] = useState<Tab>('cli');\n const [drive] = useSelectedDrive();\n const driveRemoteUrl: string | undefined = (drive?.state?.local as { remoteUrl?: string } | undefined)?.remoteUrl;\n const attachmentService = useMemo(\n () =>\n createRemoteAttachmentService({\n remoteUrl: driveRemoteUrl ? getSwitchboardGatewayUrlFromDriveUrl(driveRemoteUrl) : DEFAULT_SWITCHBOARD_URL,\n }),\n [driveRemoteUrl],\n );\n\n // identity dispatchers\n const setPackageIdentifier = (identifier: string) => dispatch(actions.setPackageIdentifier({ identifier }));\n const setVersion = (version: string) => dispatch(actions.setVersion({ version }));\n const setDescription = (description: string) => dispatch(actions.setDescription({ description }));\n\n // feature dispatchers\n const setPowerhouseLevel = (level: PowerhouseLevel) => dispatch(actions.setPowerhouseLevel({ level }));\n const toggleMastra = (enabled: boolean) => {\n if (enabled) {\n const baseName = state.name || 'my-agent';\n const agentId = `${baseName}-agent`;\n const agentName = `${baseName.charAt(0).toUpperCase()}${baseName.slice(1).replace(/-([a-z])/g, (_, c: string) => ` ${c.toUpperCase()}`)} Agent`;\n dispatch(actions.enableMastra({ agentId, agentName }));\n } else {\n dispatch(actions.disableMastra({ _: true }));\n }\n };\n const toggleRoutine = (enabled: boolean) => {\n if (enabled) dispatch(actions.enableRoutine({ _: true }));\n else dispatch(actions.disableRoutine({ _: true }));\n };\n\n // package dispatchers\n const addPackage = (packageName: string) => dispatch(actions.addPowerhousePackage({ id: generateId(), packageName }));\n const removePackage = (id: string) => dispatch(actions.removePowerhousePackage({ id }));\n const addDocType = (packageId: string, documentType: string) => dispatch(actions.addPackageDocumentType({ packageId, documentType }));\n const removeDocType = (packageId: string, documentType: string) => dispatch(actions.removePackageDocumentType({ packageId, documentType }));\n\n // external-skill dispatchers\n const addSkill = (name: string, githubUrl: string) => dispatch(actions.addExternalSkill({ id: generateId(), name, githubUrl }));\n const removeSkill = (id: string) => dispatch(actions.removeExternalSkill({ id }));\n\n // publish dispatchers\n const bumpVersion = (version: string) => dispatch(actions.bumpVersion({ version }));\n const publishDev = () => dispatch(actions.publishDev({ id: generateId(), timestamp: new Date().toISOString() }));\n const publishStaging = () => dispatch(actions.publishStaging({ id: generateId(), timestamp: new Date().toISOString() }));\n const publishProduction = () => dispatch(actions.publishProduction({ id: generateId(), timestamp: new Date().toISOString() }));\n\n // main agent dispatchers\n const setMainAgentName = (name: string) => dispatch(actions.setMainAgentName({ name }));\n const setMainAgentDescription = (description: string) => dispatch(actions.setMainAgentDescription({ description }));\n const clearMainAgentDescription = () => dispatch(actions.clearMainAgentDescription({ _: true }));\n const setMainAgentImage = (attachment: string) => dispatch(actions.setMainAgentImage({ attachment }));\n const clearMainAgentImage = () => dispatch(actions.clearMainAgentImage({ _: true }));\n\n // sub agent dispatchers\n const addSubAgent = (id: string, name: string, description: string, modelId: string) => dispatch(actions.addSubAgent({ id, name, description, modelId }));\n const removeSubAgent = (id: string) => dispatch(actions.removeSubAgent({ id }));\n const setSubAgentName = (id: string, name: string) => dispatch(actions.setSubAgentName({ id, name }));\n const setSubAgentDescription = (id: string, description: string) => dispatch(actions.setSubAgentDescription({ id, description }));\n\n // library dispatchers\n const addModel = (id: string) => dispatch(actions.addModel({ id }));\n const removeModel = (id: string) => dispatch(actions.removeModel({ id }));\n const addProfile = (id: string, title: string, content: string, insertBefore?: string) => dispatch(actions.addProfile({ id, title, content, insertBefore }));\n const updateProfile = (id: string, title?: string, content?: string) => dispatch(actions.updateProfile({ id, title, content }));\n const removeProfile = (id: string) => dispatch(actions.removeProfile({ id }));\n const reorderProfiles = (ids: string[], insertBefore: string | null) => dispatch(actions.reorderProfiles({ ids, insertBefore }));\n\n // per-agent binding dispatchers\n const setAgentModel = (agentId: string, modelId: string) => dispatch(actions.setAgentModel({ agentId, modelId }));\n const addAgentProfileRef = (agentId: string, profileId: string, insertBefore?: string) => dispatch(actions.addAgentProfileRef({ agentId, profileId, insertBefore }));\n const removeAgentProfileRef = (agentId: string, profileId: string) => dispatch(actions.removeAgentProfileRef({ agentId, profileId }));\n const reorderAgentProfileRefs = (agentId: string, ids: string[], insertBefore: string | null) => dispatch(actions.reorderAgentProfileRefs({ agentId, ids, insertBefore }));\n const addAgentSkill = (agentId: string, name: string) => dispatch(actions.addAgentSkill({ agentId, name }));\n const removeAgentSkill = (agentId: string, name: string) => dispatch(actions.removeAgentSkill({ agentId, name }));\n const addAgentToolPattern = (agentId: string, pattern: string) => dispatch(actions.addAgentToolPattern({ agentId, pattern }));\n const removeAgentToolPattern = (agentId: string, pattern: string) => dispatch(actions.removeAgentToolPattern({ agentId, pattern }));\n\n // chat dispatcher\n const setEnableChat = (enabled: boolean) => dispatch(actions.setEnableChat({ enabled }));\n\n // deployment dispatchers\n const setProxyEnabled = (enabled: boolean) => dispatch(actions.setProxyEnabled({ enabled }));\n const setObservabilityEnabled = (enabled: boolean) => dispatch(actions.setObservabilityEnabled({ enabled }));\n const addSupportedResource = (resource: string) => dispatch(actions.addSupportedResource({ resource }));\n const removeSupportedResource = (resource: string) => dispatch(actions.removeSupportedResource({ resource }));\n\n const isAboveDisabled = powerhouse !== 'Disabled';\n\n const tabClasses = (tab: Tab) => `px-4 py-2 text-sm font-medium border-b-2 cursor-pointer ${activeTab === tab ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700'}`;\n\n return (\n <div className=\"mx-auto max-w-4xl bg-gray-50 p-6\">\n <DocumentToolbar />\n\n <div className=\"ph-default-styles\">\n <h2 className=\"mt-4 text-xl font-bold\">ph-clint Project Spec</h2>\n\n <nav className=\"my-4 flex border-b border-gray-200\">\n {TAB_LABELS.map((t) => (\n <button key={t.value} className={tabClasses(t.value)} onClick={() => setActiveTab(t.value)}>\n {t.label}\n </button>\n ))}\n </nav>\n\n {activeTab === 'cli' && (\n <CliTab\n state={state}\n powerhouse={powerhouse}\n mastra={mastra}\n routine={routine}\n isAboveDisabled={isAboveDisabled}\n setPackageIdentifier={setPackageIdentifier}\n setVersion={setVersion}\n setDescription={setDescription}\n setPowerhouseLevel={setPowerhouseLevel}\n toggleMastra={toggleMastra}\n toggleRoutine={toggleRoutine}\n setEnableChat={setEnableChat}\n addModel={addModel}\n removeModel={removeModel}\n />\n )}\n\n {activeTab === 'agents' && (\n <AgentsTab\n mastra={mastra}\n attachments={attachmentService}\n setMainAgentName={setMainAgentName}\n setMainAgentDescription={setMainAgentDescription}\n clearMainAgentDescription={clearMainAgentDescription}\n setMainAgentImage={setMainAgentImage}\n clearMainAgentImage={clearMainAgentImage}\n addSubAgent={addSubAgent}\n removeSubAgent={removeSubAgent}\n setSubAgentName={setSubAgentName}\n setSubAgentDescription={setSubAgentDescription}\n setAgentModel={setAgentModel}\n addAgentProfileRef={addAgentProfileRef}\n removeAgentProfileRef={removeAgentProfileRef}\n reorderAgentProfileRefs={reorderAgentProfileRefs}\n addAgentSkill={addAgentSkill}\n removeAgentSkill={removeAgentSkill}\n addAgentToolPattern={addAgentToolPattern}\n removeAgentToolPattern={removeAgentToolPattern}\n />\n )}\n\n {activeTab === 'profiles' && <ProfilesTab mastra={mastra} addProfile={addProfile} updateProfile={updateProfile} removeProfile={removeProfile} reorderProfiles={reorderProfiles} />}\n\n {activeTab === 'skills' && <SkillsTab skills={state.externalSkills} addSkill={addSkill} removeSkill={removeSkill} />}\n\n {activeTab === 'powerhouse' && <PowerhouseTab packages={state.packages} isAboveDisabled={isAboveDisabled} addPackage={addPackage} removePackage={removePackage} addDocType={addDocType} removeDocType={removeDocType} />}\n\n {activeTab === 'publish' && (\n <PublishTab\n version={state.version}\n publishHistory={state.publishHistory}\n documentHeader={document.header}\n deployment={state.deployment}\n bumpVersion={bumpVersion}\n publishDev={publishDev}\n publishStaging={publishStaging}\n publishProduction={publishProduction}\n setProxyEnabled={setProxyEnabled}\n setObservabilityEnabled={setObservabilityEnabled}\n addSupportedResource={addSupportedResource}\n removeSupportedResource={removeSupportedResource}\n />\n )}\n </div>\n </div>\n );\n}\n\n/* ── CLI Tab ──────────────────────────────────────────────────── */\n\nfunction CliTab(props: {\n state: PhClintProjectState;\n powerhouse: PowerhouseLevel;\n mastra: PhClintMastraFeature;\n routine: { enabled: boolean };\n isAboveDisabled: boolean;\n setPackageIdentifier: (identifier: string) => void;\n setVersion: (version: string) => void;\n setDescription: (description: string) => void;\n setPowerhouseLevel: (level: PowerhouseLevel) => void;\n toggleMastra: (enabled: boolean) => void;\n toggleRoutine: (enabled: boolean) => void;\n setEnableChat: (enabled: boolean) => void;\n addModel: (id: string) => void;\n removeModel: (id: string) => void;\n}) {\n const { state, mastra } = props;\n const packageIdentifier = `${state.scope ? state.scope + '/' : ''}${state.name ?? ''}`;\n\n return (\n <>\n <section className=\"my-6\">\n <h3 className=\"text-lg font-semibold\">Identity</h3>\n <div className=\"grid grid-cols-[3fr_1fr] gap-4\">\n <TextField label=\"Package name\" value={packageIdentifier} placeholder=\"@scope/my-tool-cli\" onCommit={props.setPackageIdentifier} />\n <TextField label=\"Version\" value={state.version} placeholder=\"0.1.0\" onCommit={props.setVersion} />\n </div>\n <TextField label=\"Description\" value={state.description} placeholder=\"What this CLI does\" onCommit={props.setDescription} />\n </section>\n\n <hr />\n\n <section className=\"my-6\">\n <h3 className=\"text-lg font-semibold\">Features</h3>\n\n <div className=\"my-4 rounded border border-gray-200 bg-white p-4\">\n <h4 className=\"text-base font-semibold\">Powerhouse</h4>\n {props.isAboveDisabled && <p className=\"text-sm text-gray-500\">Cannot go back to Disabled once enabled</p>}\n <div className=\"mt-2 space-y-2\">\n {POWERHOUSE_LEVELS.map((level, i) => (\n <label key={level.value} className=\"flex items-start gap-2\">\n {i > 0 && <div className=\"absolute -mt-3 ml-[7px] h-3 border-l border-gray-300\" />}\n <input type=\"radio\" name=\"powerhouse-level\" checked={props.powerhouse === level.value} disabled={props.isAboveDisabled && level.value === 'Disabled'} onChange={() => props.setPowerhouseLevel(level.value)} className=\"mt-0.5\" />\n <div>\n <span className=\"font-medium\">{level.value}</span>\n <span className=\"ml-2 text-sm text-gray-500\">{level.description}</span>\n </div>\n </label>\n ))}\n </div>\n </div>\n\n <div className=\"my-4 rounded border border-gray-200 bg-white p-4\">\n <Toggle label=\"Mastra\" checked={mastra.enabled} hint=\"AI agent framework\" onChange={props.toggleMastra} />\n {mastra.enabled && (\n <div className=\"mt-4 space-y-4 border-t border-gray-100 pt-4\">\n <ModelsSection models={mastra.models} main={mastra.mainAgent} subAgents={mastra.subAgents} addModel={props.addModel} removeModel={props.removeModel} />\n <div>\n <h4 className=\"text-sm font-semibold text-gray-700\">Common</h4>\n <Toggle\n label=\"Enable Chat\"\n checked={mastra.common.enableChat}\n disabled={!props.isAboveDisabled}\n hint={props.isAboveDisabled ? 'Chat session integration via clint-common' : 'Requires Powerhouse to be enabled'}\n onChange={props.setEnableChat}\n />\n </div>\n </div>\n )}\n </div>\n\n <div className=\"my-4 rounded border border-gray-200 bg-white p-4\">\n <Toggle label=\"Routine loop\" checked={props.routine.enabled} hint=\"tick-based execution loop with triggers\" onChange={props.toggleRoutine} />\n </div>\n </section>\n </>\n );\n}\n\n/* ── Agents Tab ───────────────────────────────────────────────── */\n\ninterface AgentsTabProps {\n mastra: PhClintMastraFeature;\n attachments?: IAttachmentService;\n setMainAgentName: (name: string) => void;\n setMainAgentDescription: (description: string) => void;\n clearMainAgentDescription: () => void;\n setMainAgentImage: (image: string) => void;\n clearMainAgentImage: () => void;\n addSubAgent: (id: string, name: string, description: string, modelId: string) => void;\n removeSubAgent: (id: string) => void;\n setSubAgentName: (id: string, name: string) => void;\n setSubAgentDescription: (id: string, description: string) => void;\n setAgentModel: (agentId: string, modelId: string) => void;\n addAgentProfileRef: (agentId: string, profileId: string, insertBefore?: string) => void;\n removeAgentProfileRef: (agentId: string, profileId: string) => void;\n reorderAgentProfileRefs: (agentId: string, ids: string[], insertBefore: string | null) => void;\n addAgentSkill: (agentId: string, name: string) => void;\n removeAgentSkill: (agentId: string, name: string) => void;\n addAgentToolPattern: (agentId: string, pattern: string) => void;\n removeAgentToolPattern: (agentId: string, pattern: string) => void;\n}\n\nfunction AgentsTab(props: AgentsTabProps) {\n const { mastra, attachments } = props;\n const main = mastra.mainAgent;\n const [showAddForm, setShowAddForm] = useState(false);\n\n if (!mastra.enabled || !main) {\n return (\n <section className=\"my-6 rounded border border-dashed border-gray-300 bg-white p-8 text-center text-gray-500\">\n <h3 className=\"text-lg font-semibold\">Agents</h3>\n <p className=\"mt-2\">Enable Mastra in the CLI tab to configure agents.</p>\n </section>\n );\n }\n\n const allAgentIds = [main.id, ...mastra.subAgents.map((s) => s.id)];\n\n return (\n <>\n <MainAgentCard\n main={main}\n models={mastra.models}\n profiles={mastra.profiles}\n attachments={attachments}\n setMainAgentName={props.setMainAgentName}\n setMainAgentDescription={props.setMainAgentDescription}\n clearMainAgentDescription={props.clearMainAgentDescription}\n setMainAgentImage={props.setMainAgentImage}\n clearMainAgentImage={props.clearMainAgentImage}\n setAgentModel={props.setAgentModel}\n addAgentProfileRef={props.addAgentProfileRef}\n removeAgentProfileRef={props.removeAgentProfileRef}\n reorderAgentProfileRefs={props.reorderAgentProfileRefs}\n addAgentSkill={props.addAgentSkill}\n removeAgentSkill={props.removeAgentSkill}\n addAgentToolPattern={props.addAgentToolPattern}\n removeAgentToolPattern={props.removeAgentToolPattern}\n />\n\n {mastra.subAgents.map((sub) => (\n <SubAgentCard\n key={sub.id}\n sub={sub}\n models={mastra.models}\n profiles={mastra.profiles}\n removeSubAgent={props.removeSubAgent}\n setSubAgentName={props.setSubAgentName}\n setSubAgentDescription={props.setSubAgentDescription}\n setAgentModel={props.setAgentModel}\n addAgentProfileRef={props.addAgentProfileRef}\n removeAgentProfileRef={props.removeAgentProfileRef}\n reorderAgentProfileRefs={props.reorderAgentProfileRefs}\n addAgentSkill={props.addAgentSkill}\n removeAgentSkill={props.removeAgentSkill}\n addAgentToolPattern={props.addAgentToolPattern}\n removeAgentToolPattern={props.removeAgentToolPattern}\n />\n ))}\n\n <section className=\"my-6\">\n {showAddForm ? (\n <AddSubAgentForm\n models={mastra.models}\n existingAgentIds={allAgentIds}\n onAdd={(id, name, description, modelId) => {\n props.addSubAgent(id, name, description, modelId);\n setShowAddForm(false);\n }}\n onCancel={() => setShowAddForm(false)}\n />\n ) : (\n <button\n className=\"rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={mastra.models.length === 0}\n title={mastra.models.length === 0 ? 'Add a model first (CLI tab → Mastra)' : ''}\n onClick={() => setShowAddForm(true)}\n >\n + Add Sub-agent\n </button>\n )}\n </section>\n </>\n );\n}\n\n/* ── Main Agent card (collapsible, sits as a peer of sub-agents) ── */\n\ninterface MainAgentCardProps {\n main: PhClintMainAgent;\n models: PhClintAgentModel[];\n profiles: PhClintAgentProfile[];\n attachments?: IAttachmentService;\n setMainAgentName: (name: string) => void;\n setMainAgentDescription: (description: string) => void;\n clearMainAgentDescription: () => void;\n setMainAgentImage: (image: string) => void;\n clearMainAgentImage: () => void;\n setAgentModel: (agentId: string, modelId: string) => void;\n addAgentProfileRef: (agentId: string, profileId: string, insertBefore?: string) => void;\n removeAgentProfileRef: (agentId: string, profileId: string) => void;\n reorderAgentProfileRefs: (agentId: string, ids: string[], insertBefore: string | null) => void;\n addAgentSkill: (agentId: string, name: string) => void;\n removeAgentSkill: (agentId: string, name: string) => void;\n addAgentToolPattern: (agentId: string, pattern: string) => void;\n removeAgentToolPattern: (agentId: string, pattern: string) => void;\n}\n\nfunction MainAgentCard(props: MainAgentCardProps) {\n const { main } = props;\n const [expanded, setExpanded] = useState(true);\n\n return (\n <div className=\"my-3 rounded border border-gray-200 bg-white p-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <button className=\"text-sm text-gray-400 hover:text-gray-700\" onClick={() => setExpanded(!expanded)} title={expanded ? 'Collapse' : 'Expand'}>\n {expanded ? '▾' : '▸'}\n </button>\n <span className=\"rounded bg-gray-100 px-2 py-0.5 font-mono text-xs text-gray-500\">{main.id}</span>\n <span className=\"font-semibold\">{main.name}</span>\n <span className=\"rounded bg-blue-100 px-2 py-0.5 text-xs font-semibold text-blue-700\">Main</span>\n </div>\n </div>\n {main.description && <p className=\"ml-7 text-sm text-gray-600\">{main.description}</p>}\n\n {expanded && (\n <div className=\"mt-4 space-y-3 border-t border-gray-100 pt-4\">\n <div style={{ display: 'flex', gap: '1.5rem' }}>\n <div style={{ flexShrink: 0, width: '7rem' }}>\n <AgentImageField attachmentRef={main.attachment ?? null} attachments={props.attachments} onSetImage={props.setMainAgentImage} onClearImage={props.clearMainAgentImage} />\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div className=\"grid grid-cols-[1fr_2fr] gap-4\">\n <TextField compact readOnly label=\"Agent ID\" value={main.id} onCommit={() => {}} />\n <TextField compact label=\"Agent Name\" value={main.name} placeholder=\"My Agent\" onCommit={props.setMainAgentName} />\n </div>\n <DescriptionField value={main.description} placeholder=\"A brief description of what this agent does\" onSet={props.setMainAgentDescription} onClear={props.clearMainAgentDescription} />\n </div>\n </div>\n\n <AgentBindings\n agentId={main.id}\n isMain\n modelId={main.modelId}\n profileIds={main.profileIds}\n skills={main.skills}\n toolPatterns={main.toolPatterns}\n models={props.models}\n profiles={props.profiles}\n setAgentModel={props.setAgentModel}\n addAgentProfileRef={props.addAgentProfileRef}\n removeAgentProfileRef={props.removeAgentProfileRef}\n reorderAgentProfileRefs={props.reorderAgentProfileRefs}\n addAgentSkill={props.addAgentSkill}\n removeAgentSkill={props.removeAgentSkill}\n addAgentToolPattern={props.addAgentToolPattern}\n removeAgentToolPattern={props.removeAgentToolPattern}\n />\n </div>\n )}\n </div>\n );\n}\n\nfunction DescriptionField(props: { value: string | null | undefined; placeholder: string; onSet: (v: string) => void; onClear: () => void }) {\n return (\n <label className=\"my-1 block\">\n <h3 className=\"text-xs text-gray-600\">Description</h3>\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n defaultValue={props.value ?? ''}\n placeholder={props.placeholder}\n onBlur={(e) => {\n const next = e.target.value.trim();\n if (next && next !== (props.value ?? '')) props.onSet(next);\n else if (!next && props.value !== null) props.onClear();\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') e.currentTarget.blur();\n }}\n className=\"w-full font-mono\"\n />\n </div>\n </label>\n );\n}\n\nfunction AddSubAgentForm(props: { models: PhClintAgentModel[]; existingAgentIds: string[]; onAdd: (id: string, name: string, description: string, modelId: string) => void; onCancel: () => void }) {\n const [id, setId] = useState('');\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [modelId, setModelId] = useState<string>(props.models[0]?.id ?? '');\n\n const idValid = /^[a-z][a-z0-9-]*$/.test(id) && !props.existingAgentIds.includes(id);\n const canAdd = idValid && name.trim() && description.trim() && modelId;\n\n return (\n <div className=\"my-3 rounded border border-blue-200 bg-blue-50 p-4\">\n <div className=\"grid grid-cols-2 gap-3\">\n <label className=\"block\">\n <span className=\"text-xs text-gray-600\">Sub-agent ID</span>\n <input type=\"text\" value={id} placeholder=\"summarizer\" onChange={(e) => setId(e.target.value.trim())} className=\"w-full rounded border p-2 font-mono text-sm\" />\n </label>\n <label className=\"block\">\n <span className=\"text-xs text-gray-600\">Display name</span>\n <input type=\"text\" value={name} placeholder=\"Summarizer\" onChange={(e) => setName(e.target.value)} className=\"w-full rounded border p-2 text-sm\" />\n </label>\n </div>\n <label className=\"my-2 block\">\n <span className=\"text-xs text-gray-600\">Description (the main agent uses this to decide when to delegate)</span>\n <input type=\"text\" value={description} placeholder=\"Summarizes long documents into bullet points\" onChange={(e) => setDescription(e.target.value)} className=\"w-full rounded border p-2 text-sm\" />\n </label>\n <label className=\"my-2 block\">\n <span className=\"text-xs text-gray-600\">Model</span>\n <select value={modelId} onChange={(e) => setModelId(e.target.value)} className=\"w-full rounded border p-2 font-mono text-sm\">\n {props.models.map((m) => (\n <option key={m.id} value={m.id}>\n {m.id}\n </option>\n ))}\n </select>\n </label>\n <div className=\"mt-2 flex items-center gap-2\">\n <button className=\"rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:cursor-not-allowed disabled:opacity-50\" disabled={!canAdd} onClick={() => props.onAdd(id, name.trim(), description.trim(), modelId)}>\n Add\n </button>\n <button className=\"text-sm text-gray-500 hover:text-gray-700\" onClick={props.onCancel}>\n Cancel\n </button>\n </div>\n </div>\n );\n}\n\ninterface SubAgentCardProps {\n sub: PhClintSubAgent;\n models: PhClintAgentModel[];\n profiles: PhClintAgentProfile[];\n removeSubAgent: (id: string) => void;\n setSubAgentName: (id: string, name: string) => void;\n setSubAgentDescription: (id: string, description: string) => void;\n setAgentModel: (agentId: string, modelId: string) => void;\n addAgentProfileRef: (agentId: string, profileId: string, insertBefore?: string) => void;\n removeAgentProfileRef: (agentId: string, profileId: string) => void;\n reorderAgentProfileRefs: (agentId: string, ids: string[], insertBefore: string | null) => void;\n addAgentSkill: (agentId: string, name: string) => void;\n removeAgentSkill: (agentId: string, name: string) => void;\n addAgentToolPattern: (agentId: string, pattern: string) => void;\n removeAgentToolPattern: (agentId: string, pattern: string) => void;\n}\n\nfunction SubAgentCard(props: SubAgentCardProps) {\n const { sub } = props;\n const [expanded, setExpanded] = useState(false);\n\n return (\n <div className=\"my-3 rounded border border-gray-200 bg-white p-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <button className=\"text-sm text-gray-400 hover:text-gray-700\" onClick={() => setExpanded(!expanded)} title={expanded ? 'Collapse' : 'Expand'}>\n {expanded ? '▾' : '▸'}\n </button>\n <span className=\"rounded bg-gray-100 px-2 py-0.5 font-mono text-xs text-gray-500\">{sub.id}</span>\n <span className=\"font-semibold\">{sub.name}</span>\n </div>\n <button className=\"text-sm text-red-500 hover:text-red-700\" onClick={() => props.removeSubAgent(sub.id)}>\n Remove\n </button>\n </div>\n <p className=\"ml-7 text-sm text-gray-600\">{sub.description}</p>\n\n {expanded && (\n <div className=\"mt-4 space-y-3 border-t border-gray-100 pt-4\">\n <div className=\"grid grid-cols-2 gap-3\">\n <TextField compact label=\"Name\" value={sub.name} onCommit={(v) => props.setSubAgentName(sub.id, v)} />\n <TextField compact label=\"Description\" value={sub.description} onCommit={(v) => props.setSubAgentDescription(sub.id, v)} />\n </div>\n <AgentBindings\n agentId={sub.id}\n isMain={false}\n modelId={sub.modelId}\n profileIds={sub.profileIds}\n skills={sub.skills}\n toolPatterns={sub.toolPatterns}\n models={props.models}\n profiles={props.profiles}\n setAgentModel={props.setAgentModel}\n addAgentProfileRef={props.addAgentProfileRef}\n removeAgentProfileRef={props.removeAgentProfileRef}\n reorderAgentProfileRefs={props.reorderAgentProfileRefs}\n addAgentSkill={props.addAgentSkill}\n removeAgentSkill={props.removeAgentSkill}\n addAgentToolPattern={props.addAgentToolPattern}\n removeAgentToolPattern={props.removeAgentToolPattern}\n />\n </div>\n )}\n </div>\n );\n}\n\n/* ── Agent bindings (per-agent model + profiles + skills + tool patterns) ── */\n\ninterface AgentBindingsProps {\n agentId: string;\n isMain: boolean;\n modelId: string;\n profileIds: string[];\n skills: string[];\n toolPatterns: string[];\n models: PhClintAgentModel[];\n profiles: PhClintAgentProfile[];\n setAgentModel: (agentId: string, modelId: string) => void;\n addAgentProfileRef: (agentId: string, profileId: string, insertBefore?: string) => void;\n removeAgentProfileRef: (agentId: string, profileId: string) => void;\n reorderAgentProfileRefs: (agentId: string, ids: string[], insertBefore: string | null) => void;\n addAgentSkill: (agentId: string, name: string) => void;\n removeAgentSkill: (agentId: string, name: string) => void;\n addAgentToolPattern: (agentId: string, pattern: string) => void;\n removeAgentToolPattern: (agentId: string, pattern: string) => void;\n}\n\nfunction AgentBindings(props: AgentBindingsProps) {\n return (\n <div className=\"space-y-3\">\n <label className=\"block\">\n <span className=\"text-xs text-gray-600\">Model</span>\n <select value={props.modelId} onChange={(e) => props.setAgentModel(props.agentId, e.target.value)} className=\"mt-1 w-full rounded border p-2 font-mono text-sm\">\n {props.models.map((m) => (\n <option key={m.id} value={m.id}>\n {m.id}\n </option>\n ))}\n </select>\n </label>\n\n <ProfileRefsEditor\n agentId={props.agentId}\n profileIds={props.profileIds}\n allProfiles={props.profiles}\n onAdd={(profileId) => props.addAgentProfileRef(props.agentId, profileId)}\n onRemove={(profileId) => props.removeAgentProfileRef(props.agentId, profileId)}\n onReorder={(ids, insertBefore) => props.reorderAgentProfileRefs(props.agentId, ids, insertBefore)}\n />\n\n <ChipListEditor\n label=\"Skills\"\n hint=\"Reference skills by name. tpl wins over ext if both exist.\"\n values={props.skills}\n placeholder=\"skill-name\"\n validator={(v) => /^[a-z][a-z0-9-]*$/.test(v)}\n onAdd={(v) => props.addAgentSkill(props.agentId, v)}\n onRemove={(v) => props.removeAgentSkill(props.agentId, v)}\n />\n\n <ChipListEditor\n label=\"Tool patterns\"\n hint={props.isMain ? 'Glob patterns over tool names (e.g. clint-project-*, *-mcp__*). Empty = all tools.' : 'Glob patterns over tool names. Empty = no tools.'}\n values={props.toolPatterns}\n placeholder=\"pattern*\"\n validator={(v) => v.length > 0}\n onAdd={(v) => props.addAgentToolPattern(props.agentId, v)}\n onRemove={(v) => props.removeAgentToolPattern(props.agentId, v)}\n />\n </div>\n );\n}\n\nfunction ProfileRefsEditor(props: {\n agentId: string;\n profileIds: string[];\n allProfiles: PhClintAgentProfile[];\n onAdd: (profileId: string) => void;\n onRemove: (profileId: string) => void;\n onReorder: (ids: string[], insertBefore: string | null) => void;\n}) {\n const available = props.allProfiles.filter((p) => !props.profileIds.includes(p.id));\n\n const moveUp = (index: number) => {\n if (index === 0) return;\n const id = props.profileIds[index];\n const beforeId = props.profileIds[index - 1];\n props.onReorder([id], beforeId);\n };\n\n const moveDown = (index: number) => {\n if (index >= props.profileIds.length - 1) return;\n const id = props.profileIds[index];\n const afterNext = index + 2 < props.profileIds.length ? props.profileIds[index + 2] : null;\n props.onReorder([id], afterNext);\n };\n\n return (\n <div>\n <span className=\"text-xs text-gray-600\">Profiles (instructions, in order)</span>\n <ul className=\"my-1 space-y-1\">\n {props.profileIds.map((profileId, i) => {\n const profile = props.allProfiles.find((p) => p.id === profileId);\n return (\n <li key={profileId} className=\"flex items-center gap-2 rounded bg-gray-50 px-2 py-1\">\n <button className=\"text-gray-400 hover:text-gray-600 disabled:opacity-30\" disabled={i === 0} onClick={() => moveUp(i)} title=\"Move up\">\n ↑\n </button>\n <button className=\"text-gray-400 hover:text-gray-600 disabled:opacity-30\" disabled={i === props.profileIds.length - 1} onClick={() => moveDown(i)} title=\"Move down\">\n ↓\n </button>\n <span className=\"font-mono text-xs text-gray-500\">{profileId}</span>\n <span className=\"flex-1 text-sm\">{profile?.title ?? <em className=\"text-red-500\">(missing in library)</em>}</span>\n <button className=\"text-sm text-red-500 hover:text-red-700\" onClick={() => props.onRemove(profileId)}>\n Remove\n </button>\n </li>\n );\n })}\n {props.profileIds.length === 0 && <li className=\"px-2 py-1 text-sm italic text-gray-400\">No profiles assigned</li>}\n </ul>\n {available.length > 0 && (\n <select\n value=\"\"\n onChange={(e) => {\n if (e.target.value) props.onAdd(e.target.value);\n }}\n className=\"rounded border p-1 text-sm\"\n >\n <option value=\"\">+ Add profile…</option>\n {available.map((p) => (\n <option key={p.id} value={p.id}>\n {p.title} ({p.id})\n </option>\n ))}\n </select>\n )}\n </div>\n );\n}\n\nfunction ChipListEditor(props: { label: string; hint: string; values: string[]; placeholder: string; validator: (v: string) => boolean; onAdd: (v: string) => void; onRemove: (v: string) => void }) {\n const [input, setInput] = useState('');\n const valid = props.validator(input.trim());\n\n return (\n <div>\n <span className=\"text-xs text-gray-600\">{props.label}</span>\n <p className=\"text-xs text-gray-500\">{props.hint}</p>\n <div className=\"my-1 flex flex-wrap items-center gap-1\">\n {props.values.map((v) => (\n <span key={v} className=\"flex items-center gap-1 rounded bg-gray-100 px-2 py-1 font-mono text-xs\">\n {v}\n <button className=\"text-red-500 hover:text-red-700\" onClick={() => props.onRemove(v)} title=\"Remove\">\n ×\n </button>\n </span>\n ))}\n </div>\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n placeholder={props.placeholder}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && valid) {\n props.onAdd(input.trim());\n setInput('');\n }\n }}\n className=\"flex-1 rounded border p-1 font-mono text-sm\"\n />\n <button\n className=\"rounded bg-blue-500 px-2 py-1 text-xs text-white hover:bg-blue-600 disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={!valid}\n onClick={() => {\n props.onAdd(input.trim());\n setInput('');\n }}\n >\n Add\n </button>\n </div>\n </div>\n );\n}\n\n/* ── Agent image (avatar) — main only ────────────────────────── */\n\nfunction AgentImageField(props: { attachmentRef: string | null | undefined; attachments?: IAttachmentService; onSetImage: (ref: string) => void; onClearImage: () => void }) {\n const [isDragOver, setIsDragOver] = useState(false);\n const [objectUrl, setObjectUrl] = useState<string | undefined>(undefined);\n const dragDepthRef = useRef(0);\n const toast = usePHToast();\n\n useEffect(() => {\n if (!props.attachmentRef || !props.attachments) {\n setObjectUrl(undefined);\n return;\n }\n let cancelled = false;\n let createdUrl: string | undefined;\n void (async () => {\n try {\n const { body, header } = await props.attachments!.get(props.attachmentRef as Parameters<NonNullable<typeof props.attachments>['get']>[0]);\n const chunks: Uint8Array[] = [];\n const reader = body.getReader();\n for (;;) {\n const { done, value } = await reader.read();\n if (cancelled) break;\n if (done) break;\n if (value) chunks.push(value);\n }\n if (cancelled) return;\n const blob = new Blob(chunks as BlobPart[], { type: header.mimeType });\n const url = URL.createObjectURL(blob);\n createdUrl = url;\n setObjectUrl(url);\n } catch {\n // attachment not yet available or service error\n }\n })();\n return () => {\n cancelled = true;\n if (createdUrl) URL.revokeObjectURL(createdUrl);\n };\n }, [props.attachmentRef, props.attachments]);\n\n const handleFile = async (file: File) => {\n if (!file.type.startsWith('image/')) return;\n if (!props.attachments) {\n toast?.('Attachment service unavailable — cannot upload image', { type: 'error' });\n return;\n }\n try {\n const upload = await props.attachments.reserve({ mimeType: file.type, fileName: file.name });\n const { ref } = await upload.send(file.stream());\n props.onSetImage(ref);\n } catch (err) {\n toast?.(`Failed to upload image: ${err instanceof Error ? err.message : String(err)}`, { type: 'error' });\n }\n };\n\n const onDragOver = useCallback((e: React.DragEvent) => {\n if (e.dataTransfer.types.includes('Files')) {\n e.preventDefault();\n e.stopPropagation();\n }\n }, []);\n\n const onDragEnter = useCallback((e: React.DragEvent) => {\n if (e.dataTransfer.types.includes('Files')) {\n e.stopPropagation();\n dragDepthRef.current += 1;\n if (dragDepthRef.current === 1) setIsDragOver(true);\n }\n }, []);\n\n const onDragLeave = useCallback((e: React.DragEvent) => {\n if (e.dataTransfer.types.includes('Files')) {\n e.stopPropagation();\n dragDepthRef.current = Math.max(0, dragDepthRef.current - 1);\n if (dragDepthRef.current === 0) setIsDragOver(false);\n }\n }, []);\n\n const onDrop = useCallback((e: React.DragEvent) => {\n if (e.dataTransfer.types.includes('Files')) {\n e.preventDefault();\n e.stopPropagation();\n dragDepthRef.current = 0;\n setIsDragOver(false);\n const file = e.dataTransfer.files[0];\n if (file) void handleFile(file);\n }\n }, []);\n\n const SIZE = '7rem';\n\n return (\n <div style={{ width: SIZE, height: SIZE, flexShrink: 0 }} className=\"relative my-3\">\n {props.attachmentRef ? (\n <>\n {objectUrl && <img src={objectUrl} alt=\"Agent\" style={{ width: SIZE, height: SIZE }} className=\"rounded border border-gray-200 object-cover\" />}\n {!objectUrl && <div style={{ width: SIZE, height: SIZE }} className=\"rounded border border-gray-200 bg-gray-100\" />}\n <div className=\"mt-1 flex justify-center gap-1\">\n <label className=\"cursor-pointer rounded bg-gray-100 px-2 py-0.5 text-xs hover:bg-gray-200\">\n Replace\n <input\n type=\"file\"\n accept=\"image/*\"\n className=\"hidden\"\n onChange={(e) => {\n if (e.target.files?.[0]) void handleFile(e.target.files[0]);\n }}\n />\n </label>\n <button className=\"rounded bg-gray-100 px-2 py-0.5 text-xs text-red-600 hover:bg-gray-200\" onClick={props.onClearImage}>\n Remove\n </button>\n </div>\n </>\n ) : (\n <div\n style={{ width: SIZE, height: SIZE }}\n className={`flex flex-col items-center justify-center rounded border-2 border-dashed text-center ${isDragOver ? 'border-blue-400 bg-blue-50' : 'border-gray-300 bg-white'}`}\n onDragOver={onDragOver}\n onDragEnter={onDragEnter}\n onDragLeave={onDragLeave}\n onDrop={onDrop}\n >\n <label className=\"cursor-pointer p-2 text-xs text-gray-500 hover:text-blue-600\">\n Drop image or click\n <input\n type=\"file\"\n accept=\"image/*\"\n className=\"hidden\"\n onChange={(e) => {\n if (e.target.files?.[0]) void handleFile(e.target.files[0]);\n }}\n />\n </label>\n </div>\n )}\n </div>\n );\n}\n\n/* ── Models library (inlined under CLI > Features > Mastra) ─── */\n\nfunction ModelsSection(props: { models: PhClintAgentModel[]; main: PhClintMainAgent | null | undefined; subAgents: PhClintSubAgent[]; addModel: (id: string) => void; removeModel: (id: string) => void }) {\n const [newModelId, setNewModelId] = useState('');\n\n const usersOf = (modelId: string): string[] => {\n const u: string[] = [];\n if (props.main?.modelId === modelId) u.push(props.main.id);\n for (const s of props.subAgents) if (s.modelId === modelId) u.push(s.id);\n return u;\n };\n\n const handleAdd = () => {\n const id = newModelId.trim();\n if (id) {\n props.addModel(id);\n setNewModelId('');\n }\n };\n\n return (\n <div>\n <h4 className=\"text-sm font-semibold text-gray-700\">Models</h4>\n <p className=\"text-xs text-gray-500\">\n Provider/model format (e.g. <code>anthropic/claude-sonnet-4-5</code>). Each agent picks one from this list.\n </p>\n\n {props.models.length > 0 && (\n <table className=\"mt-2 w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-gray-500\">\n <th className=\"py-1\">Model</th>\n <th className=\"py-1\">Used by</th>\n <th className=\"py-1\" />\n </tr>\n </thead>\n <tbody>\n {props.models.map((m) => {\n const users = usersOf(m.id);\n const inUse = users.length > 0;\n return (\n <tr key={m.id} className=\"border-b border-gray-100\">\n <td className=\"py-2 font-mono\">{m.id}</td>\n <td className=\"py-2 text-xs text-gray-500\">{users.length === 0 ? <em>—</em> : users.join(', ')}</td>\n <td className=\"py-2 text-right\">\n <button className=\"text-red-500 hover:text-red-700 disabled:cursor-not-allowed disabled:text-gray-300\" disabled={inUse} title={inUse ? `In use by ${users.join(', ')}` : ''} onClick={() => props.removeModel(m.id)}>\n Remove\n </button>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n )}\n\n <div className=\"mt-2 flex items-center gap-2\">\n <input\n type=\"text\"\n placeholder=\"provider/model-name\"\n value={newModelId}\n onChange={(e) => setNewModelId(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n className=\"flex-1 rounded border p-2 font-mono text-sm\"\n />\n <button className=\"rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:opacity-50\" disabled={!newModelId.trim()} onClick={handleAdd}>\n Add Model\n </button>\n </div>\n </div>\n );\n}\n\n/* ── Profiles Tab ─────────────────────────────────────────────── */\n\nfunction ProfilesTab(props: {\n mastra: PhClintMastraFeature;\n addProfile: (id: string, title: string, content: string, insertBefore?: string) => void;\n updateProfile: (id: string, title?: string, content?: string) => void;\n removeProfile: (id: string) => void;\n reorderProfiles: (ids: string[], insertBefore: string | null) => void;\n}) {\n if (!props.mastra.enabled) {\n return (\n <section className=\"my-6 rounded border border-dashed border-gray-300 bg-white p-8 text-center text-gray-500\">\n <h3 className=\"text-lg font-semibold\">Profiles</h3>\n <p className=\"mt-2\">Enable Mastra in the CLI tab to manage agent profiles.</p>\n </section>\n );\n }\n\n return (\n <ProfilesSection\n profiles={props.mastra.profiles}\n main={props.mastra.mainAgent}\n subAgents={props.mastra.subAgents}\n addProfile={props.addProfile}\n updateProfile={props.updateProfile}\n removeProfile={props.removeProfile}\n reorderProfiles={props.reorderProfiles}\n />\n );\n}\n\nfunction ProfilesSection(props: {\n profiles: PhClintAgentProfile[];\n main: PhClintMainAgent | null | undefined;\n subAgents: PhClintSubAgent[];\n addProfile: (id: string, title: string, content: string, insertBefore?: string) => void;\n updateProfile: (id: string, title?: string, content?: string) => void;\n removeProfile: (id: string) => void;\n reorderProfiles: (ids: string[], insertBefore: string | null) => void;\n}) {\n const [showAddForm, setShowAddForm] = useState(false);\n const [newId, setNewId] = useState('');\n const [newTitle, setNewTitle] = useState('');\n\n const usersOf = (profileId: string): string[] => {\n const u: string[] = [];\n if (props.main?.profileIds.includes(profileId)) u.push(props.main.id);\n for (const s of props.subAgents) if (s.profileIds.includes(profileId)) u.push(s.id);\n return u;\n };\n\n const handleAdd = () => {\n const id = newId.trim();\n const title = newTitle.trim();\n if (id && title) {\n props.addProfile(id, title, '');\n setNewId('');\n setNewTitle('');\n setShowAddForm(false);\n }\n };\n\n const moveUp = (index: number) => {\n if (index === 0) return;\n const id = props.profiles[index].id;\n const beforeId = props.profiles[index - 1].id;\n props.reorderProfiles([id], beforeId);\n };\n\n const moveDown = (index: number) => {\n if (index >= props.profiles.length - 1) return;\n const id = props.profiles[index].id;\n const afterNext = index + 2 < props.profiles.length ? props.profiles[index + 2].id : null;\n props.reorderProfiles([id], afterNext);\n };\n\n return (\n <section className=\"my-6\">\n <h3 className=\"text-lg font-semibold\">Agent Profiles</h3>\n <p className=\"text-sm text-gray-600\">Markdown sections that compose into agents' instructions. Reference these from each agent's profile list.</p>\n\n {props.profiles.map((profile, i) => {\n const users = usersOf(profile.id);\n const inUse = users.length > 0;\n return (\n <div key={profile.id} className=\"my-3 rounded border border-gray-200 bg-white p-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <span className=\"rounded bg-gray-100 px-2 py-0.5 font-mono text-xs text-gray-500\">{profile.id}</span>\n <input\n type=\"text\"\n defaultValue={profile.title}\n onBlur={(e) => {\n const next = e.target.value.trim();\n if (next && next !== profile.title) props.updateProfile(profile.id, next);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') e.currentTarget.blur();\n }}\n className=\"border-b border-transparent font-semibold hover:border-gray-300 focus:border-blue-500\"\n />\n {users.length > 0 && (\n <span className=\"rounded bg-blue-50 px-2 py-0.5 text-xs text-blue-700\" title={users.join(', ')}>\n used by: {users.join(', ')}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-1\">\n <button className=\"px-1 text-gray-400 hover:text-gray-600 disabled:opacity-30\" disabled={i === 0} onClick={() => moveUp(i)} title=\"Move up\">\n ↑\n </button>\n <button className=\"px-1 text-gray-400 hover:text-gray-600 disabled:opacity-30\" disabled={i === props.profiles.length - 1} onClick={() => moveDown(i)} title=\"Move down\">\n ↓\n </button>\n <button className=\"ml-2 text-sm text-red-500 hover:text-red-700 disabled:cursor-not-allowed disabled:text-gray-300\" disabled={inUse} title={inUse ? `In use by ${users.join(', ')}` : ''} onClick={() => props.removeProfile(profile.id)}>\n Remove\n </button>\n </div>\n </div>\n <textarea\n defaultValue={profile.content}\n onBlur={(e) => {\n const next = e.target.value;\n if (next !== profile.content) props.updateProfile(profile.id, undefined, next);\n }}\n placeholder=\"Markdown content for this profile section...\"\n rows={4}\n className=\"mt-2 w-full rounded border border-gray-200 p-2 font-mono text-sm\"\n />\n </div>\n );\n })}\n\n {showAddForm ? (\n <div className=\"my-3 rounded border border-blue-200 bg-blue-50 p-4\">\n <div className=\"flex items-center gap-2\">\n <input type=\"text\" placeholder=\"section-id\" value={newId} onChange={(e) => setNewId(e.target.value)} className=\"w-40 rounded border p-2 font-mono text-sm\" />\n <input\n type=\"text\"\n placeholder=\"Section Title\"\n value={newTitle}\n onChange={(e) => setNewTitle(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n className=\"flex-1 rounded border p-2 text-sm\"\n />\n <button className=\"rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:opacity-50\" disabled={!newId.trim() || !newTitle.trim()} onClick={handleAdd}>\n Add\n </button>\n <button\n className=\"text-sm text-gray-500 hover:text-gray-700\"\n onClick={() => {\n setShowAddForm(false);\n setNewId('');\n setNewTitle('');\n }}\n >\n Cancel\n </button>\n </div>\n </div>\n ) : (\n <button className=\"mt-3 rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600\" onClick={() => setShowAddForm(true)}>\n + Add Profile\n </button>\n )}\n </section>\n );\n}\n\n/* ── Skills Tab ───────────────────────────────────────────────── */\n\nfunction SkillsTab(props: { skills: ExternalSkill[]; addSkill: (name: string, githubUrl: string) => void; removeSkill: (id: string) => void }) {\n return (\n <>\n <section className=\"my-6 rounded border border-dashed border-gray-300 bg-white p-8 text-center text-gray-500\">\n <h3 className=\"text-lg font-semibold\">Skill Templates</h3>\n <p className=\"mt-2\">Coming soon</p>\n </section>\n\n <hr />\n\n <ExternalSkillsSection skills={props.skills} addSkill={props.addSkill} removeSkill={props.removeSkill} />\n </>\n );\n}\n\nfunction ExternalSkillsSection(props: { skills: ExternalSkill[]; addSkill: (name: string, githubUrl: string) => void; removeSkill: (id: string) => void }) {\n const [newName, setNewName] = useState('');\n const [newUrl, setNewUrl] = useState('');\n\n const handleAdd = () => {\n if (newName.trim() && newUrl.trim()) {\n props.addSkill(newName.trim(), newUrl.trim());\n setNewName('');\n setNewUrl('');\n }\n };\n\n return (\n <section className=\"my-6\">\n <h3 className=\"text-lg font-semibold\">External Skills</h3>\n <p className=\"text-sm text-gray-600\">Skills from the skills.sh ecosystem, installed via GitHub URL.</p>\n\n {props.skills.length > 0 && (\n <ul className=\"mt-3 space-y-2\">\n {props.skills.map((skill) => (\n <li key={skill.id} className=\"flex items-center justify-between rounded border border-gray-200 bg-white p-3\">\n <div>\n <span className=\"font-mono font-semibold\">{skill.name}</span>\n <span className=\"ml-2 text-sm text-gray-500\">{skill.githubUrl}</span>\n </div>\n <button className=\"text-sm text-red-500 hover:text-red-700\" onClick={() => props.removeSkill(skill.id)}>\n Remove\n </button>\n </li>\n ))}\n </ul>\n )}\n\n <div className=\"mt-3 flex items-center gap-2\">\n <input type=\"text\" placeholder=\"skill-name\" value={newName} onChange={(e) => setNewName(e.target.value)} className=\"w-40 rounded border p-2 font-mono text-sm\" />\n <input\n type=\"text\"\n placeholder=\"https://github.com/org/repo\"\n value={newUrl}\n onChange={(e) => setNewUrl(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n className=\"flex-1 rounded border p-2 font-mono text-sm\"\n />\n <button className=\"rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:opacity-50\" disabled={!newName.trim() || !newUrl.trim()} onClick={handleAdd}>\n Add Skill\n </button>\n </div>\n </section>\n );\n}\n\n/* ── Powerhouse Tab ──────────────────────────────────────────── */\n\nfunction PowerhouseTab(props: {\n packages: PowerhousePackage[];\n isAboveDisabled: boolean;\n addPackage: (packageName: string) => void;\n removePackage: (id: string) => void;\n addDocType: (packageId: string, documentType: string) => void;\n removeDocType: (packageId: string, documentType: string) => void;\n}) {\n if (!props.isAboveDisabled) {\n return (\n <section className=\"my-6 rounded border border-dashed border-gray-300 bg-white p-8 text-center text-gray-500\">\n <h3 className=\"text-lg font-semibold\">Powerhouse</h3>\n <p className=\"mt-2\">Enable Powerhouse in the CLI tab (set level to Reactor or above) to manage packages.</p>\n </section>\n );\n }\n\n return <PackagesSection packages={props.packages} addPackage={props.addPackage} removePackage={props.removePackage} addDocType={props.addDocType} removeDocType={props.removeDocType} />;\n}\n\n/* ── Publish Tab ──────────────────────────────────────────────── */\n\nfunction PublishTab(props: {\n version: string;\n publishHistory: PublishRecord[];\n documentHeader: { id: string; documentType: string };\n deployment: PhClintDeployment;\n bumpVersion: (version: string) => void;\n publishDev: () => void;\n publishStaging: () => void;\n publishProduction: () => void;\n setProxyEnabled: (enabled: boolean) => void;\n setObservabilityEnabled: (enabled: boolean) => void;\n addSupportedResource: (resource: string) => void;\n removeSupportedResource: (resource: string) => void;\n}) {\n const recentHistory = props.publishHistory.slice(-5).reverse();\n const nextPatch = bumpPatch(props.version);\n\n return (\n <>\n <section className=\"my-6\">\n <h3 className=\"text-lg font-semibold\">Publishing</h3>\n\n <div className=\"my-3 rounded border border-gray-200 bg-white p-4\">\n <div className=\"flex items-center gap-4\">\n <span className=\"text-sm text-gray-600\">Current version:</span>\n <span className=\"font-mono font-semibold\">{props.version}</span>\n </div>\n\n <div className=\"mt-3 flex items-center gap-2\">\n <span className=\"text-sm text-gray-600\">Bump version to:</span>\n <input\n type=\"text\"\n placeholder={nextPatch}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n const v = e.currentTarget.value.trim();\n if (v) props.bumpVersion(v);\n e.currentTarget.value = '';\n }\n }}\n className=\"rounded border p-1 font-mono text-sm\"\n />\n </div>\n\n <div className=\"mt-4 flex items-center gap-2\">\n <button className=\"rounded bg-gray-600 px-3 py-2 text-sm text-white hover:bg-gray-700\" onClick={props.publishDev}>\n Publish Dev\n </button>\n <button className=\"rounded bg-amber-600 px-3 py-2 text-sm text-white hover:bg-amber-700\" onClick={props.publishStaging}>\n Publish Staging\n </button>\n <button className=\"rounded bg-green-600 px-3 py-2 text-sm text-white hover:bg-green-700\" onClick={props.publishProduction}>\n Publish Production\n </button>\n </div>\n </div>\n\n {recentHistory.length > 0 && (\n <div className=\"mt-3\">\n <h4 className=\"text-sm font-semibold text-gray-600\">Recent publish history</h4>\n <ul className=\"mt-2 space-y-1\">\n {recentHistory.map((r) => (\n <li key={r.id} className=\"flex items-center gap-3 text-sm\">\n <StatusBadge status={r.status} />\n <span className=\"font-mono\">{r.version}</span>\n <span className=\"text-gray-500\">{r.tag}</span>\n <span className=\"text-gray-400\">{r.timestamp}</span>\n </li>\n ))}\n </ul>\n </div>\n )}\n </section>\n\n <hr />\n\n <DeploymentSection\n deployment={props.deployment}\n setProxyEnabled={props.setProxyEnabled}\n setObservabilityEnabled={props.setObservabilityEnabled}\n addSupportedResource={props.addSupportedResource}\n removeSupportedResource={props.removeSupportedResource}\n />\n\n <hr />\n\n <section className=\"my-6\">\n <h3 className=\"text-lg font-semibold\">Document</h3>\n <div className=\"my-3 rounded border border-gray-200 bg-white p-4\">\n <p className=\"text-sm text-gray-600\">\n Document ID: <span className=\"font-mono\">{props.documentHeader.id}</span>\n </p>\n <p className=\"text-sm text-gray-600\">\n Type: <span className=\"font-mono\">{props.documentHeader.documentType}</span>\n </p>\n </div>\n </section>\n </>\n );\n}\n\nfunction DeploymentSection(props: {\n deployment: PhClintDeployment;\n setProxyEnabled: (enabled: boolean) => void;\n setObservabilityEnabled: (enabled: boolean) => void;\n addSupportedResource: (resource: string) => void;\n removeSupportedResource: (resource: string) => void;\n}) {\n const [newResource, setNewResource] = useState('');\n\n return (\n <section className=\"my-6\">\n <h3 className=\"text-lg font-semibold\">Deployment</h3>\n\n <div className=\"my-3 rounded border border-gray-200 bg-white p-4\">\n <Toggle label=\"Proxy enabled\" checked={props.deployment.proxyEnabled} onChange={props.setProxyEnabled} hint=\"Embedded reverse proxy\" />\n <Toggle label=\"Observability enabled\" checked={props.deployment.observabilityEnabled} onChange={props.setObservabilityEnabled} hint=\"Sentry + OpenTelemetry\" />\n </div>\n\n <div className=\"my-3 rounded border border-gray-200 bg-white p-4\">\n <h4 className=\"text-base font-semibold\">Supported resources</h4>\n <ul className=\"my-2 space-y-1\">\n {props.deployment.supportedResources.map((r) => (\n <li key={r} className=\"flex items-center justify-between text-sm\">\n <span className=\"font-mono\">{r}</span>\n <button className=\"text-red-500 hover:text-red-700\" onClick={() => props.removeSupportedResource(r)}>\n Remove\n </button>\n </li>\n ))}\n </ul>\n <div className=\"mt-2 flex items-center gap-2\">\n <input\n type=\"text\"\n placeholder=\"vetra-agent-...\"\n value={newResource}\n onChange={(e) => setNewResource(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && newResource.trim()) {\n props.addSupportedResource(newResource.trim());\n setNewResource('');\n }\n }}\n className=\"flex-1 rounded border p-1 font-mono text-sm\"\n />\n <button\n className=\"rounded bg-blue-500 px-2 py-1 text-xs text-white hover:bg-blue-600 disabled:opacity-50\"\n disabled={!newResource.trim()}\n onClick={() => {\n props.addSupportedResource(newResource.trim());\n setNewResource('');\n }}\n >\n Add\n </button>\n </div>\n </div>\n </section>\n );\n}\n\n/* ── Powerhouse Packages section ─────────────────────────────── */\n\nfunction PackagesSection(props: {\n packages: PowerhousePackage[];\n addPackage: (packageName: string) => void;\n removePackage: (id: string) => void;\n addDocType: (packageId: string, documentType: string) => void;\n removeDocType: (packageId: string, documentType: string) => void;\n}) {\n const [newPackage, setNewPackage] = useState('');\n\n return (\n <section className=\"my-6\">\n <h3 className=\"text-lg font-semibold\">Reactor Packages</h3>\n\n {props.packages.map((pkg) => (\n <PackageCard key={pkg.id} pkg={pkg} addDocType={props.addDocType} removeDocType={props.removeDocType} removePackage={props.removePackage} />\n ))}\n\n <div className=\"my-3 flex items-center gap-2\">\n <input\n type=\"text\"\n placeholder=\"@scope/package-name\"\n value={newPackage}\n onChange={(e) => setNewPackage(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && newPackage.trim()) {\n props.addPackage(newPackage.trim());\n setNewPackage('');\n }\n }}\n className=\"flex-1 rounded border p-2 font-mono text-sm\"\n />\n <button\n className=\"rounded bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600 disabled:opacity-50\"\n disabled={!newPackage.trim()}\n onClick={() => {\n props.addPackage(newPackage.trim());\n setNewPackage('');\n }}\n >\n Add Package\n </button>\n </div>\n </section>\n );\n}\n\nfunction PackageCard(props: { pkg: PowerhousePackage; addDocType: (packageId: string, documentType: string) => void; removeDocType: (packageId: string, documentType: string) => void; removePackage: (id: string) => void }) {\n const [newDocType, setNewDocType] = useState('');\n\n return (\n <div className=\"my-3 rounded border border-gray-200 bg-white p-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <span className=\"font-mono font-semibold\">{props.pkg.packageName}</span>\n {props.pkg.managed && <span className=\"ml-2 rounded bg-blue-100 px-2 py-0.5 text-xs text-blue-700\">managed</span>}\n {props.pkg.version && <span className=\"ml-2 text-sm text-gray-500\">v{props.pkg.version}</span>}\n </div>\n {!props.pkg.managed && (\n <button className=\"text-sm text-red-500 hover:text-red-700\" onClick={() => props.removePackage(props.pkg.id)}>\n Remove Package\n </button>\n )}\n </div>\n <ul className=\"my-2 space-y-1\">\n {props.pkg.documentTypes.map((dt) => (\n <li key={dt} className=\"flex items-center justify-between text-sm\">\n <span className=\"font-mono\">{dt}</span>\n <button className=\"text-red-500 hover:text-red-700\" onClick={() => props.removeDocType(props.pkg.id, dt)}>\n ×\n </button>\n </li>\n ))}\n </ul>\n <div className=\"mt-2 flex items-center gap-2\">\n <input\n type=\"text\"\n placeholder=\"org/doc-type or */*\"\n value={newDocType}\n onChange={(e) => setNewDocType(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && newDocType.trim()) {\n props.addDocType(props.pkg.id, newDocType.trim());\n setNewDocType('');\n }\n }}\n className=\"flex-1 rounded border p-1 font-mono text-sm\"\n />\n <button\n className=\"rounded bg-blue-500 px-2 py-1 text-xs text-white hover:bg-blue-600 disabled:opacity-50\"\n disabled={!newDocType.trim()}\n onClick={() => {\n props.addDocType(props.pkg.id, newDocType.trim());\n setNewDocType('');\n }}\n >\n Add Doc Type\n </button>\n </div>\n </div>\n );\n}\n\nfunction StatusBadge(props: { status: string }) {\n const color = props.status === 'Succeeded' ? 'bg-green-100 text-green-700' : props.status === 'Failed' ? 'bg-red-100 text-red-700' : props.status === 'InProgress' ? 'bg-amber-100 text-amber-700' : 'bg-gray-100 text-gray-700';\n return <span className={`rounded px-2 py-0.5 text-xs ${color}`}>{props.status}</span>;\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
|