@rubytech/create-realagent-code 0.1.597 → 0.1.599
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/__tests__/installer-settings-permissions.test.js +54 -0
- package/dist/__tests__/output-style-seed.test.js +23 -0
- package/dist/index.js +24 -0
- package/dist/permissions-seed.js +11 -2
- package/package.json +1 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +5 -7
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +10 -0
- package/payload/platform/plugins/docs/references/settings.md +4 -6
- package/payload/platform/plugins/email/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/email/PLUGIN.md +2 -2
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js +45 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/index.js +5 -4
- package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +6 -4
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js +42 -4
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-fetch-body.d.ts +2 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-fetch-body.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-fetch-body.js +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-fetch-body.js.map +1 -1
- package/payload/platform/plugins/email/references/email-reference.md +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +6 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js +40 -16
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gateless-census.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gateless-census.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gateless-census.test.js +55 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gateless-census.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +22 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +84 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +63 -24
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +13 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/output-style-audit.d.ts +42 -0
- package/payload/platform/services/claude-session-manager/dist/output-style-audit.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/output-style-audit.js +98 -0
- package/payload/platform/services/claude-session-manager/dist/output-style-audit.js.map +1 -0
- package/payload/platform/templates/output-styles/plain-assistant.md +50 -0
- package/payload/server/public/assets/routines-DN_yDtEj.js +2 -0
- package/payload/server/public/assets/routines-DN_yDtEj.js.br +0 -0
- package/payload/server/public/assets/routines-DN_yDtEj.js.gz +0 -0
- package/payload/server/public/routines.html +1 -1
- package/payload/server/server.js +36 -0
- package/payload/server/public/assets/routines-CWEuQ7Gl.js +0 -2
- package/payload/server/public/assets/routines-CWEuQ7Gl.js.br +0 -0
- package/payload/server/public/assets/routines-CWEuQ7Gl.js.gz +0 -0
package/payload/server/server.js
CHANGED
|
@@ -33101,6 +33101,42 @@ function runsCsvFilename(name, eventId, date) {
|
|
|
33101
33101
|
const slug = clean(name ?? "").slice(0, 48).replace(/-+$/, "");
|
|
33102
33102
|
return `${slug || clean(eventId.slice(0, 8)) || "routine"}-runs-${date}.csv`;
|
|
33103
33103
|
}
|
|
33104
|
+
app55.get("/runs", requireAdminSession, async (c) => {
|
|
33105
|
+
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
33106
|
+
if (!accountId) {
|
|
33107
|
+
console.error('[admin:routines] op=runs-all auth-rejected reason="no account for session"');
|
|
33108
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
33109
|
+
}
|
|
33110
|
+
const rawLimit = Number(c.req.query("limit") ?? 200);
|
|
33111
|
+
const limit = Number.isFinite(rawLimit) ? Math.min(Math.max(Math.trunc(rawLimit), 1), 1e3) : 200;
|
|
33112
|
+
const session = getSession();
|
|
33113
|
+
try {
|
|
33114
|
+
const res = await session.run(
|
|
33115
|
+
`MATCH (r:RoutineRun)-[:RUN_OF]->(e:Event {accountId: $accountId})
|
|
33116
|
+
WHERE r.accountId = $accountId
|
|
33117
|
+
RETURN r, e.name AS eventName
|
|
33118
|
+
ORDER BY r.startedAt DESC
|
|
33119
|
+
LIMIT $limit`,
|
|
33120
|
+
{ accountId, limit: int2(limit) }
|
|
33121
|
+
);
|
|
33122
|
+
const runs = res.records.map((rec) => ({
|
|
33123
|
+
...mapRun(rec.get("r").properties),
|
|
33124
|
+
// An existing event whose name is null (created before names were
|
|
33125
|
+
// required) renders a placeholder rather than `null`. A run whose event
|
|
33126
|
+
// was deleted has no RUN_OF match and is excluded from the feed entirely,
|
|
33127
|
+
// so it never reaches this fallback.
|
|
33128
|
+
eventName: rec.get("eventName") ?? "(unnamed routine)"
|
|
33129
|
+
}));
|
|
33130
|
+
console.log(`[admin:routines] op=runs-all accountId=${accountId.slice(0, 8)} count=${runs.length}`);
|
|
33131
|
+
return c.json({ runs });
|
|
33132
|
+
} catch (err) {
|
|
33133
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
33134
|
+
console.error(`[admin:routines] op=runs-all-fail err="${message}"`);
|
|
33135
|
+
return c.json({ error: `Runs unavailable: ${message}` }, 503);
|
|
33136
|
+
} finally {
|
|
33137
|
+
session.close();
|
|
33138
|
+
}
|
|
33139
|
+
});
|
|
33104
33140
|
app55.get("/:eventId/runs", requireAdminSession, async (c) => {
|
|
33105
33141
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
33106
33142
|
if (!accountId) {
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{o as e,t}from"./chunk-BycB0eMI.js";import{i as n,n as r,t as i}from"./jsx-runtime-BtDK2X5t.js";import{F as a,G as o,L as s,M as c,O as l,V as u,Y as d,Z as f,_ as p,it as m,j as h,k as g,m as _,p as v,v as y}from"./useMediaQuery-R1smYLx4.js";import{A as b,m as x,t as S}from"./AdminShell-C3R-vMZ5.js";import{t as C}from"./clock-Dzy79hq3.js";import{t as w}from"./triangle-alert-d7yjaIqv.js";import{t as ee}from"./wrench-DL1pbaCs.js";import{r as T}from"./file-download-B7zwa78w.js";var te=f(`circle-pause`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`10`,x2:`10`,y1:`15`,y2:`9`,key:`c1nkhi`}],[`line`,{x1:`14`,x2:`14`,y1:`15`,y2:`9`,key:`h65svq`}]]),ne=f(`circle-play`,[[`path`,{d:`M9 9.003a1 1 0 0 1 1.517-.859l4.997 2.997a1 1 0 0 1 0 1.718l-4.997 2.997A1 1 0 0 1 9 14.996z`,key:`kmsa83`}],[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}]]),E=f(`history`,[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}],[`path`,{d:`M12 7v5l4 2`,key:`1fdv2h`}]]),D=r(),O=e(n(),1),k=[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`];function A(e,t){if(e===`*`)return{kind:`any`,value:0,rangeStart:null,rangeEnd:null,step:1};let n=e.match(/^(\*|\d+-\d+)\/(\d+)$/);if(n){let e=Number(n[2]);if(e<1)return null;if(n[1]===`*`)return{kind:`step`,value:0,rangeStart:null,rangeEnd:null,step:e};let[r,i]=n[1].split(`-`).map(Number);return r>t||i>t||r>i?null:{kind:`step`,value:0,rangeStart:r,rangeEnd:i,step:e}}let r=e.match(/^(\d+)-(\d+)$/);if(r){let e=Number(r[1]),n=Number(r[2]);return e>t||n>t||e>n?null:{kind:`step`,value:0,rangeStart:e,rangeEnd:n,step:1}}if(/^\d+$/.test(e)){let n=Number(e);return n>t?null:{kind:`fixed`,value:n,rangeStart:null,rangeEnd:null,step:1}}return null}function j(e){return String(e).padStart(2,`0`)}function M(e){if(e===`*`)return null;let t=e.match(/^(\d+)-(\d+)$/);if(t){let e=Number(t[1]),n=Number(t[2]);return e>7||n>7||e>n?`invalid`:`${k[e%7]} to ${k[n%7]}`}let n=e.split(`,`);return n.length>0&&n.every(e=>/^\d+$/.test(e)&&Number(e)<=7)?n.map(e=>k[Number(e)%7]).join(`, `):`invalid`}function N(e){let t=e.trim().split(/\s+/);if(t.length!==5)return e;let[n,r,i,a,o]=t;if(a!==`*`||i!==`*`&&!/^\d+$/.test(i)||i!==`*`&&(Number(i)<1||Number(i)>31))return e;let s=A(n,59),c=A(r,23);if(!s||!c)return e;let l=M(o);if(l===`invalid`||s.kind===`step`&&s.rangeStart!==null||(s.kind===`any`&&(s={kind:`step`,value:0,rangeStart:null,rangeEnd:null,step:1}),c.kind===`step`&&c.step===1&&c.rangeStart===null&&(c={kind:`any`,value:0,rangeStart:null,rangeEnd:null,step:1}),i!==`*`&&!(s.kind===`fixed`&&c.kind===`fixed`&&o===`*`))||s.kind===`step`&&c.kind===`step`&&c.step>1)return e;let u=l?`, ${l}`:``,d=e=>e.rangeStart+Math.floor((e.rangeEnd-e.rangeStart)/e.step)*e.step;if(s.kind===`step`){let e=s.step===1?`Every minute`:`Every ${s.step} minutes`;return c.kind===`any`?`${e}${u}`:c.kind===`fixed`?`${e}, ${j(c.value)}:00 to ${j(c.value)}:59${u}`:`${e}, ${j(c.rangeStart)}:00 to ${j(d(c))}:00${u}`}if(c.kind===`step`){let e=j(s.value),t=s.value===0?``:` at :${e}`;return c.rangeStart===null?`Every ${c.step} hours${t}${u}`:c.step===1?`Hourly, ${j(c.rangeStart)}:${e} to ${j(c.rangeEnd)}:${e}${u}`:`Every ${c.step} hours, ${j(c.rangeStart)}:${e} to ${j(d(c))}:${e}${u}`}if(c.kind===`any`)return`${s.value===0?`Every hour`:`Every hour at :${j(s.value)}`}${u}`;let f=`${j(c.value)}:${j(s.value)}`;return i===`*`?l?`${l} at ${f}`:`Daily at ${f}`:`Monthly on day ${Number(i)} at ${f}`}var P={timeMode:`at`,minute:0,hour:9,interval:1,window:null,dayMode:`every`,weekdays:[],dayOfMonth:1};function F(e){let t=e.match(/^(\d+)-(\d+)$/);if(t){let e=Number(t[1]),n=Number(t[2]);if(e>7||n>7||e>n)return null;let r=[];for(let t=e;t<=n;t+=1)r.push(t%7);return[...new Set(r)].sort((e,t)=>e-t)}let n=e.split(`,`);return n.every(e=>/^\d+$/.test(e)&&Number(e)<=7)?[...new Set(n.map(e=>Number(e)%7))].sort((e,t)=>e-t):null}function I(e){let t=e.trim().split(/\s+/);if(t.length!==5)return null;let[n,r,i,a,o]=t;if(a!==`*`||i!==`*`&&!/^\d+$/.test(i))return null;let s=A(n,59),c=A(r,23);if(!s||!c||s.kind===`step`&&s.rangeStart!==null)return null;let l=`every`,u=[],d=1;if(i!==`*`){if(o!==`*`)return null;let e=Number(i);if(e<1||e>31||s.kind!==`fixed`||c.kind!==`fixed`)return null;l=`dayOfMonth`,d=e}else if(o!==`*`){let e=F(o);if(e===null)return null;l=`weekdays`,u=e}let f={dayMode:l,weekdays:u,dayOfMonth:d};if(s.kind===`any`||s.kind===`step`){if(c.kind===`step`&&c.step>1)return null;let e=s.kind===`any`?1:s.step,t=c.kind===`any`?null:c.kind===`fixed`?{start:c.value,end:c.value}:{start:c.rangeStart,end:c.rangeEnd};return{...P,...f,timeMode:`everyMinutes`,minute:0,interval:e,window:t}}return c.kind===`fixed`?{...P,...f,timeMode:`at`,minute:s.value,hour:c.value}:c.kind===`any`?{...P,...f,timeMode:`everyHours`,minute:s.value,interval:1,window:null}:{...P,...f,timeMode:`everyHours`,minute:s.value,interval:c.step,window:c.rangeStart===null?null:{start:c.rangeStart,end:c.rangeEnd}}}function L(e){return e.dayMode===`dayOfMonth`?[String(e.dayOfMonth),`*`]:e.dayMode===`weekdays`&&e.weekdays.length>0?[`*`,[...e.weekdays].sort((e,t)=>e-t).join(`,`)]:[`*`,`*`]}function R(e){let[t,n]=L(e);if(e.timeMode===`everyMinutes`){let r=e.window===null?`*`:e.window.start===e.window.end?String(e.window.start):`${e.window.start}-${e.window.end}`;return`*/${e.interval} ${r} ${t} * ${n}`}if(e.timeMode===`everyHours`){let r=e.window===null?e.interval===1?`*`:`*/${e.interval}`:e.interval===1?`${e.window.start}-${e.window.end}`:`${e.window.start}-${e.window.end}/${e.interval}`;return`${e.minute} ${r} ${t} * ${n}`}return`${e.minute} ${e.hour} ${t} * ${n}`}var z={scheduled:`live`,suspended:`stood-down`,due:`inert`,cancelled:`inert`,completed:`inert`};function re(e){return e==null||!Object.hasOwn(z,e)?`unknown`:z[e]}var B={scheduled:{control:`suspend`,note:null},suspended:{control:`resume`,note:null},due:{control:`none`,note:`This one-time routine has already been dispatched. It will not run again.`},cancelled:{control:`none`,note:`This routine was cancelled and cannot be restarted. Delete it, or create a new one.`},completed:{control:`none`,note:`This routine has finished and will not run again.`}},ie={control:`none`,note:`This routine's status is not one this dashboard recognises, so no start or stop is offered.`};function ae(e){return e==null||!Object.hasOwn(B,e)?ie:B[e]}var V={finished:`live`,gated:`live`,started:`in-flight`,accepted:`in-flight`,open:`in-flight`,failed:`error`,"no-destination":`warning`};function oe(e){return e==null||!Object.hasOwn(V,e)?`unknown`:V[e]}function H(e){return e===`gated`?`skipped: no work`:e??`unknown`}var U=i(),se=[{value:1,label:`Mon`},{value:2,label:`Tue`},{value:3,label:`Wed`},{value:4,label:`Thu`},{value:5,label:`Fri`},{value:6,label:`Sat`},{value:0,label:`Sun`}],W=Array.from({length:24},(e,t)=>t),G=e=>String(e).padStart(2,`0`),K={timeMode:`at`,minute:0,hour:9,interval:1,window:null,dayMode:`every`,weekdays:[],dayOfMonth:1};function ce({recurrence:e,onChange:t,disabled:n}){let r=e?I(e):K,[i,a]=(0,O.useState)(r??K),[o]=(0,O.useState)(e!=null&&r==null),[s,c]=(0,O.useState)(e??``);if((0,O.useEffect)(()=>{fetch(`/api/_client-error`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({kind:`event`,source:`routines`,op:`schedule-editor`,mode:o?`raw`:`builder`}),keepalive:!0}).catch(()=>{})},[o]),o)return(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Schedule (advanced)`}),(0,U.jsx)(`input`,{type:`text`,className:`routine-raw-cron`,value:s,disabled:n,onChange:e=>{c(e.target.value),t(e.target.value)},"aria-label":`Cron expression`}),(0,U.jsx)(`span`,{className:`routine-raw-note`,children:`This routine uses an advanced schedule, edited as a raw cron expression.`})]});let l=e=>{a(e),t(R(e))},u=e=>{let t=e!==`at`&&i.dayMode===`dayOfMonth`?`every`:i.dayMode;l({...i,timeMode:e,dayMode:t})},d=e=>{let t=e===`weekdays`&&i.weekdays.length===0?[1]:i.weekdays;l({...i,dayMode:e,weekdays:t})},f=e=>{let[t,n]=e.split(`:`);l({...i,hour:Number(t)||0,minute:Number(n)||0})},p=e=>{let t=i.weekdays.includes(e);if(t&&i.weekdays.length===1)return;let n=t?i.weekdays.filter(t=>t!==e):[...i.weekdays,e];l({...i,weekdays:n})},m=e=>l({...i,window:e?{start:0,end:23}:null}),h=(e,t)=>{let n={...i.window??{start:0,end:23},[e]:Number(t)};n.start>n.end&&(e===`start`?n.end=n.start:n.start=n.end),l({...i,window:n})},g=(e,t,n)=>Math.min(n,Math.max(t,Number(e)||t));return(0,U.jsxs)(`div`,{className:`routine-sched`,children:[(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`How often`}),(0,U.jsxs)(`select`,{"aria-label":`How often`,value:i.timeMode,disabled:n,onChange:e=>u(e.target.value),children:[(0,U.jsx)(`option`,{value:`at`,children:`At a time of day`}),(0,U.jsx)(`option`,{value:`everyMinutes`,children:`Every few minutes`}),(0,U.jsx)(`option`,{value:`everyHours`,children:`Every few hours`})]})]}),i.timeMode===`at`&&(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Time of day`}),(0,U.jsx)(`input`,{type:`time`,"aria-label":`Time of day`,value:`${G(i.hour)}:${G(i.minute)}`,disabled:n,onChange:e=>f(e.target.value)})]}),i.timeMode===`everyMinutes`&&(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Minutes between runs`}),(0,U.jsx)(`input`,{type:`number`,min:1,max:59,"aria-label":`Minutes between runs`,value:i.interval,disabled:n,onChange:e=>l({...i,interval:g(e.target.value,1,59)})})]}),i.timeMode===`everyHours`&&(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Hours between runs`}),(0,U.jsx)(`input`,{type:`number`,min:1,max:23,"aria-label":`Hours between runs`,value:i.interval,disabled:n,onChange:e=>l({...i,interval:g(e.target.value,1,23)})})]}),(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Minute of the hour`}),(0,U.jsx)(`input`,{type:`number`,min:0,max:59,"aria-label":`Minute of the hour`,value:i.minute,disabled:n,onChange:e=>l({...i,minute:g(e.target.value,0,59)})})]})]}),i.timeMode!==`at`&&(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`label`,{className:`cal-modal-field routine-sched-check`,children:[(0,U.jsx)(`input`,{type:`checkbox`,"aria-label":`Only between certain hours`,checked:i.window!==null,disabled:n,onChange:e=>m(e.target.checked)}),(0,U.jsx)(`span`,{children:`Only between certain hours`})]}),i.window!==null&&(0,U.jsxs)(`div`,{className:`routine-sched-row`,children:[(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`From hour`}),(0,U.jsx)(`select`,{"aria-label":`From hour`,value:i.window.start,disabled:n,onChange:e=>h(`start`,e.target.value),children:W.map(e=>(0,U.jsxs)(`option`,{value:e,children:[G(e),`:00`]},e))})]}),(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`To hour`}),(0,U.jsx)(`select`,{"aria-label":`To hour`,value:i.window.end,disabled:n,onChange:e=>h(`end`,e.target.value),children:W.map(e=>(0,U.jsxs)(`option`,{value:e,children:[G(e),`:00`]},e))})]})]})]}),(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Which days`}),(0,U.jsxs)(`select`,{"aria-label":`Which days`,value:i.dayMode,disabled:n,onChange:e=>d(e.target.value),children:[(0,U.jsx)(`option`,{value:`every`,children:`Every day`}),(0,U.jsx)(`option`,{value:`weekdays`,children:`Specific days`}),i.timeMode===`at`&&(0,U.jsx)(`option`,{value:`dayOfMonth`,children:`A day of the month`})]})]}),i.dayMode===`weekdays`&&(0,U.jsxs)(`div`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Days`}),(0,U.jsx)(`div`,{className:`routine-weekdays`,children:se.map(e=>(0,U.jsx)(`button`,{type:`button`,className:`routine-weekday${i.weekdays.includes(e.value)?` routine-weekday-on`:``}`,"aria-pressed":i.weekdays.includes(e.value),disabled:n,onClick:()=>p(e.value),children:e.label},e.value))})]}),i.dayMode===`dayOfMonth`&&(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Day of month`}),(0,U.jsx)(`select`,{"aria-label":`Day of month`,value:i.dayOfMonth,disabled:n,onChange:e=>l({...i,dayOfMonth:Number(e.target.value)||1}),children:Array.from({length:31},(e,t)=>t+1).map(e=>(0,U.jsx)(`option`,{value:e,children:e},e))})]})]})}function q(e){let t=e.trim().replace(/[\s\-().]/g,``).replace(/^\+/,``);return/^\d{11,15}$/.test(t)?`+${t.slice(0,2)} ${t.slice(2,6)} ${t.slice(6)}`:e}function le(e){if(e.name)return`${e.name} · ${e.label}`;let t=e.channel===`whatsapp`?q(e.destination):e.destination;return`${e.label} · ${t}`}function ue({eventStatus:e}){let t=re(e);return(0,U.jsx)(`span`,{className:`routine-status-dot is-${t}`,"data-state":t,"aria-hidden":`true`})}function de(e){return e.agentChannel==null?e.actionPlugin==null?`trigger`:`deterministic`:e.gateTool==null?`agent-every-fire`:`checked-agent`}var fe={"checked-agent":`checks first, model only when there is work`,"agent-every-fire":`model every fire`,deterministic:`runs a tool, no model`,trigger:null};function pe(e){return e.agentChannel&&e.agentDestination&&e.agentPrompt?`model`:e.actionPlugin&&e.actionTool?`tool`:`none`}function me(e){let t=e.filter(e=>e.eventStatus===`scheduled`&&e.recurrence!=null),n={live:t.length,model:0,tool:0,none:0};for(let e of t)n[pe(e)]++;return n}function he(e){if(!e)return[];let t;try{t=JSON.parse(e)}catch{return[]}let n=t?.checks;return Array.isArray(n)?n.flatMap(e=>{if(typeof e!=`object`||!e)return[];let t=e;return typeof t.type==`string`?[{kind:t.type,target:J(t.type,t)}]:[]}):[]}function J(e,t){let n=e=>typeof t[e]==`string`?t[e]:null;if(e===`mail`){let e=n(`mailbox`);if(e===null)return null;let t=n(`folder`);return t?`${e}/${t}`:e}return e===`d1`?n(`database`):e===`whatsapp`?n(`scope`):e===`calendar`?n(`connector`):null}function ge(e,t){if(!e)return null;let n=Date.parse(e);if(!Number.isFinite(n))return null;let r=Math.max(t-n,0);return r<6e4?`${Math.round(r/1e3)}s ago`:r<36e5?`${Math.round(r/6e4)}m ago`:`${Math.round(r/36e5)}h ago`}function _e(e,t){if(!e)return`—`;let n=Date.parse(e);return Number.isFinite(n)?p(new Date(n).toISOString(),t):e}function ve(e){return e?e.split(`
|
|
2
|
-
`).filter(e=>e.trim()!==``).reverse():[]}function Y({routine:e,adminFetch:t,onClose:n,onSaved:r,onDeleted:i,onViewRuns:a}){let{zone:o}=y(),[l,d]=(0,O.useState)(!1),[f,p]=(0,O.useState)(!1),[m,g]=(0,O.useState)(null),[b,S]=(0,O.useState)(e),[w,T]=(0,O.useState)(!1),D=b.agentChannel!=null,k=de(b),A=he(b.gateArgs),j=ge(b.gateLastCommitAt,Date.now()),M=ae(b.eventStatus),P=M.control===`resume`,[F,I]=(0,O.useState)(!1),[L,R]=(0,O.useState)(e.agentPrompt??``),[z,re]=(0,O.useState)(e.name??``),[B,ie]=(0,O.useState)(e.description??``),[V,oe]=(0,O.useState)(e.recurrence),[H,se]=(0,O.useState)(e.agentChannel??``),[W,G]=(0,O.useState)(e.agentDestination??``),[K,q]=(0,O.useState)(null),[pe,me]=(0,O.useState)(null),J=D||b.actionPlugin==null,Y=ve(b.notes);(0,O.useEffect)(()=>{let e=e=>{e.key===`Escape`&&!f&&n()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[f,n]),(0,O.useEffect)(()=>{if(!l||!J||K!==null)return;let e=!1;return t(`/api/admin/dispatch-destinations`).then(async e=>{if(!e.ok)throw Error(`HTTP ${e.status}`);return await e.json()}).then(t=>{e||q(t.destinations)}).catch(t=>{e||(q([]),me(t instanceof Error?t.message:`Could not load destinations`))}),()=>{e=!0}},[l,J,K,t]);let X=(K??[]).filter(e=>e.channel===H),Z=H.length>0&&W.length>0,ye=z.trim().length===0&&(b.name??``).length>0||H.length>0&&W.length===0||Z&&L.trim().length===0,be=(0,O.useCallback)(()=>{let e={},t=H.length>0&&W.length>0,n=z.trim();n!==(b.name??``)&&(e.name=n),(D||t)&&L!==(b.agentPrompt??``)&&(e.agentPrompt=L);let r=B.trim().length>0?B:null;return r!==(b.description??null)&&(e.description=r),V!=null&&V!==(b.recurrence??null)&&(e.recurrence=V),t&&(H!==(b.agentChannel??``)||W!==(b.agentDestination??``))?(e.agentChannel=H,e.agentDestination=W):!t&&H===``&&(b.agentChannel??``)!==``&&(e.agentChannel=null,e.agentDestination=null),e},[D,z,L,B,V,H,W,b]),Q=(0,O.useCallback)(async()=>{let n=be();if(Object.keys(n).length===0){d(!1);return}p(!0),g(null);try{let i=await t(`/api/admin/routines/${encodeURIComponent(e.eventId)}`,{method:`PATCH`,headers:{"content-type":`application/json`},body:JSON.stringify(n)});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.error??`HTTP ${i.status}`)}let a=await i.json();S(a.routine),re(a.routine.name??``),R(a.routine.agentPrompt??``),ie(a.routine.description??``),oe(a.routine.recurrence),se(a.routine.agentChannel??``),G(a.routine.agentDestination??``),r(a.routine),d(!1)}catch(e){g(e instanceof Error?e.message:`Save failed`)}finally{p(!1)}},[t,be,e.eventId,r]),xe=(0,O.useCallback)(async()=>{if(f)return;if(!F){T(!1),I(!0);return}let n=P?`resume`:`suspend`;p(!0),g(null);try{let i=await t(`/api/admin/routines/${encodeURIComponent(e.eventId)}/${n}`,{method:`POST`});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.error??`HTTP ${i.status}`)}let a=await i.json();S(a.routine),r(a.routine),I(!1)}catch(e){g(e instanceof Error?e.message:`${n} failed`),I(!1)}finally{p(!1)}},[t,f,F,P,e.eventId,r]),Se=(0,O.useCallback)(async()=>{if(!f){if(!w){I(!1),T(!0);return}p(!0),g(null);try{let n=await t(`/api/admin/routines/${encodeURIComponent(e.eventId)}`,{method:`DELETE`});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`HTTP ${n.status}`)}i(e.eventId)}catch(e){g(e instanceof Error?e.message:`Delete failed`),T(!1)}finally{p(!1)}}},[t,f,w,e.eventId,i]);return(0,U.jsx)(`div`,{className:`cal-modal-overlay`,onClick:()=>{f||n()},children:(0,U.jsxs)(`div`,{className:`cal-modal ${!l||D||Z?`cal-modal-wide`:`cal-modal-dispatch`}`,role:`dialog`,"aria-modal":`true`,"aria-label":l?`Edit routine`:`Routine detail`,onClick:e=>e.stopPropagation(),children:[(0,U.jsxs)(`div`,{className:`cal-modal-header`,children:[(0,U.jsxs)(`span`,{className:`cal-modal-kind`,children:[(0,U.jsx)(x,{size:13}),` Routine`]}),(0,U.jsx)(`button`,{type:`button`,className:`cal-modal-close`,onClick:n,"aria-label":`Close`,autoFocus:!0,disabled:f,children:(0,U.jsx)(h,{size:16})})]}),!l&&(0,U.jsxs)(`div`,{className:`cal-modal-body`,children:[(0,U.jsx)(`div`,{className:`cal-modal-title`,children:b.name??`Untitled routine`}),(0,U.jsxs)(`div`,{className:`cal-modal-row`,children:[(0,U.jsx)(C,{size:14}),(0,U.jsx)(`span`,{children:b.recurrence?N(b.recurrence):`One-time`})]}),(0,U.jsxs)(`div`,{className:`cal-modal-row cal-modal-meta`,children:[(0,U.jsx)(ue,{eventStatus:b.eventStatus}),(0,U.jsxs)(`span`,{children:[`Status: `,b.eventStatus??`unknown`]})]}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsxs)(`span`,{children:[`Next run: `,_e(b.nextRun,o)]})}),(0,U.jsxs)(`div`,{className:`cal-modal-row cal-modal-meta`,children:[(0,U.jsx)(E,{size:14}),(0,U.jsxs)(`span`,{children:[`Last run: `,_e(b.lastTriggered,o),b.lastDispatchResult?` (${b.lastDispatchResult})`:``]})]}),b.description&&(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsx)(`span`,{children:`Description`})}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-row-top routine-prose`,children:(0,U.jsx)(`span`,{children:b.description})})]}),fe[k]&&(0,U.jsxs)(`div`,{className:`cal-modal-row cal-modal-meta`,"data-testid":`routine-mode`,children:[(0,U.jsx)(x,{size:14}),(0,U.jsxs)(`span`,{children:[fe[k],k===`agent-every-fire`&&b.gateWaived?`: ${b.gateWaived}`:``]})]}),b.gateClassified===!1&&b.gateTool==null&&(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,"data-testid":`gate-unclassified`,children:(0,U.jsx)(`span`,{children:`No check is set and no reason is recorded, so every fire spends a model turn.`})}),D?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`div`,{className:`cal-modal-row`,children:[(0,U.jsx)(_,{channel:b.agentChannel,size:14}),(0,U.jsxs)(`span`,{children:[v[b.agentChannel]??b.agentChannel,` to `,b.agentDestination??`—`]})]}),b.gateTool!=null&&(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsx)(`span`,{children:`Checks before the agent runs`})}),(0,U.jsxs)(`div`,{className:`cal-modal-row`,children:[(0,U.jsx)(ee,{size:14}),(0,U.jsxs)(`span`,{children:[b.gatePlugin,`.`,b.gateTool]})]}),A.map((e,t)=>(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,"data-testid":`gate-check`,children:(0,U.jsxs)(`span`,{children:[e.kind,e.target?` · ${e.target}`:``]})},t)),b.lastTriggered!=null&&(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,"data-testid":`gate-commit-age`,children:(0,U.jsx)(`span`,{children:j===null?`This gate has never committed, so it reports work on every fire.`:`Checks last committed ${j} (${_e(b.gateLastCommitAt,o)})`})})]}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsx)(`span`,{children:`Instruction sent to the agent`})}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-row-top routine-prose`,children:(0,U.jsx)(`span`,{children:b.agentPrompt??`No instruction sent to the agent.`})})]}):b.actionPlugin?(0,U.jsxs)(`div`,{className:`cal-modal-row`,children:[(0,U.jsx)(ee,{size:14}),(0,U.jsxs)(`span`,{children:[b.actionPlugin,`.`,b.actionTool,b.actionArgs?` ${b.actionArgs}`:``]})]}):(0,U.jsxs)(`div`,{className:`cal-modal-row`,children:[(0,U.jsx)(C,{size:14}),(0,U.jsx)(`span`,{children:`Scheduled trigger (no dispatch)`})]}),Y.length===0?(0,U.jsxs)(`div`,{className:`cal-modal-row cal-modal-meta`,children:[(0,U.jsx)(E,{size:14}),(0,U.jsx)(`span`,{children:`No history recorded.`})]}):(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`div`,{className:`cal-modal-row cal-modal-meta`,children:[(0,U.jsx)(E,{size:14}),(0,U.jsxs)(`span`,{children:[`History (`,Y.length,` `,Y.length===1?`entry`:`entries`,`)`]})]}),(0,U.jsx)(`div`,{className:`routine-history`,children:Y.map((e,t)=>(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:e},t))})]})]}),l&&(0,U.jsxs)(`div`,{className:`cal-modal-body`,children:[(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Name`}),(0,U.jsx)(`input`,{type:`text`,value:z,onChange:e=>re(e.target.value),disabled:f,maxLength:200,placeholder:`The routine's title, shown on the card`})]}),J&&(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Send to`}),(0,U.jsxs)(`div`,{className:`cal-modal-field-inline`,children:[(0,U.jsxs)(`select`,{value:H,disabled:f,onChange:e=>{se(e.target.value),G(``)},children:[(0,U.jsx)(`option`,{value:``,children:`None (no dispatch)`}),(0,U.jsx)(`option`,{value:`whatsapp`,children:`WhatsApp`}),(0,U.jsx)(`option`,{value:`telegram`,children:`Telegram`})]}),H!==``&&(0,U.jsx)(_,{channel:H,size:16})]})]}),H!==``&&(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Destination`}),(0,U.jsxs)(`select`,{value:W,disabled:f||K===null,onChange:e=>G(e.target.value),children:[(0,U.jsx)(`option`,{value:``,children:K===null?`Loading destinations`:X.length===0?`No registered destinations`:`Choose a destination`}),W!==``&&!X.some(e=>e.destination===W)&&(0,U.jsxs)(`option`,{value:W,children:[W,` (not in the current list)`]}),X.map(e=>(0,U.jsx)(`option`,{value:e.destination,children:le(e)},e.destination))]})]}),pe&&(0,U.jsxs)(`div`,{className:`cal-modal-error`,children:[`Could not load destinations: `,pe]})]}),(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Description`}),(0,U.jsx)(`input`,{type:`text`,value:B,onChange:e=>ie(e.target.value),disabled:f,placeholder:`One line: what this routine is for`})]}),(D||Z)&&(0,U.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,U.jsx)(`span`,{children:`Instruction sent to the agent`}),(0,U.jsx)(`textarea`,{className:`cal-modal-textarea`,value:L,onChange:e=>R(e.target.value),disabled:f,rows:16,placeholder:`What should the agent do when this routine fires?`})]}),(0,U.jsx)(ce,{recurrence:b.recurrence,onChange:oe,disabled:f})]}),m&&(0,U.jsx)(`div`,{className:`cal-modal-error`,children:m}),(0,U.jsxs)(`div`,{className:`cal-modal-actions`,children:[!l&&(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:()=>{T(!1),I(!1),d(!0)},disabled:f,children:[(0,U.jsx)(s,{size:14}),` Edit`]}),(0,U.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:()=>a(b),disabled:f,children:[(0,U.jsx)(E,{size:14}),` Runs`]}),M.control===`none`?(0,U.jsx)(`span`,{className:`cal-modal-confirm-text`,children:M.note}):(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:xe,disabled:f,children:[f&&F?(0,U.jsx)(u,{size:14,className:`spin`}):P?(0,U.jsx)(ne,{size:14}):(0,U.jsx)(te,{size:14}),F?P?`Confirm resume`:`Confirm suspend`:P?`Resume`:`Suspend`]}),F&&(0,U.jsx)(`span`,{className:`cal-modal-confirm-text`,children:P?`This routine will run at its next scheduled time. It will not run for the times it missed.`:`This routine stops running until you resume it. Nothing is deleted.`})]}),(0,U.jsxs)(`button`,{type:`button`,className:`cal-modal-btn cal-modal-btn-danger`,onClick:Se,disabled:f,children:[f&&w?(0,U.jsx)(u,{size:14,className:`spin`}):(0,U.jsx)(c,{size:14}),w?`Confirm delete`:`Delete`]})]}),l&&(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`button`,{type:`button`,className:`cal-modal-btn cal-modal-btn-primary`,onClick:Q,disabled:f||ye,children:[f?(0,U.jsx)(u,{size:14,className:`spin`}):null,` Save`]}),(0,U.jsx)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:()=>{d(!1),g(null)},disabled:f,children:`Cancel`})]})]})]})})}function X(e,t){if(!e)return`—`;let n=Date.parse(e);return Number.isFinite(n)?p(new Date(n).toISOString(),t):e}function Z(e){return e===null?`—`:e<1e3?`${e} ms`:`${(e/1e3).toFixed(1)} s`}function ye({run:e,routineName:t,onClose:n}){let{zone:r}=y();return(0,O.useEffect)(()=>{let e=e=>{e.key===`Escape`&&n()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[n]),(0,U.jsx)(`div`,{className:`cal-modal-overlay`,onClick:n,children:(0,U.jsxs)(`div`,{className:`cal-modal cal-modal-wide`,role:`dialog`,"aria-modal":`true`,"aria-label":`Run detail`,onClick:e=>e.stopPropagation(),children:[(0,U.jsxs)(`div`,{className:`cal-modal-header`,children:[(0,U.jsx)(`span`,{className:`cal-modal-kind`,children:`Run`}),(0,U.jsx)(`button`,{type:`button`,className:`cal-modal-close`,onClick:n,"aria-label":`Close`,autoFocus:!0,children:(0,U.jsx)(h,{size:16})})]}),(0,U.jsxs)(`div`,{className:`cal-modal-body`,children:[(0,U.jsx)(`div`,{className:`cal-modal-title`,children:t??`Untitled routine`}),e.outputExcerpt!==null&&(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-row-top routine-prose`,"data-testid":`run-output`,children:(0,U.jsx)(`span`,{children:e.outputExcerpt})}),e.outputExcerpt===null&&e.status===`finished`&&(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,"data-testid":`run-output-none`,children:(0,U.jsx)(`span`,{children:`This run finished without sending anything.`})}),(0,U.jsx)(`div`,{className:`cal-modal-row`,children:(0,U.jsx)(`span`,{children:H(e.status)})}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsxs)(`span`,{children:[`Due: `,X(e.scheduledFor,r)]})}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsxs)(`span`,{children:[`Started: `,X(e.startedAt,r)]})}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsxs)(`span`,{children:[`Dispatch ended: `,X(e.endedAt,r),` (`,Z(e.ranMs),`)`]})}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsxs)(`span`,{children:[`Output seen: `,X(e.finishedAt,r)]})}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsxs)(`span`,{children:[`Sent to: `,e.target,` · `,e.mode,` · `,e.kind]})}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsxs)(`span`,{children:[`Transport: `,e.dispatchResult??`—`,e.httpStatus===null?``:` (HTTP ${e.httpStatus})`]})}),e.error&&(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-row-top routine-prose`,children:(0,U.jsx)(`span`,{children:e.error})}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsxs)(`span`,{children:[`Conversation: `,e.sessionKey??`—`,e.transcriptOffset===null?``:` at byte ${e.transcriptOffset}`]})}),!e.bounded&&e.status!==`gated`&&(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsx)(`span`,{children:`This run shares its conversation with other traffic, so what it produced cannot be separated out. Its status stays at whatever the dispatch reported.`})}),(0,U.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,U.jsxs)(`span`,{children:[`Run `,e.runId]})})]})]})})}function be({status:e}){let t=oe(e);return(0,U.jsx)(`span`,{className:`routine-status-dot is-${t}`,"data-state":t,"aria-hidden":`true`})}var Q=500;function xe(e,t){if(!e)return`—`;let n=Date.parse(e);return Number.isFinite(n)?p(new Date(n).toISOString(),t):e}function Se(e){return e===null?`—`:e<1e3?`${e} ms`:`${(e/1e3).toFixed(1)} s`}var Ce={channel:`a channel`,destination:`a destination`,prompt:`an instruction`};function we(e){if(e===`no-dispatch-configured`)return`This routine has no dispatch set up, so there was nothing to do.`;if(e===`no-action-plugin`)return`The tool action names no plugin, so nothing ran.`;if(e===`no-action-tool`)return`The tool action names no tool, so nothing ran.`;let t=e.startsWith(`no-`)?e.slice(3).split(`+`):[];if(t.length>0&&t.every(e=>e in Ce)){let e=t.map(e=>Ce[e]);return`This routine has no ${(e.length===1?e[0]:`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`).replace(/^an? /,``)} set, so nothing was sent.`}return e}function Te(e){return e.status===`no-destination`?e.error?we(e.error):`Nothing was dispatched, and no reason was recorded.`:e.status===`failed`?e.error??e.dispatchResult??`The dispatch failed.`:e.status===`open`?`Opened and never closed. The dispatch did not report back.`:null}function Ee(e){let t=e.indexOf(`:`);return t<=0?{channel:null,destination:e}:{channel:e.slice(0,t),destination:e.slice(t+1)}}function De(e){return e.outputExcerpt===null?e.status===`finished`?`Finished and sent nothing.`:null:e.outputExcerpt}function Oe({routine:e,adminFetch:t,cacheKey:n,from:r=`card`,onBack:i}){let{zone:s}=y(),[c,l]=(0,O.useState)([]),[f,p]=(0,O.useState)(!0),[m,h]=(0,O.useState)(null),[g,b]=(0,O.useState)(null),x=(0,O.useRef)(0),S=(0,O.useCallback)(()=>{let n=!1,i=++x.current,a=()=>n||i!==x.current;return p(!0),h(null),t(`/api/admin/routines/${encodeURIComponent(e.eventId)}/runs?limit=${Q}&from=${r}`).then(async e=>{if(a())return;if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();a()||l(Array.isArray(t.runs)?t.runs:[])}).catch(e=>{a()||(h(e instanceof Error?e.message:`Failed to load`),l([]))}).finally(()=>{a()||p(!1)}),()=>{n=!0}},[t,e.eventId,r]);(0,O.useEffect)(()=>S(),[S]);let C=(0,O.useCallback)(()=>{T(n,e.eventId)},[n,e.eventId]);return(0,U.jsxs)(`div`,{className:`cal-page`,children:[(0,U.jsx)(`header`,{className:`cal-header`,children:(0,U.jsxs)(`div`,{className:`cal-nav`,children:[(0,U.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:i,children:[(0,U.jsx)(d,{size:14}),` Routines`]}),(0,U.jsx)(`span`,{className:`cal-range-label runs-title`,"data-testid":`runs-title`,title:e.name??`Untitled routine`,children:e.name??`Untitled routine`}),(0,U.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,"data-testid":`runs-refresh`,onClick:S,disabled:f,title:`Refresh runs`,"aria-label":`Refresh runs`,children:[f?(0,U.jsx)(u,{size:14,className:`spin`}):(0,U.jsx)(a,{size:14}),` Refresh`]}),c.length>0&&(0,U.jsx)(`div`,{className:`routine-bulk-actions`,children:(0,U.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:C,children:[(0,U.jsx)(o,{size:14}),` Download all runs`]})})]})}),(0,U.jsxs)(`div`,{className:`cal-body`,children:[m&&(0,U.jsxs)(`div`,{className:`cal-error`,children:[`Could not load runs: `,m]}),!m&&!f&&c.length===0&&(0,U.jsxs)(`div`,{className:`cal-empty`,"data-testid":`runs-empty`,children:[(0,U.jsx)(`p`,{children:`Nothing to show for this routine.`}),(0,U.jsx)(`p`,{children:`That means one of three things, and this page cannot tell them apart: it has never run, it ran but no record was written, or every run it did have is older than the 30 days records are kept for.`}),(0,U.jsxs)(`p`,{children:[`For a repeating routine, the server log settles the middle one: a`,(0,U.jsx)(`code`,{children:` fires-without-records `}),` count above zero names a routine that fired and left no record. It does not distinguish the other two, and it does not cover a one-time routine.`]})]}),c.length>=Q&&(0,U.jsxs)(`div`,{className:`cal-modal-confirm-text`,"data-testid":`runs-capped`,children:[`Showing the most recent `,Q,` runs. There may be more; the download has everything still on record.`]}),(0,U.jsx)(`div`,{className:`routine-list`,children:c.map(e=>{let t=Te(e),n=De(e),{channel:r,destination:i}=Ee(e.target);return(0,U.jsxs)(`button`,{type:`button`,className:`admin-card admin-card--padded routine-card`,"data-testid":`run-row-${e.runId}`,onClick:()=>b(e),children:[(0,U.jsxs)(`span`,{className:`admin-card-title routine-card-title run-card-title`,children:[(0,U.jsx)(be,{status:e.status}),` `,H(e.status)]}),(0,U.jsx)(`span`,{className:`routine-card-sched`,children:Se(e.ranMs)}),(0,U.jsx)(`span`,{className:`routine-card-target`,children:r?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(_,{channel:r,size:13}),` `,v[r]??r,` to `,r===`whatsapp`?q(i):i]}):i}),(0,U.jsxs)(`span`,{className:`routine-card-meta`,children:[`Due `,xe(e.scheduledFor,s)]}),n&&(0,U.jsx)(`span`,{className:`routine-card-meta run-card-output`,children:n}),t&&(0,U.jsx)(`span`,{className:`routine-card-meta run-card-detail`,children:t})]},e.runId)})})]}),g&&(0,U.jsx)(ye,{run:g,routineName:e.name,onClose:()=>b(null)})]})}t(((e,t)=>{t.exports={}}))();function ke(e){return e.agentChannel&&e.agentDestination&&e.agentPrompt?!0:!!(e.actionPlugin&&e.actionTool)}function Ae(e){if(e.agentChannel||e.agentDestination||e.agentPrompt){let t=[];return e.agentChannel||t.push(`channel`),e.agentDestination||t.push(`destination`),e.agentPrompt||t.push(`prompt`),`no-${t.join(`+`)}`}return e.actionPlugin||e.actionTool?e.actionTool?`no-action-plugin`:`no-action-tool`:`no-dispatch-configured`}var $=`maxy-admin-session-key`;function je(e){return e?N(e):`One-time`}function Me(e,t){if(!e)return`—`;let n=Date.parse(e);return Number.isFinite(n)?p(new Date(n).toISOString(),t):e}function Ne(){let[e,t]=(0,O.useState)(null),[n,r]=(0,O.useState)(!1),[i,a]=(0,O.useState)(void 0),[o,s]=(0,O.useState)(null),[c,u]=(0,O.useState)(void 0),[d,f]=(0,O.useState)(null),[p,m]=(0,O.useState)(null);(0,O.useEffect)(()=>{let e=!1,n=null;try{n=sessionStorage.getItem($)}catch{}if(!n){r(!0);return}return fetch(`/api/admin/session?session_key=${encodeURIComponent(n)}`).then(async i=>{if(!e){if(i.status===401){try{sessionStorage.removeItem($)}catch{}window.location.href=`/`;return}if(i.ok)try{let e=await i.json();typeof e.businessName==`string`&&a(e.businessName),e.sessionId!==void 0&&s(e.sessionId??null),m(e.role??null),u(e.userName===void 0?null:e.userName),f(e.avatar??null)}catch{}t(n),r(!0)}}).catch(()=>{e||(t(n),r(!0))}),()=>{e=!0}},[]);let h=(0,O.useCallback)(()=>{try{sessionStorage.removeItem($)}catch{}window.location.href=`/`},[]),[_,v]=(0,O.useState)(!1),y=(0,O.useCallback)(async()=>{v(!0);try{let e=await b();if(e){try{sessionStorage.removeItem($)}catch{}window.location.href=`/`}return e}finally{v(!1)}},[]);return n?e?(0,U.jsx)(g,{cacheKey:e,surface:`routines`,onSessionExpired:({code:e,path:t})=>{console.warn(`[admin-auth] outcome=session-expired-redirect code=${e} path=${t} surface=routines`);try{sessionStorage.removeItem($)}catch{}window.location.href=`/`},children:(0,U.jsx)(S,{cacheKey:e,businessName:i,sessionId:o,onLogout:h,onDisconnect:y,disconnecting:_,userName:c,userAvatar:d,role:p,children:(0,U.jsx)(Pe,{cacheKey:e})})}):(0,U.jsx)(`div`,{className:`cal-page`,children:(0,U.jsxs)(`div`,{className:`cal-empty`,children:[(0,U.jsx)(`p`,{children:`You are not signed in.`}),(0,U.jsxs)(`p`,{children:[`Open the `,(0,U.jsx)(`a`,{href:`/`,className:`cal-link`,children:`main admin page`}),` and log in, then return here.`]})]})}):(0,U.jsx)(l,{surface:`gate`})}function Pe({cacheKey:e}){let{zone:t}=y(),{adminFetch:n,cacheKey:r,sessionRefetchNonce:i}=m({initialCacheKey:e,surface:`routines`}),[o,s]=(0,O.useState)([]),[c,d]=(0,O.useState)(null),[f,p]=(0,O.useState)(!1),[h,g]=(0,O.useState)(!1),[b,S]=(0,O.useState)(null),[T,E]=(0,O.useState)(null),[D,k]=(0,O.useState)(null),A=(0,O.useCallback)(()=>{let e=!1;return p(!0),S(null),n(`/api/admin/routines`).then(async t=>{if(e)return;if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();s(Array.isArray(n.routines)?n.routines:[]),d(typeof n.workflowRuns24h==`number`?n.workflowRuns24h:null)}).catch(t=>{e||(S(t instanceof Error?t.message:`Failed to load`),s([]),d(null))}).finally(()=>{e||(p(!1),g(!0))}),()=>{e=!0}},[n]);(0,O.useEffect)(()=>A(),[A,i]);let j=(0,O.useCallback)(e=>{s(t=>t.map(t=>t.eventId===e.eventId?e:t)),E(e)},[]),M=(0,O.useCallback)(e=>{s(t=>t.filter(t=>t.eventId!==e)),E(null)},[]),[N,P]=(0,O.useState)(!1),[F,I]=(0,O.useState)(null),L=o.filter(e=>e.eventStatus===`scheduled`).length,R=o.filter(e=>e.suspendedInBulk).length,z=(0,O.useCallback)(async e=>{P(!0),I(null);try{let t=await n(`/api/admin/routines/${e}`,{method:`POST`});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`HTTP ${t.status}`)}let r=await t.json(),i=r.refused?.length??0;I(e===`suspend-all`?`Suspended ${r.suspended??0}. Nothing runs on its own until you resume it.`:`Resumed ${r.restored??0}${i>0?`. ${i} could not be resumed and stayed suspended`:``}. Routines you suspended one at a time are still suspended.`),A()}catch(e){I(e instanceof Error?e.message:`Failed`)}finally{P(!1)}},[n,A]);return h?D?(0,U.jsx)(Oe,{routine:D,adminFetch:n,cacheKey:r,from:`modal`,onBack:()=>k(null)}):(0,U.jsxs)(`div`,{className:`cal-page`,children:[(0,U.jsx)(`header`,{className:`cal-header`,children:(0,U.jsxs)(`div`,{className:`cal-nav`,children:[(0,U.jsxs)(`span`,{className:`cal-range-label`,children:[(0,U.jsx)(x,{size:16}),` Routines`]}),(0,U.jsxs)(`div`,{className:`routine-bulk-actions`,children:[(0,U.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,"data-testid":`routines-refresh`,onClick:A,disabled:f,title:`Refresh routines`,"aria-label":`Refresh routines`,children:[f?(0,U.jsx)(u,{size:14,className:`spin`}):(0,U.jsx)(a,{size:14}),` Refresh`]}),(0,U.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:()=>z(`suspend-all`),disabled:N||L===0,children:[(0,U.jsx)(te,{size:14}),` Suspend all (`,L,`)`]}),(0,U.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:()=>z(`resume-all`),disabled:N||R===0,children:[(0,U.jsx)(ne,{size:14}),` Resume all (`,R,`)`]})]})]})}),(0,U.jsxs)(`div`,{className:`cal-body`,children:[!b&&(()=>{let e=me(o);return(0,U.jsxs)(`div`,{className:`routine-rail-strip`,"data-testid":`routine-rail-strip`,children:[`Live recurring: `,e.live,` · `,e.model,` model · `,e.tool,` tool · `,e.none,` no dispatch`,` · `,`Workflow runs (24h): `,c===null?`—`:c]})})(),F&&(0,U.jsx)(`div`,{className:`cal-modal-confirm-text`,children:F}),b&&(0,U.jsxs)(`div`,{className:`cal-error`,children:[`Could not load routines: `,b]}),!b&&!f&&o.length===0&&(0,U.jsx)(`div`,{className:`cal-empty`,children:(0,U.jsx)(`p`,{children:`No routines yet.`})}),(0,U.jsx)(`div`,{className:`routine-list`,children:o.map(e=>{let n=e.eventStatus===`scheduled`&&!ke(e)?Ae(e):null;return(0,U.jsxs)(`div`,{role:`button`,tabIndex:0,className:`admin-card admin-card--padded routine-card`,"data-testid":`routine-card-${e.eventId}`,onClick:()=>E(e),onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),E(e))},children:[(0,U.jsx)(`span`,{className:`admin-card-title routine-card-title`,title:e.name??`Untitled routine`,children:e.name??`Untitled routine`}),(0,U.jsxs)(`span`,{className:`routine-card-sched`,children:[(0,U.jsx)(C,{size:13}),` `,je(e.recurrence)]}),e.description&&(0,U.jsx)(`span`,{className:`routine-card-desc`,children:e.description}),n===null?(0,U.jsx)(`span`,{className:`routine-card-target`,children:e.agentChannel?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(_,{channel:e.agentChannel,size:13}),` `,v[e.agentChannel]??e.agentChannel,` to `,e.agentDestination??`—`]}):e.actionPlugin?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(ee,{size:13}),` `,e.actionPlugin,`.`,e.actionTool]}):(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(C,{size:13}),` Scheduled trigger`]})}):(0,U.jsxs)(`span`,{className:`routine-card-target routine-card-target--gap`,children:[(0,U.jsx)(w,{size:13}),` `,we(n)]}),e.dispatchFailing===!0&&n===null&&(0,U.jsxs)(`span`,{className:`routine-card-target routine-card-target--gap`,"data-testid":`routine-dispatch-${e.eventId}`,children:[(0,U.jsx)(w,{size:13}),` Last dispatch failed: `,e.lastDispatchResult]}),(()=>{let t=[],n=fe[de(e)];n&&t.push(n),e.runs24h>0&&t.push(`24h: ${e.runs24h} ${e.runs24h===1?`fire`:`fires`}, ${e.gated24h} skipped`);let r=e.gateNeverGates===!0&&e.dispatchFailing!==!0;return r&&t.push(`this gate is decoration`),t.length===0?null:(0,U.jsx)(`span`,{className:r?`routine-card-gate routine-card-target--gap`:`routine-card-gate`,"data-testid":`routine-gate-${e.eventId}`,children:r?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(w,{size:13}),` `,t.join(` · `)]}):t.join(` · `)})})(),(0,U.jsxs)(`span`,{className:`routine-card-meta`,children:[(0,U.jsx)(ue,{eventStatus:e.eventStatus}),`Next: `,Me(e.nextRun,t),` · `,e.eventStatus??`unknown`]})]},e.eventId)})})]}),T&&(0,U.jsx)(Y,{routine:T,adminFetch:n,onClose:()=>E(null),onSaved:j,onDeleted:M,onViewRuns:e=>{E(null),k(e)}})]}):(0,U.jsx)(l,{surface:`gate`})}(0,D.createRoot)(document.getElementById(`root`)).render((0,U.jsx)(Ne,{}));
|
|
Binary file
|
|
Binary file
|