@rubytech/create-maxy-code 0.1.295 → 0.1.296

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/models/dist/index.d.ts +1 -0
  3. package/payload/platform/lib/models/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/models/dist/index.js +4 -2
  5. package/payload/platform/lib/models/dist/index.js.map +1 -1
  6. package/payload/platform/lib/models/src/index.ts +3 -1
  7. package/payload/platform/neo4j/schema.cypher +10 -2
  8. package/payload/platform/plugins/admin/hooks/__tests__/prompt-optimiser-compliance.test.sh +27 -0
  9. package/payload/platform/plugins/admin/hooks/prompt-optimiser-compliance.sh +24 -5
  10. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-doc-contradictions.test.d.ts +2 -0
  11. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-doc-contradictions.test.d.ts.map +1 -0
  12. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-doc-contradictions.test.js +214 -0
  13. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-doc-contradictions.test.js.map +1 -0
  14. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-validator.test.js +1 -0
  15. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-validator.test.js.map +1 -1
  16. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-write-path-task802.test.d.ts +2 -0
  17. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-write-path-task802.test.d.ts.map +1 -0
  18. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-write-path-task802.test.js +113 -0
  19. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-write-path-task802.test.js.map +1 -0
  20. package/payload/platform/plugins/memory/mcp/dist/lib/schema-loader.d.ts +52 -2
  21. package/payload/platform/plugins/memory/mcp/dist/lib/schema-loader.d.ts.map +1 -1
  22. package/payload/platform/plugins/memory/mcp/dist/lib/schema-loader.js +90 -4
  23. package/payload/platform/plugins/memory/mcp/dist/lib/schema-loader.js.map +1 -1
  24. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-open.test.js +1 -0
  25. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-open.test.js.map +1 -1
  26. package/payload/platform/plugins/memory/mcp/vitest.config.ts +3 -0
  27. package/payload/platform/plugins/memory/references/schema-base.md +6 -2
  28. package/payload/platform/plugins/memory/references/schema-construction.md +8 -6
  29. package/payload/platform/plugins/memory/references/schema-estate-agent.md +1 -1
  30. package/payload/platform/scripts/smoke-boot-services.sh +1 -1
  31. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +10 -0
  32. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
  33. package/payload/platform/services/whatsapp-channel/dist/notification.js +15 -0
  34. package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
  35. package/payload/platform/templates/account.json +1 -1
  36. package/payload/server/public/assets/chat-rJYaCD6C.js +1 -0
  37. package/payload/server/public/chat.html +1 -1
  38. package/payload/server/public/assets/chat-DeEYwIKE.js +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "accountId": "",
3
3
  "tier": "",
4
- "adminModel": "claude-sonnet-4-6",
4
+ "adminModel": "claude-fable-5[1m]",
5
5
  "publicModel": "claude-haiku-4-5",
6
6
  "outputStyle": "default",
7
7
  "thinkingView": "default",
@@ -0,0 +1 @@
1
+ import{o as e}from"./chunk-CWOGyPgy.js";import{a as t,i as n,r,t as i}from"./jsx-runtime-5auA0FEj.js";import{n as a,s as o}from"./file-download-C3pBZjt9.js";import{a as s,l as c,o as l,r as u,t as d}from"./AdminShell-DDieHnzi.js";import{a as f,d as p,f as m,i as h,n as g,o as _,r as v,t as y}from"./audio-attachment-mime-DGEfApkA.js";import{l as b}from"./useSelectionMode-C_EBRd2k.js";import{n as x,r as S,t as C}from"./Transcript-C3aDVJ-n.js";var w=r(`calendar-clock`,[[`path`,{d:`M16 14v2.2l1.6 1`,key:`fo4ql5`}],[`path`,{d:`M16 2v4`,key:`4m81vk`}],[`path`,{d:`M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5`,key:`1osxxc`}],[`path`,{d:`M3 10h5`,key:`r794hk`}],[`path`,{d:`M8 2v4`,key:`1cmpym`}],[`circle`,{cx:`16`,cy:`16`,r:`6`,key:`qoo3c4`}]]),ee=r(`corner-down-left`,[[`path`,{d:`M20 4v7a4 4 0 0 1-4 4H4`,key:`6o5b7l`}],[`path`,{d:`m9 10-5 5 5 5`,key:`1kshq7`}]]),T=n(),E=e(t(),1),D=`claude-fable-5[1m]`,O=`claude-opus-4-8[1m]`,k=`claude-sonnet-4-6`,A=`claude-haiku-4-5`,j=i();function M({turns:e}){let[t,n]=(0,E.useState)(!1),r=e.filter(e=>e.kind===`tool-call`).length,i=r>0?`Used ${r} tool${r===1?``:`s`}`:`${e.length} tool result${e.length===1?``:`s`}`;return(0,j.jsxs)(`div`,{className:`chat-toolrun`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`chat-toolrun-toggle`,"aria-expanded":t,onClick:()=>n(e=>!e),children:[(0,j.jsx)(`span`,{className:`wa-chevron`,children:t?`▾`:`▸`}),(0,j.jsx)(`span`,{className:`chat-toolrun-label`,children:i})]}),t&&e.map((e,t)=>(0,j.jsxs)(`div`,{className:`chat-toolrun-item`,children:[(0,j.jsx)(`span`,{className:`chat-toolrun-name`,children:e.kind===`tool-call`?`↳ ${e.name}`:e.isError?`result (error)`:`result`}),(0,j.jsx)(`pre`,{className:`wa-code`,children:e.kind===`tool-call`?JSON.stringify(e.input,null,2):e.text})]},t))]})}function N(e,t){switch(e.kind){case`operator-inbound`:case`operator-typed`:return(0,j.jsx)(`div`,{className:`chat-turn-op`,children:(0,j.jsx)(`p`,{className:`chat-op-body`,children:e.text})},t);case`agent-text`:case`agent-reply`:return(0,j.jsx)(`div`,{className:`chat-prose`,children:(0,j.jsx)(`p`,{className:`chat-prose-body`,children:e.text})},t);case`agent-reply-document`:return(0,j.jsxs)(`div`,{className:`chat-prose`,children:[(0,j.jsxs)(`p`,{className:`chat-doc`,children:[`📎 sent document(s): `,e.files.map(S).join(`, `)]}),e.caption&&(0,j.jsx)(`p`,{className:`chat-prose-body`,children:e.caption})]},t)}}function te(e,t,n){let r=[],i=[],a=()=>{i.length!==0&&(r.push((0,j.jsx)(M,{turns:i},`run-${r.length}`)),i=[])};return e.forEach((e,o)=>{if(e.kind===`turn`&&(e.turn.kind===`tool-call`||e.turn.kind===`tool-result`)){i.push(e.turn);return}a(),e.kind===`directive`?r.push((0,j.jsx)(C,{entry:e.entry,sessionId:t,sessionKey:n},o)):r.push(N(e.turn,o))}),a(),r}var P=[D,O,k,A],ne=[`low`,`medium`,`high`,`xhigh`],re=2500;function F(e){let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(void 0,{weekday:`short`,day:`numeric`,month:`short`,hour:`2-digit`,minute:`2-digit`})}function ie({cacheKey:e,userName:t}){let[n,r]=(0,E.useState)(null);(0,E.useEffect)(()=>{let t=!1;return fetch(`/api/webchat/greeting?session_key=${encodeURIComponent(e)}`).then(async e=>{let n=await e.json();if(!t){if(!e.ok||n.ok!==!0){console.warn(`[admin-ui] greeting-unavailable status=${e.status} ok=${String(n.ok)}`);return}r({events:n.events,tasks:n.tasks,specialists:n.specialists??[]})}}).catch(e=>{t||console.warn(`[admin-ui] greeting-unavailable error=${e instanceof Error?e.message:String(e)}`)}),()=>{t=!0}},[e]);let i=t?.trim().split(/\s+/)[0],a=n?n.tasks.total-n.tasks.items.length:0;return(0,j.jsxs)(`div`,{className:`webchat-greeting`,children:[(0,j.jsx)(`h2`,{className:`webchat-greeting-head`,children:i?`What's up next, ${i}?`:`What's up next?`}),n&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`section`,{className:`webchat-greeting-section`,"data-kind":`events`,children:[(0,j.jsxs)(`h3`,{className:`webchat-greeting-label`,children:[(0,j.jsx)(w,{size:14}),` Upcoming schedule`]}),n.events.length===0?(0,j.jsx)(`p`,{className:`webchat-greeting-none`,children:`Nothing scheduled`}):n.events.map(e=>(0,j.jsxs)(`div`,{className:`webchat-greeting-row`,children:[(0,j.jsx)(`span`,{className:`webchat-greeting-name`,children:e.name}),(0,j.jsx)(`span`,{className:`webchat-greeting-when`,children:F(e.at)})]},e.eventId))]}),(0,j.jsxs)(`section`,{className:`webchat-greeting-section`,"data-kind":`tasks`,children:[(0,j.jsxs)(`h3`,{className:`webchat-greeting-label`,children:[(0,j.jsx)(l,{size:14}),` Outstanding tasks`]}),n.tasks.items.length===0?(0,j.jsx)(`p`,{className:`webchat-greeting-none`,children:`No open tasks`}):(0,j.jsxs)(j.Fragment,{children:[n.tasks.items.map(e=>(0,j.jsxs)(`div`,{className:`webchat-greeting-row`,children:[(0,j.jsx)(`span`,{className:`webchat-greeting-name`,children:e.name}),(0,j.jsx)(`span`,{className:`webchat-greeting-status`,children:e.status})]},e.taskId)),a>0&&(0,j.jsxs)(`p`,{className:`webchat-greeting-more`,children:[`+`,a,` more`]})]})]}),(0,j.jsxs)(`section`,{className:`webchat-greeting-section`,"data-kind":`specialists`,children:[(0,j.jsxs)(`h3`,{className:`webchat-greeting-label`,children:[(0,j.jsx)(u,{size:14}),` Your specialists`]}),n.specialists.length===0?(0,j.jsx)(`p`,{className:`webchat-greeting-none`,children:`No specialists installed`}):n.specialists.map((e,t)=>(0,j.jsxs)(`div`,{className:`webchat-greeting-row webchat-greeting-row-stacked`,children:[(0,j.jsx)(`span`,{className:`webchat-greeting-name`,children:e.name}),e.summary&&(0,j.jsx)(`span`,{className:`webchat-greeting-summary`,children:e.summary})]},`${t}-${e.name}`))]})]})]})}function I({cacheKey:e,userName:t,targetSessionId:n}){let[r,i]=(0,E.useState)(null),[a,c]=(0,E.useState)(``),[l,u]=(0,E.useState)(!1),[d,S]=(0,E.useState)([]),[C,w]=(0,E.useState)(null),[T,D]=(0,E.useState)(!1),O=(0,E.useRef)(null),k=(0,E.useCallback)(e=>{w(null);let t=e.find(e=>!y(e.type,_));if(t){w(`Unsupported file type: "${t.type}". Supported: images, PDF, plain text, markdown, CSV, calendar, voice notes.`);return}let n=e.find(e=>e.size>f);if(n){w(`"${n.name}" exceeds the 50 MB limit.`);return}S(t=>[...t,...e].slice(0,5))},[]),A=(0,E.useMemo)(()=>d.map(e=>e.type.startsWith(`image/`)?URL.createObjectURL(e):null),[d]);(0,E.useEffect)(()=>()=>{for(let e of A)e&&URL.revokeObjectURL(e)},[A]);let M=g(),N=M.state===`recording`||M.state===`paused`||M.state===`sending`,F=(0,E.useCallback)(async()=>{let t=await M.send();if(!t)return;let r=t.type===`audio/ogg`?`.ogg`:t.type===`audio/mp4`?`.m4a`:`.webm`,i=new File([t],`voice-note${r}`,{type:t.type}),a=new FormData;a.append(`text`,``),a.append(`attachments`,i),n&&a.append(`session`,n);try{let t=await fetch(`/api/webchat/send?session_key=${encodeURIComponent(e)}`,{method:`POST`,body:a});t.ok||console.error(`[admin-ui] webchat-send-failed status=${t.status}`)}catch(e){console.error(`[admin-ui] webchat-send-failed error=${e instanceof Error?e.message:String(e)}`)}},[M,e,n]),I=(0,E.useRef)(!1);(0,E.useEffect)(()=>(I.current=!1,()=>{I.current=!0}),[]);let L=(0,E.useRef)(!1),R=(0,E.useCallback)(async()=>{if(L.current)return null;L.current=!0;try{let t=`session_key=${encodeURIComponent(e)}${n?`&session=${encodeURIComponent(n)}`:``}`,r=await fetch(`/api/webchat/session?${t}`);if(!r.ok)return null;let a=await r.json();return I.current||i(a),a}catch{return null}finally{L.current=!1}},[e,n]);(0,E.useEffect)(()=>{R();let e=setInterval(()=>{R()},re);return()=>clearInterval(e)},[R]);let z=(0,E.useCallback)(async()=>{let t=a.trim();if(!(!t&&d.length===0||l)){u(!0);try{let r;if(d.length>0){let i=new FormData;i.append(`text`,t);for(let e of d)i.append(`attachments`,e);n&&i.append(`session`,n),r=await fetch(`/api/webchat/send?session_key=${encodeURIComponent(e)}`,{method:`POST`,body:i})}else r=await fetch(`/api/webchat/send?session_key=${encodeURIComponent(e)}`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(n?{text:t,session:n}:{text:t})});r.ok?(c(``),S([])):r.status===409?console.error(`[admin-ui] webchat-send-refused reason=channel-conflict`):console.error(`[admin-ui] webchat-send-failed status=${r.status}`)}catch(e){console.error(`[admin-ui] webchat-send-failed error=${e instanceof Error?e.message:String(e)}`)}finally{u(!1)}}},[a,l,e,d,n]),ae=(0,E.useCallback)(e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),z())},[z]),B=n?r?.channelBinding??null:null,V=(0,E.useRef)(!1);(0,E.useEffect)(()=>{!n||V.current||!r||(V.current=!0,console.warn(`[admin-ui] chat-session-target sessionId=${n} jsonl=${r.projectDir?`found`:`missing`}`))},[r,n]);let H=r?r.effectivePermissionMode??r.permissionMode??null:null,U=r?.model??null,oe=r?.activity===`busy`,[W,G]=(0,E.useState)(null),[K,q]=(0,E.useState)(null),[J,Y]=(0,E.useState)(null),X=(0,E.useCallback)(async(t,n)=>{let r=t===`model`?G:q;r(n),Y(null);try{let i=await fetch(`/api/webchat/settings?session_key=${encodeURIComponent(e)}`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({op:t,value:n})});i.ok||(r(null),Y(`Could not save ${t} (status ${i.status})`),console.error(`[admin-ui] webchat-settings-failed op=${t} status=${i.status}`))}catch(e){r(null),Y(`Could not save ${t} (network error)`),console.error(`[admin-ui] webchat-settings-failed op=${t} error=${e instanceof Error?e.message:String(e)}`)}},[e]);(0,E.useEffect)(()=>{W!==null&&r?.leverModel===W&&G(null),K!==null&&r?.leverEffort===K&&q(null)},[r,W,K]);let Z=W??r?.leverModel??U??``,Q=K??r?.leverEffort??``,se=Z&&!P.includes(Z)?[...P,Z]:P,$=(0,E.useRef)(!1);return(0,E.useEffect)(()=>{$.current||r?.projectDir&&r.activity==null&&H==null&&U==null&&($.current=!0,console.warn(`[admin-ui] composer-indicators-unavailable sessionId=${r.sessionId} (manager meta unreadable or pre-activity)`))},[r,H,U]),(0,j.jsxs)(`div`,{className:`webchat-page`,children:[r?.projectDir?(0,j.jsx)(x,{sessionId:r.sessionId,projectDir:r.projectDir,sessionKey:e,renderItems:te},r.sessionId):r?n?(0,j.jsx)(`div`,{className:`webchat-greeting`,children:(0,j.jsx)(`p`,{className:`webchat-greeting-none`,children:`No transcript found for this session.`})}):(0,j.jsx)(ie,{cacheKey:e,userName:t}):null,(0,j.jsx)(`div`,{className:`webchat-composer`,children:(0,j.jsxs)(`div`,{className:`webchat-composer-box${T?` drag-over`:``}`,onDragOver:e=>{e.preventDefault(),D(!0)},onDragLeave:()=>D(!1),onDrop:e=>{e.preventDefault(),D(!1),k([...e.dataTransfer.files])},children:[(0,j.jsx)(`input`,{ref:O,type:`file`,multiple:!0,accept:h,style:{display:`none`},onChange:e=>{e.target.files&&k([...e.target.files]),e.target.value=``}}),d.length>0&&(0,j.jsx)(`div`,{className:`attachment-strip`,children:d.map((e,t)=>(0,j.jsxs)(`div`,{className:`attachment-chip`,children:[A[t]?(0,j.jsx)(`img`,{src:A[t],alt:e.name,className:`attachment-chip-thumb`}):e.type.startsWith(`audio/`)?(0,j.jsx)(p,{size:14}):e.type===`application/pdf`?(0,j.jsx)(b,{size:14}):(0,j.jsx)(m,{size:14}),(0,j.jsx)(`span`,{className:`attachment-chip-name`,children:e.name}),(0,j.jsx)(`button`,{type:`button`,className:`attachment-chip-remove`,onClick:()=>S(e=>e.filter((e,n)=>n!==t)),"aria-label":`Remove ${e.name}`,children:`×`})]},t))}),C&&(0,j.jsx)(`p`,{className:`attach-error`,children:C}),M.state===`error`&&M.errorMessage&&(0,j.jsxs)(`p`,{className:`voice-error`,role:`alert`,children:[(0,j.jsx)(p,{size:14}),M.errorMessage]}),N?(0,j.jsx)(`div`,{className:`webchat-input-row voice-active`,children:(0,j.jsx)(v,{state:M.state,elapsedSeconds:M.elapsedSeconds,waveform:M.waveform,onTogglePause:M.togglePause,onDiscard:M.discard,onSend:()=>void F()})}):(0,j.jsxs)(`div`,{className:`webchat-input-row`,children:[(0,j.jsx)(`textarea`,{className:`webchat-input`,value:a,placeholder:`Message your agent…`,rows:2,disabled:B!==null,onChange:e=>c(e.target.value),onKeyDown:ae,onPaste:e=>{let t=e.clipboardData?.items;if(!t)return;let n=[];for(let e of t){if(e.kind!==`file`)continue;let t=e.getAsFile();if(!t)continue;let r=t.type.split(`/`)[1]?.replace(`jpeg`,`jpg`)||`png`;n.push(new File([t],`pasted-image-${Date.now()}.${r}`,{type:t.type}))}n.length>0&&k(n)}}),(0,j.jsx)(`button`,{type:`button`,className:`webchat-send`,onClick:()=>void z(),disabled:l||a.trim().length===0&&d.length===0||B!==null,"aria-label":`Send`,title:`Send`,children:(0,j.jsx)(ee,{size:16})})]}),B!==null&&(0,j.jsxs)(`p`,{className:`webchat-conflict-hint`,children:[`This session is bound to the `,B,` channel — message it there. The transcript stays readable here.`]}),(0,j.jsxs)(`div`,{className:`webchat-controls`,children:[(0,j.jsxs)(`div`,{className:`webchat-controls-left`,children:[H&&(0,j.jsx)(`span`,{className:`webchat-chip`,title:`Permission mode (read-only)`,children:H}),(0,j.jsx)(`button`,{type:`button`,className:`webchat-control`,onClick:()=>O.current?.click(),disabled:B!==null,title:`Attach files`,"aria-label":`Attach`,children:(0,j.jsx)(s,{size:14})}),(0,j.jsx)(`button`,{type:`button`,className:`webchat-control`,onClick:M.start,disabled:N||B!==null,title:`Record voice note`,"aria-label":`Voice input`,children:(0,j.jsx)(p,{size:14})})]}),(0,j.jsxs)(`div`,{className:`webchat-controls-right`,children:[J&&(0,j.jsx)(`span`,{className:`webchat-settings-error`,role:`alert`,children:J}),(0,j.jsxs)(`select`,{className:`webchat-select`,"data-kind":`model`,value:Z,onChange:e=>void X(`model`,e.target.value),title:`Model for new sessions — the current session keeps its model`,"aria-label":`Model for new sessions`,children:[Z===``&&(0,j.jsx)(`option`,{value:``,disabled:!0,children:`model`}),se.map(e=>(0,j.jsx)(`option`,{value:e,children:e},e))]}),(0,j.jsxs)(`select`,{className:`webchat-select`,"data-kind":`effort`,value:Q,onChange:e=>void X(`effort`,e.target.value),title:`Effort for new sessions — the current session keeps its effort`,"aria-label":`Effort for new sessions`,children:[Q===``&&(0,j.jsx)(`option`,{value:``,disabled:!0,children:`effort`}),ne.map(e=>(0,j.jsx)(`option`,{value:e,children:e},e))]}),oe&&(0,j.jsx)(o,{size:14,className:`spin webchat-busy`,"aria-label":`Agent is working`})]})]})]})})]})}function L(){let[e,t]=(0,E.useState)(null),[n]=(0,E.useState)(()=>{try{return new URLSearchParams(window.location.search).get(`session`)}catch{return null}}),[r,i]=(0,E.useState)(!1),[s,l]=(0,E.useState)(void 0),[u,f]=(0,E.useState)(null),[p,m]=(0,E.useState)(void 0),[h,g]=(0,E.useState)(null),[_,v]=(0,E.useState)(null);(0,E.useEffect)(()=>{let e=!1,n=null;try{n=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!n){t(null),i(!0);return}return fetch(`/api/admin/session?session_key=${encodeURIComponent(n)}`).then(async r=>{if(!e){if(r.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}window.location.href=`/`;return}if(r.ok)try{let e=await r.json();typeof e.businessName==`string`&&l(e.businessName),e.sessionId!==void 0&&f(e.sessionId??null),v(e.role??null),m(e.userName===void 0?null:e.userName),g(e.avatar??null)}catch{}t(n),i(!0)}}).catch(()=>{e||(t(n),i(!0))}),()=>{e=!0}},[]);let y=(0,E.useCallback)(()=>{try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}window.location.href=`/`},[]),[b,x]=(0,E.useState)(!1),S=(0,E.useCallback)(async()=>{x(!0);try{let e=await c();if(e){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}window.location.href=`/`}return e}finally{x(!1)}},[]);return r?e?(0,j.jsx)(a,{cacheKey:e,surface:`chat`,onSessionExpired:({code:e,path:t})=>{console.warn(`[admin-auth] outcome=session-expired-redirect code=${e} path=${t} surface=chat`);try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}window.location.href=`/`},children:(0,j.jsx)(d,{cacheKey:e,businessName:s,sessionId:u,onLogout:y,onDisconnect:S,disconnecting:b,userName:p,userAvatar:h,role:_,children:(0,j.jsx)(I,{cacheKey:e,userName:p??null,targetSessionId:n})})}):(0,j.jsx)(`div`,{className:`data-page`,children:(0,j.jsxs)(`div`,{className:`data-empty`,children:[(0,j.jsx)(`p`,{children:`You are not signed in.`}),(0,j.jsxs)(`p`,{children:[`Open the `,(0,j.jsx)(`a`,{href:`/`,className:`data-link`,children:`main admin page`}),` and log in, then return here.`]})]})}):(0,j.jsx)(`div`,{className:`data-page`,children:(0,j.jsxs)(`div`,{className:`data-loading`,children:[(0,j.jsx)(o,{size:18,className:`spin`}),` Loading…`]})})}(0,T.createRoot)(document.getElementById(`root`)).render((0,j.jsx)(L,{}));
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Chat — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/chat-DeEYwIKE.js"></script>
8
+ <script type="module" crossorigin src="/assets/chat-rJYaCD6C.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CWOGyPgy.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/jsx-runtime-5auA0FEj.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/useSelectionMode-C_EBRd2k.js">
@@ -1 +0,0 @@
1
- import{o as e}from"./chunk-CWOGyPgy.js";import{a as t,i as n,r,t as i}from"./jsx-runtime-5auA0FEj.js";import{n as a,s as o}from"./file-download-C3pBZjt9.js";import{a as s,l as c,o as l,r as u,t as d}from"./AdminShell-DDieHnzi.js";import{a as f,d as p,f as m,i as h,n as g,o as _,r as v,t as y}from"./audio-attachment-mime-DGEfApkA.js";import{l as b}from"./useSelectionMode-C_EBRd2k.js";import{n as x,r as S,t as C}from"./Transcript-C3aDVJ-n.js";var w=r(`calendar-clock`,[[`path`,{d:`M16 14v2.2l1.6 1`,key:`fo4ql5`}],[`path`,{d:`M16 2v4`,key:`4m81vk`}],[`path`,{d:`M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5`,key:`1osxxc`}],[`path`,{d:`M3 10h5`,key:`r794hk`}],[`path`,{d:`M8 2v4`,key:`1cmpym`}],[`circle`,{cx:`16`,cy:`16`,r:`6`,key:`qoo3c4`}]]),ee=r(`corner-down-left`,[[`path`,{d:`M20 4v7a4 4 0 0 1-4 4H4`,key:`6o5b7l`}],[`path`,{d:`m9 10-5 5 5 5`,key:`1kshq7`}]]),T=n(),E=e(t(),1),D=`claude-opus-4-8[1m]`,O=`claude-sonnet-4-6`,k=`claude-haiku-4-5`,A=i();function j({turns:e}){let[t,n]=(0,E.useState)(!1),r=e.filter(e=>e.kind===`tool-call`).length,i=r>0?`Used ${r} tool${r===1?``:`s`}`:`${e.length} tool result${e.length===1?``:`s`}`;return(0,A.jsxs)(`div`,{className:`chat-toolrun`,children:[(0,A.jsxs)(`button`,{type:`button`,className:`chat-toolrun-toggle`,"aria-expanded":t,onClick:()=>n(e=>!e),children:[(0,A.jsx)(`span`,{className:`wa-chevron`,children:t?`▾`:`▸`}),(0,A.jsx)(`span`,{className:`chat-toolrun-label`,children:i})]}),t&&e.map((e,t)=>(0,A.jsxs)(`div`,{className:`chat-toolrun-item`,children:[(0,A.jsx)(`span`,{className:`chat-toolrun-name`,children:e.kind===`tool-call`?`↳ ${e.name}`:e.isError?`result (error)`:`result`}),(0,A.jsx)(`pre`,{className:`wa-code`,children:e.kind===`tool-call`?JSON.stringify(e.input,null,2):e.text})]},t))]})}function M(e,t){switch(e.kind){case`operator-inbound`:case`operator-typed`:return(0,A.jsx)(`div`,{className:`chat-turn-op`,children:(0,A.jsx)(`p`,{className:`chat-op-body`,children:e.text})},t);case`agent-text`:case`agent-reply`:return(0,A.jsx)(`div`,{className:`chat-prose`,children:(0,A.jsx)(`p`,{className:`chat-prose-body`,children:e.text})},t);case`agent-reply-document`:return(0,A.jsxs)(`div`,{className:`chat-prose`,children:[(0,A.jsxs)(`p`,{className:`chat-doc`,children:[`📎 sent document(s): `,e.files.map(S).join(`, `)]}),e.caption&&(0,A.jsx)(`p`,{className:`chat-prose-body`,children:e.caption})]},t)}}function te(e,t,n){let r=[],i=[],a=()=>{i.length!==0&&(r.push((0,A.jsx)(j,{turns:i},`run-${r.length}`)),i=[])};return e.forEach((e,o)=>{if(e.kind===`turn`&&(e.turn.kind===`tool-call`||e.turn.kind===`tool-result`)){i.push(e.turn);return}a(),e.kind===`directive`?r.push((0,A.jsx)(C,{entry:e.entry,sessionId:t,sessionKey:n},o)):r.push(M(e.turn,o))}),a(),r}var N=[D,O,k],ne=[`low`,`medium`,`high`,`xhigh`],re=2500;function P(e){let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(void 0,{weekday:`short`,day:`numeric`,month:`short`,hour:`2-digit`,minute:`2-digit`})}function ie({cacheKey:e,userName:t}){let[n,r]=(0,E.useState)(null);(0,E.useEffect)(()=>{let t=!1;return fetch(`/api/webchat/greeting?session_key=${encodeURIComponent(e)}`).then(async e=>{let n=await e.json();if(!t){if(!e.ok||n.ok!==!0){console.warn(`[admin-ui] greeting-unavailable status=${e.status} ok=${String(n.ok)}`);return}r({events:n.events,tasks:n.tasks,specialists:n.specialists??[]})}}).catch(e=>{t||console.warn(`[admin-ui] greeting-unavailable error=${e instanceof Error?e.message:String(e)}`)}),()=>{t=!0}},[e]);let i=t?.trim().split(/\s+/)[0],a=n?n.tasks.total-n.tasks.items.length:0;return(0,A.jsxs)(`div`,{className:`webchat-greeting`,children:[(0,A.jsx)(`h2`,{className:`webchat-greeting-head`,children:i?`What's up next, ${i}?`:`What's up next?`}),n&&(0,A.jsxs)(A.Fragment,{children:[(0,A.jsxs)(`section`,{className:`webchat-greeting-section`,"data-kind":`events`,children:[(0,A.jsxs)(`h3`,{className:`webchat-greeting-label`,children:[(0,A.jsx)(w,{size:14}),` Upcoming schedule`]}),n.events.length===0?(0,A.jsx)(`p`,{className:`webchat-greeting-none`,children:`Nothing scheduled`}):n.events.map(e=>(0,A.jsxs)(`div`,{className:`webchat-greeting-row`,children:[(0,A.jsx)(`span`,{className:`webchat-greeting-name`,children:e.name}),(0,A.jsx)(`span`,{className:`webchat-greeting-when`,children:P(e.at)})]},e.eventId))]}),(0,A.jsxs)(`section`,{className:`webchat-greeting-section`,"data-kind":`tasks`,children:[(0,A.jsxs)(`h3`,{className:`webchat-greeting-label`,children:[(0,A.jsx)(l,{size:14}),` Outstanding tasks`]}),n.tasks.items.length===0?(0,A.jsx)(`p`,{className:`webchat-greeting-none`,children:`No open tasks`}):(0,A.jsxs)(A.Fragment,{children:[n.tasks.items.map(e=>(0,A.jsxs)(`div`,{className:`webchat-greeting-row`,children:[(0,A.jsx)(`span`,{className:`webchat-greeting-name`,children:e.name}),(0,A.jsx)(`span`,{className:`webchat-greeting-status`,children:e.status})]},e.taskId)),a>0&&(0,A.jsxs)(`p`,{className:`webchat-greeting-more`,children:[`+`,a,` more`]})]})]}),(0,A.jsxs)(`section`,{className:`webchat-greeting-section`,"data-kind":`specialists`,children:[(0,A.jsxs)(`h3`,{className:`webchat-greeting-label`,children:[(0,A.jsx)(u,{size:14}),` Your specialists`]}),n.specialists.length===0?(0,A.jsx)(`p`,{className:`webchat-greeting-none`,children:`No specialists installed`}):n.specialists.map((e,t)=>(0,A.jsxs)(`div`,{className:`webchat-greeting-row webchat-greeting-row-stacked`,children:[(0,A.jsx)(`span`,{className:`webchat-greeting-name`,children:e.name}),e.summary&&(0,A.jsx)(`span`,{className:`webchat-greeting-summary`,children:e.summary})]},`${t}-${e.name}`))]})]})]})}function F({cacheKey:e,userName:t,targetSessionId:n}){let[r,i]=(0,E.useState)(null),[a,c]=(0,E.useState)(``),[l,u]=(0,E.useState)(!1),[d,S]=(0,E.useState)([]),[C,w]=(0,E.useState)(null),[T,D]=(0,E.useState)(!1),O=(0,E.useRef)(null),k=(0,E.useCallback)(e=>{w(null);let t=e.find(e=>!y(e.type,_));if(t){w(`Unsupported file type: "${t.type}". Supported: images, PDF, plain text, markdown, CSV, calendar, voice notes.`);return}let n=e.find(e=>e.size>f);if(n){w(`"${n.name}" exceeds the 50 MB limit.`);return}S(t=>[...t,...e].slice(0,5))},[]),j=(0,E.useMemo)(()=>d.map(e=>e.type.startsWith(`image/`)?URL.createObjectURL(e):null),[d]);(0,E.useEffect)(()=>()=>{for(let e of j)e&&URL.revokeObjectURL(e)},[j]);let M=g(),P=M.state===`recording`||M.state===`paused`||M.state===`sending`,F=(0,E.useCallback)(async()=>{let t=await M.send();if(!t)return;let r=t.type===`audio/ogg`?`.ogg`:t.type===`audio/mp4`?`.m4a`:`.webm`,i=new File([t],`voice-note${r}`,{type:t.type}),a=new FormData;a.append(`text`,``),a.append(`attachments`,i),n&&a.append(`session`,n);try{let t=await fetch(`/api/webchat/send?session_key=${encodeURIComponent(e)}`,{method:`POST`,body:a});t.ok||console.error(`[admin-ui] webchat-send-failed status=${t.status}`)}catch(e){console.error(`[admin-ui] webchat-send-failed error=${e instanceof Error?e.message:String(e)}`)}},[M,e,n]),I=(0,E.useRef)(!1);(0,E.useEffect)(()=>(I.current=!1,()=>{I.current=!0}),[]);let L=(0,E.useRef)(!1),R=(0,E.useCallback)(async()=>{if(L.current)return null;L.current=!0;try{let t=`session_key=${encodeURIComponent(e)}${n?`&session=${encodeURIComponent(n)}`:``}`,r=await fetch(`/api/webchat/session?${t}`);if(!r.ok)return null;let a=await r.json();return I.current||i(a),a}catch{return null}finally{L.current=!1}},[e,n]);(0,E.useEffect)(()=>{R();let e=setInterval(()=>{R()},re);return()=>clearInterval(e)},[R]);let z=(0,E.useCallback)(async()=>{let t=a.trim();if(!(!t&&d.length===0||l)){u(!0);try{let r;if(d.length>0){let i=new FormData;i.append(`text`,t);for(let e of d)i.append(`attachments`,e);n&&i.append(`session`,n),r=await fetch(`/api/webchat/send?session_key=${encodeURIComponent(e)}`,{method:`POST`,body:i})}else r=await fetch(`/api/webchat/send?session_key=${encodeURIComponent(e)}`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(n?{text:t,session:n}:{text:t})});r.ok?(c(``),S([])):r.status===409?console.error(`[admin-ui] webchat-send-refused reason=channel-conflict`):console.error(`[admin-ui] webchat-send-failed status=${r.status}`)}catch(e){console.error(`[admin-ui] webchat-send-failed error=${e instanceof Error?e.message:String(e)}`)}finally{u(!1)}}},[a,l,e,d,n]),ae=(0,E.useCallback)(e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),z())},[z]),B=n?r?.channelBinding??null:null,V=(0,E.useRef)(!1);(0,E.useEffect)(()=>{!n||V.current||!r||(V.current=!0,console.warn(`[admin-ui] chat-session-target sessionId=${n} jsonl=${r.projectDir?`found`:`missing`}`))},[r,n]);let H=r?r.effectivePermissionMode??r.permissionMode??null:null,U=r?.model??null,oe=r?.activity===`busy`,[W,G]=(0,E.useState)(null),[K,q]=(0,E.useState)(null),[J,Y]=(0,E.useState)(null),X=(0,E.useCallback)(async(t,n)=>{let r=t===`model`?G:q;r(n),Y(null);try{let i=await fetch(`/api/webchat/settings?session_key=${encodeURIComponent(e)}`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({op:t,value:n})});i.ok||(r(null),Y(`Could not save ${t} (status ${i.status})`),console.error(`[admin-ui] webchat-settings-failed op=${t} status=${i.status}`))}catch(e){r(null),Y(`Could not save ${t} (network error)`),console.error(`[admin-ui] webchat-settings-failed op=${t} error=${e instanceof Error?e.message:String(e)}`)}},[e]);(0,E.useEffect)(()=>{W!==null&&r?.leverModel===W&&G(null),K!==null&&r?.leverEffort===K&&q(null)},[r,W,K]);let Z=W??r?.leverModel??U??``,Q=K??r?.leverEffort??``,se=Z&&!N.includes(Z)?[...N,Z]:N,$=(0,E.useRef)(!1);return(0,E.useEffect)(()=>{$.current||r?.projectDir&&r.activity==null&&H==null&&U==null&&($.current=!0,console.warn(`[admin-ui] composer-indicators-unavailable sessionId=${r.sessionId} (manager meta unreadable or pre-activity)`))},[r,H,U]),(0,A.jsxs)(`div`,{className:`webchat-page`,children:[r?.projectDir?(0,A.jsx)(x,{sessionId:r.sessionId,projectDir:r.projectDir,sessionKey:e,renderItems:te},r.sessionId):r?n?(0,A.jsx)(`div`,{className:`webchat-greeting`,children:(0,A.jsx)(`p`,{className:`webchat-greeting-none`,children:`No transcript found for this session.`})}):(0,A.jsx)(ie,{cacheKey:e,userName:t}):null,(0,A.jsx)(`div`,{className:`webchat-composer`,children:(0,A.jsxs)(`div`,{className:`webchat-composer-box${T?` drag-over`:``}`,onDragOver:e=>{e.preventDefault(),D(!0)},onDragLeave:()=>D(!1),onDrop:e=>{e.preventDefault(),D(!1),k([...e.dataTransfer.files])},children:[(0,A.jsx)(`input`,{ref:O,type:`file`,multiple:!0,accept:h,style:{display:`none`},onChange:e=>{e.target.files&&k([...e.target.files]),e.target.value=``}}),d.length>0&&(0,A.jsx)(`div`,{className:`attachment-strip`,children:d.map((e,t)=>(0,A.jsxs)(`div`,{className:`attachment-chip`,children:[j[t]?(0,A.jsx)(`img`,{src:j[t],alt:e.name,className:`attachment-chip-thumb`}):e.type.startsWith(`audio/`)?(0,A.jsx)(p,{size:14}):e.type===`application/pdf`?(0,A.jsx)(b,{size:14}):(0,A.jsx)(m,{size:14}),(0,A.jsx)(`span`,{className:`attachment-chip-name`,children:e.name}),(0,A.jsx)(`button`,{type:`button`,className:`attachment-chip-remove`,onClick:()=>S(e=>e.filter((e,n)=>n!==t)),"aria-label":`Remove ${e.name}`,children:`×`})]},t))}),C&&(0,A.jsx)(`p`,{className:`attach-error`,children:C}),M.state===`error`&&M.errorMessage&&(0,A.jsxs)(`p`,{className:`voice-error`,role:`alert`,children:[(0,A.jsx)(p,{size:14}),M.errorMessage]}),P?(0,A.jsx)(`div`,{className:`webchat-input-row voice-active`,children:(0,A.jsx)(v,{state:M.state,elapsedSeconds:M.elapsedSeconds,waveform:M.waveform,onTogglePause:M.togglePause,onDiscard:M.discard,onSend:()=>void F()})}):(0,A.jsxs)(`div`,{className:`webchat-input-row`,children:[(0,A.jsx)(`textarea`,{className:`webchat-input`,value:a,placeholder:`Message your agent…`,rows:2,disabled:B!==null,onChange:e=>c(e.target.value),onKeyDown:ae,onPaste:e=>{let t=e.clipboardData?.items;if(!t)return;let n=[];for(let e of t){if(e.kind!==`file`)continue;let t=e.getAsFile();if(!t)continue;let r=t.type.split(`/`)[1]?.replace(`jpeg`,`jpg`)||`png`;n.push(new File([t],`pasted-image-${Date.now()}.${r}`,{type:t.type}))}n.length>0&&k(n)}}),(0,A.jsx)(`button`,{type:`button`,className:`webchat-send`,onClick:()=>void z(),disabled:l||a.trim().length===0&&d.length===0||B!==null,"aria-label":`Send`,title:`Send`,children:(0,A.jsx)(ee,{size:16})})]}),B!==null&&(0,A.jsxs)(`p`,{className:`webchat-conflict-hint`,children:[`This session is bound to the `,B,` channel — message it there. The transcript stays readable here.`]}),(0,A.jsxs)(`div`,{className:`webchat-controls`,children:[(0,A.jsxs)(`div`,{className:`webchat-controls-left`,children:[H&&(0,A.jsx)(`span`,{className:`webchat-chip`,title:`Permission mode (read-only)`,children:H}),(0,A.jsx)(`button`,{type:`button`,className:`webchat-control`,onClick:()=>O.current?.click(),disabled:B!==null,title:`Attach files`,"aria-label":`Attach`,children:(0,A.jsx)(s,{size:14})}),(0,A.jsx)(`button`,{type:`button`,className:`webchat-control`,onClick:M.start,disabled:P||B!==null,title:`Record voice note`,"aria-label":`Voice input`,children:(0,A.jsx)(p,{size:14})})]}),(0,A.jsxs)(`div`,{className:`webchat-controls-right`,children:[J&&(0,A.jsx)(`span`,{className:`webchat-settings-error`,role:`alert`,children:J}),(0,A.jsxs)(`select`,{className:`webchat-select`,"data-kind":`model`,value:Z,onChange:e=>void X(`model`,e.target.value),title:`Model for new sessions — the current session keeps its model`,"aria-label":`Model for new sessions`,children:[Z===``&&(0,A.jsx)(`option`,{value:``,disabled:!0,children:`model`}),se.map(e=>(0,A.jsx)(`option`,{value:e,children:e},e))]}),(0,A.jsxs)(`select`,{className:`webchat-select`,"data-kind":`effort`,value:Q,onChange:e=>void X(`effort`,e.target.value),title:`Effort for new sessions — the current session keeps its effort`,"aria-label":`Effort for new sessions`,children:[Q===``&&(0,A.jsx)(`option`,{value:``,disabled:!0,children:`effort`}),ne.map(e=>(0,A.jsx)(`option`,{value:e,children:e},e))]}),oe&&(0,A.jsx)(o,{size:14,className:`spin webchat-busy`,"aria-label":`Agent is working`})]})]})]})})]})}function I(){let[e,t]=(0,E.useState)(null),[n]=(0,E.useState)(()=>{try{return new URLSearchParams(window.location.search).get(`session`)}catch{return null}}),[r,i]=(0,E.useState)(!1),[s,l]=(0,E.useState)(void 0),[u,f]=(0,E.useState)(null),[p,m]=(0,E.useState)(void 0),[h,g]=(0,E.useState)(null),[_,v]=(0,E.useState)(null);(0,E.useEffect)(()=>{let e=!1,n=null;try{n=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!n){t(null),i(!0);return}return fetch(`/api/admin/session?session_key=${encodeURIComponent(n)}`).then(async r=>{if(!e){if(r.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}window.location.href=`/`;return}if(r.ok)try{let e=await r.json();typeof e.businessName==`string`&&l(e.businessName),e.sessionId!==void 0&&f(e.sessionId??null),v(e.role??null),m(e.userName===void 0?null:e.userName),g(e.avatar??null)}catch{}t(n),i(!0)}}).catch(()=>{e||(t(n),i(!0))}),()=>{e=!0}},[]);let y=(0,E.useCallback)(()=>{try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}window.location.href=`/`},[]),[b,x]=(0,E.useState)(!1),S=(0,E.useCallback)(async()=>{x(!0);try{let e=await c();if(e){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}window.location.href=`/`}return e}finally{x(!1)}},[]);return r?e?(0,A.jsx)(a,{cacheKey:e,surface:`chat`,onSessionExpired:({code:e,path:t})=>{console.warn(`[admin-auth] outcome=session-expired-redirect code=${e} path=${t} surface=chat`);try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}window.location.href=`/`},children:(0,A.jsx)(d,{cacheKey:e,businessName:s,sessionId:u,onLogout:y,onDisconnect:S,disconnecting:b,userName:p,userAvatar:h,role:_,children:(0,A.jsx)(F,{cacheKey:e,userName:p??null,targetSessionId:n})})}):(0,A.jsx)(`div`,{className:`data-page`,children:(0,A.jsxs)(`div`,{className:`data-empty`,children:[(0,A.jsx)(`p`,{children:`You are not signed in.`}),(0,A.jsxs)(`p`,{children:[`Open the `,(0,A.jsx)(`a`,{href:`/`,className:`data-link`,children:`main admin page`}),` and log in, then return here.`]})]})}):(0,A.jsx)(`div`,{className:`data-page`,children:(0,A.jsxs)(`div`,{className:`data-loading`,children:[(0,A.jsx)(o,{size:18,className:`spin`}),` Loading…`]})})}(0,T.createRoot)(document.getElementById(`root`)).render((0,A.jsx)(I,{}));