@rubytech/create-maxy-code 0.1.558 → 0.1.559
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/package.json +1 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js +20 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/lib/roster-census.d.ts +14 -0
- package/payload/platform/plugins/admin/mcp/dist/lib/roster-census.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/lib/roster-census.js +18 -0
- package/payload/platform/plugins/admin/mcp/dist/lib/roster-census.js.map +1 -0
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +10 -0
- package/payload/platform/plugins/filesystem/mcp/dist/lib/result.d.ts +5 -1
- package/payload/platform/plugins/filesystem/mcp/dist/lib/result.d.ts.map +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/lib/result.js +4 -1
- package/payload/platform/plugins/filesystem/mcp/dist/lib/result.js.map +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-read.d.ts.map +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-read.js +2 -1
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-read.js.map +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-write.d.ts.map +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-write.js +2 -1
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-write.js.map +1 -1
- package/payload/platform/plugins/scheduling/PLUGIN.md +4 -2
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +15 -3
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-audit.test.js +72 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-audit.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/workflow-census.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/workflow-census.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/workflow-census.test.js +112 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/workflow-census.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts +59 -6
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js +154 -18
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +17 -2
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-list-kind.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-list-kind.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-list-kind.test.js +25 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-list-kind.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.d.ts +15 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.js +66 -46
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.js.map +1 -1
- package/payload/platform/plugins/storage-broker/mcp/dist/index.js +5 -2
- package/payload/platform/plugins/storage-broker/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/url-get/mcp/dist/index.js +13 -13
- package/payload/platform/plugins/url-get/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/workflows/PLUGIN.md +4 -1
- package/payload/platform/plugins/workflows/mcp/dist/__tests__/retry-delay.test.d.ts +2 -0
- package/payload/platform/plugins/workflows/mcp/dist/__tests__/retry-delay.test.d.ts.map +1 -0
- package/payload/platform/plugins/workflows/mcp/dist/__tests__/retry-delay.test.js +33 -0
- package/payload/platform/plugins/workflows/mcp/dist/__tests__/retry-delay.test.js.map +1 -0
- package/payload/platform/plugins/workflows/mcp/dist/index.js +1 -0
- package/payload/platform/plugins/workflows/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/__tests__/step-resolver.test.d.ts +2 -0
- package/payload/platform/plugins/workflows/mcp/dist/lib/__tests__/step-resolver.test.d.ts.map +1 -0
- package/payload/platform/plugins/workflows/mcp/dist/lib/__tests__/step-resolver.test.js +42 -0
- package/payload/platform/plugins/workflows/mcp/dist/lib/__tests__/step-resolver.test.js.map +1 -0
- package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.d.ts +23 -5
- package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.js +20 -12
- package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.d.ts +2 -0
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js +2 -0
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.d.ts +10 -0
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js +53 -7
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js +2 -0
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js.map +1 -1
- package/payload/platform/scripts/__tests__/provision-honours-disabled-agents.test.sh +4 -3
- package/payload/platform/scripts/__tests__/provision-specialist-retirement.test.sh +115 -0
- package/payload/platform/scripts/lib/provision-account-dir.sh +88 -13
- package/payload/platform/scripts/logs-rotate.sh +6 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +16 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-tee.d.ts +16 -0
- package/payload/platform/services/claude-session-manager/dist/pty-tee.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/pty-tee.js +84 -0
- package/payload/platform/services/claude-session-manager/dist/pty-tee.js.map +1 -0
- package/payload/premium-plugins/writer-craft/agents/writer-craft--manuscript-reviewer.md +2 -0
- package/payload/server/public/activity.html +5 -5
- package/payload/server/public/agents.html +4 -4
- package/payload/server/public/assets/{AdminLoginScreens-BUv_EOfw.js → AdminLoginScreens-DLogIsJT.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-DLogIsJT.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-DLogIsJT.js.gz +0 -0
- package/payload/server/public/assets/{AdminShell-BVKfxSgh.js → AdminShell-B67tPTyE.js} +1 -1
- package/payload/server/public/assets/AdminShell-B67tPTyE.js.br +0 -0
- package/payload/server/public/assets/AdminShell-B67tPTyE.js.gz +0 -0
- package/payload/server/public/assets/{activity-CBcvL5MZ.js → activity-AVJSFESV.js} +1 -1
- package/payload/server/public/assets/activity-AVJSFESV.js.br +0 -0
- package/payload/server/public/assets/activity-AVJSFESV.js.gz +0 -0
- package/payload/server/public/assets/{admin-BUor8KRy.js → admin-eFgbld42.js} +1 -1
- package/payload/server/public/assets/admin-eFgbld42.js.br +0 -0
- package/payload/server/public/assets/admin-eFgbld42.js.gz +0 -0
- package/payload/server/public/assets/{agents-Dzx8Uxgz.js → agents-CoWLZMf7.js} +1 -1
- package/payload/server/public/assets/agents-CoWLZMf7.js.br +0 -0
- package/payload/server/public/assets/agents-CoWLZMf7.js.gz +0 -0
- package/payload/server/public/assets/{browser-B7EsGyVd.js → browser-C6K66_fw.js} +1 -1
- package/payload/server/public/assets/browser-C6K66_fw.js.br +0 -0
- package/payload/server/public/assets/browser-C6K66_fw.js.gz +0 -0
- package/payload/server/public/assets/{calendar-D4qD0upn.js → calendar-Dnw_cP4b.js} +1 -1
- package/payload/server/public/assets/calendar-Dnw_cP4b.js.br +0 -0
- package/payload/server/public/assets/calendar-Dnw_cP4b.js.gz +0 -0
- package/payload/server/public/assets/chat-Cm0fkpg1.js +1 -0
- package/payload/server/public/assets/chat-Cm0fkpg1.js.br +0 -0
- package/payload/server/public/assets/chat-Cm0fkpg1.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-CjRH-BtF.js +1 -0
- package/payload/server/public/assets/chevron-left-CjRH-BtF.js.br +0 -0
- package/payload/server/public/assets/clock-wbYEt1kM.js +1 -0
- package/payload/server/public/assets/clock-wbYEt1kM.js.br +0 -0
- package/payload/server/public/assets/clock-wbYEt1kM.js.gz +0 -0
- package/payload/server/public/assets/{copy-CG2tAK16.js → copy-kuNM0Etw.js} +1 -1
- package/payload/server/public/assets/copy-kuNM0Etw.js.br +0 -0
- package/payload/server/public/assets/copy-kuNM0Etw.js.gz +0 -0
- package/payload/server/public/assets/data-c47T2NCd.js +1 -0
- package/payload/server/public/assets/data-c47T2NCd.js.br +1 -0
- package/payload/server/public/assets/data-c47T2NCd.js.gz +0 -0
- package/payload/server/public/assets/{file-text-47cIljhV.js → file-text-BWkobrcx.js} +1 -1
- package/payload/server/public/assets/file-text-BWkobrcx.js.br +0 -0
- package/payload/server/public/assets/file-text-BWkobrcx.js.gz +0 -0
- package/payload/server/public/assets/{graph-CDbi-eqF.js → graph-BGjTL5Vz.js} +1 -1
- package/payload/server/public/assets/graph-BGjTL5Vz.js.br +0 -0
- package/payload/server/public/assets/graph-BGjTL5Vz.js.gz +0 -0
- package/payload/server/public/assets/{graph-labels-Byp2RkVg.js → graph-labels-Dvc5Kw_r.js} +1 -1
- package/payload/server/public/assets/graph-labels-Dvc5Kw_r.js.br +0 -0
- package/payload/server/public/assets/graph-labels-Dvc5Kw_r.js.gz +0 -0
- package/payload/server/public/assets/{operator-t15ZvJER.js → operator-CzBGv_he.js} +1 -1
- package/payload/server/public/assets/operator-CzBGv_he.js.br +0 -0
- package/payload/server/public/assets/operator-CzBGv_he.js.gz +0 -0
- package/payload/server/public/assets/{page-DcKH1PVD.js → page-BIY4Ku8Q.js} +1 -1
- package/payload/server/public/assets/page-BIY4Ku8Q.js.br +0 -0
- package/payload/server/public/assets/page-BIY4Ku8Q.js.gz +0 -0
- package/payload/server/public/assets/{page-CogD1Hho.js → page-DaySqamH.js} +1 -1
- package/payload/server/public/assets/page-DaySqamH.js.br +0 -0
- package/payload/server/public/assets/page-DaySqamH.js.gz +0 -0
- package/payload/server/public/assets/play-C8RA52_i.js +1 -0
- package/payload/server/public/assets/play-C8RA52_i.js.br +0 -0
- package/payload/server/public/assets/play-C8RA52_i.js.gz +0 -0
- package/payload/server/public/assets/{public-UlLvs9vV.js → public-pwDSvhBv.js} +1 -1
- package/payload/server/public/assets/public-pwDSvhBv.js.br +0 -0
- package/payload/server/public/assets/public-pwDSvhBv.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-Dbj7NrEB.js → rotate-ccw-B6s7tkEt.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-B6s7tkEt.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-B6s7tkEt.js.gz +0 -0
- package/payload/server/public/assets/routines-CFlyRdYg.js +2 -0
- package/payload/server/public/assets/routines-CFlyRdYg.js.br +0 -0
- package/payload/server/public/assets/routines-CFlyRdYg.js.gz +0 -0
- package/payload/server/public/assets/{skills-EtKyNK_3.js → skills-C45kfL_Q.js} +1 -1
- package/payload/server/public/assets/skills-C45kfL_Q.js.br +0 -0
- package/payload/server/public/assets/skills-C45kfL_Q.js.gz +0 -0
- package/payload/server/public/assets/{tasks-U0poqfi9.js → tasks-BwoCTCu5.js} +1 -1
- package/payload/server/public/assets/tasks-BwoCTCu5.js.br +0 -0
- package/payload/server/public/assets/tasks-BwoCTCu5.js.gz +0 -0
- package/payload/server/public/assets/{triangle-alert-D7zwttJW.js → triangle-alert-B3bthSzx.js} +1 -1
- package/payload/server/public/assets/triangle-alert-B3bthSzx.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-B3bthSzx.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-Ae_va0Ps.js → useCopyFeedback-BzJAkFEb.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-BzJAkFEb.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-BzJAkFEb.js.gz +0 -0
- package/payload/server/public/assets/{useMediaQuery-HRgPNA8l.css → useMediaQuery-DW_xRrMl.css} +1 -1
- package/payload/server/public/assets/useMediaQuery-DW_xRrMl.css.br +0 -0
- package/payload/server/public/assets/{useMediaQuery-HRgPNA8l.css.gz → useMediaQuery-DW_xRrMl.css.gz} +0 -0
- package/payload/server/public/assets/{useVoiceRecorder-q9U5ahfg.js → useVoiceRecorder-_qI_BAOo.js} +1 -1
- package/payload/server/public/assets/useVoiceRecorder-_qI_BAOo.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-_qI_BAOo.js.gz +0 -0
- package/payload/server/public/assets/{wrench-BmXV4Tmh.js → wrench-Bqux9jaw.js} +1 -1
- package/payload/server/public/assets/wrench-Bqux9jaw.js.br +0 -0
- package/payload/server/public/assets/wrench-Bqux9jaw.js.gz +0 -0
- package/payload/server/public/browser.html +4 -4
- package/payload/server/public/calendar.html +7 -7
- package/payload/server/public/chat.html +13 -13
- package/payload/server/public/data.html +11 -11
- package/payload/server/public/graph.html +9 -9
- package/payload/server/public/index.html +13 -13
- package/payload/server/public/operator.html +14 -14
- package/payload/server/public/public.html +13 -13
- package/payload/server/public/routines.html +7 -7
- package/payload/server/public/skills.html +5 -5
- package/payload/server/public/tasks.html +6 -6
- package/payload/server/server.js +169 -43
- package/payload/server/public/assets/AdminLoginScreens-BUv_EOfw.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-BUv_EOfw.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-BVKfxSgh.js.br +0 -0
- package/payload/server/public/assets/AdminShell-BVKfxSgh.js.gz +0 -0
- package/payload/server/public/assets/activity-CBcvL5MZ.js.br +0 -0
- package/payload/server/public/assets/activity-CBcvL5MZ.js.gz +0 -0
- package/payload/server/public/assets/admin-BUor8KRy.js.br +0 -0
- package/payload/server/public/assets/admin-BUor8KRy.js.gz +0 -0
- package/payload/server/public/assets/agents-Dzx8Uxgz.js.br +0 -0
- package/payload/server/public/assets/agents-Dzx8Uxgz.js.gz +0 -0
- package/payload/server/public/assets/browser-B7EsGyVd.js.br +0 -0
- package/payload/server/public/assets/browser-B7EsGyVd.js.gz +0 -0
- package/payload/server/public/assets/calendar-D4qD0upn.js.br +0 -0
- package/payload/server/public/assets/calendar-D4qD0upn.js.gz +0 -0
- package/payload/server/public/assets/chat-D7LjNerV.js +0 -1
- package/payload/server/public/assets/chat-D7LjNerV.js.br +0 -0
- package/payload/server/public/assets/chat-D7LjNerV.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-CGsW9Vsp.js +0 -1
- package/payload/server/public/assets/chevron-left-CGsW9Vsp.js.br +0 -0
- package/payload/server/public/assets/clock-B_xWWLQW.js +0 -1
- package/payload/server/public/assets/clock-B_xWWLQW.js.br +0 -0
- package/payload/server/public/assets/clock-B_xWWLQW.js.gz +0 -0
- package/payload/server/public/assets/copy-CG2tAK16.js.br +0 -0
- package/payload/server/public/assets/copy-CG2tAK16.js.gz +0 -0
- package/payload/server/public/assets/data-BU60tJiv.js +0 -1
- package/payload/server/public/assets/data-BU60tJiv.js.br +0 -0
- package/payload/server/public/assets/data-BU60tJiv.js.gz +0 -0
- package/payload/server/public/assets/file-text-47cIljhV.js.br +0 -0
- package/payload/server/public/assets/file-text-47cIljhV.js.gz +0 -0
- package/payload/server/public/assets/graph-CDbi-eqF.js.br +0 -0
- package/payload/server/public/assets/graph-CDbi-eqF.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-Byp2RkVg.js.br +0 -0
- package/payload/server/public/assets/graph-labels-Byp2RkVg.js.gz +0 -0
- package/payload/server/public/assets/operator-t15ZvJER.js.br +0 -0
- package/payload/server/public/assets/operator-t15ZvJER.js.gz +0 -0
- package/payload/server/public/assets/page-CogD1Hho.js.br +0 -0
- package/payload/server/public/assets/page-CogD1Hho.js.gz +0 -0
- package/payload/server/public/assets/page-DcKH1PVD.js.br +0 -0
- package/payload/server/public/assets/page-DcKH1PVD.js.gz +0 -0
- package/payload/server/public/assets/play-Bankj0zU.js +0 -1
- package/payload/server/public/assets/play-Bankj0zU.js.br +0 -0
- package/payload/server/public/assets/play-Bankj0zU.js.gz +0 -0
- package/payload/server/public/assets/public-UlLvs9vV.js.br +0 -0
- package/payload/server/public/assets/public-UlLvs9vV.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-Dbj7NrEB.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-Dbj7NrEB.js.gz +0 -0
- package/payload/server/public/assets/routines-CdqGJwyD.js +0 -2
- package/payload/server/public/assets/routines-CdqGJwyD.js.br +0 -0
- package/payload/server/public/assets/routines-CdqGJwyD.js.gz +0 -0
- package/payload/server/public/assets/skills-EtKyNK_3.js.br +0 -0
- package/payload/server/public/assets/skills-EtKyNK_3.js.gz +0 -0
- package/payload/server/public/assets/tasks-U0poqfi9.js.br +0 -0
- package/payload/server/public/assets/tasks-U0poqfi9.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-D7zwttJW.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-D7zwttJW.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-Ae_va0Ps.js.br +0 -4
- package/payload/server/public/assets/useCopyFeedback-Ae_va0Ps.js.gz +0 -0
- package/payload/server/public/assets/useMediaQuery-HRgPNA8l.css.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-q9U5ahfg.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-q9U5ahfg.js.gz +0 -0
- package/payload/server/public/assets/wrench-BmXV4Tmh.js.br +0 -0
- package/payload/server/public/assets/wrench-BmXV4Tmh.js.gz +0 -0
- /package/payload/server/public/assets/{useMediaQuery-DIm6yGOl.js → useMediaQuery-DJ6XeNN7.js} +0 -0
- /package/payload/server/public/assets/{useMediaQuery-DIm6yGOl.js.br → useMediaQuery-DJ6XeNN7.js.br} +0 -0
- /package/payload/server/public/assets/{useMediaQuery-DIm6yGOl.js.gz → useMediaQuery-DJ6XeNN7.js.gz} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -9030,23 +9030,23 @@ async function objectGate(c, action) {
|
|
|
9030
9030
|
if (err instanceof Error && err.name === "BodyLimitError") throw err;
|
|
9031
9031
|
return { ok: false, res: c.json({ error: "invalid-json" }, 400) };
|
|
9032
9032
|
}
|
|
9033
|
-
const
|
|
9034
|
-
if (!
|
|
9033
|
+
const bucket2 = body.bucket;
|
|
9034
|
+
if (!bucket2 || typeof bucket2 !== "string") {
|
|
9035
9035
|
return { ok: false, res: c.json({ error: "bucket-required" }, 400) };
|
|
9036
9036
|
}
|
|
9037
9037
|
const session = getSession();
|
|
9038
9038
|
let owner;
|
|
9039
9039
|
try {
|
|
9040
|
-
owner = await resolveOwner(session, "r2",
|
|
9040
|
+
owner = await resolveOwner(session, "r2", bucket2);
|
|
9041
9041
|
} catch (err) {
|
|
9042
9042
|
return { ok: false, res: c.json({ error: String(err) }, 500) };
|
|
9043
9043
|
} finally {
|
|
9044
9044
|
await session.close();
|
|
9045
9045
|
}
|
|
9046
9046
|
const decision = authorizeAccess({ caller: account, owner, action });
|
|
9047
|
-
log(action, "r2", account,
|
|
9047
|
+
log(action, "r2", account, bucket2, owner, decision.allow ? "allow" : "deny");
|
|
9048
9048
|
if (!decision.allow) return { ok: false, res: c.json({ error: decision.reason }, 403) };
|
|
9049
|
-
return { ok: true, bucket, body };
|
|
9049
|
+
return { ok: true, bucket: bucket2, body };
|
|
9050
9050
|
}
|
|
9051
9051
|
function readKey(body) {
|
|
9052
9052
|
const key2 = body.key;
|
|
@@ -9344,8 +9344,8 @@ function readSharedStoreNames(platformRootDir) {
|
|
|
9344
9344
|
if (m) env[m[1]] = m[2].trim();
|
|
9345
9345
|
}
|
|
9346
9346
|
const dbName = env.DATA_PORTAL_DB_NAME;
|
|
9347
|
-
const
|
|
9348
|
-
return dbName &&
|
|
9347
|
+
const bucket2 = env.DATA_PORTAL_BUCKET;
|
|
9348
|
+
return dbName && bucket2 ? { dbName, bucket: bucket2 } : null;
|
|
9349
9349
|
}
|
|
9350
9350
|
function resolveStorageModel(cfg, shared, onDisagree) {
|
|
9351
9351
|
const labelled = cfg.storageModel === "shared" ? "shared" : "dedicated";
|
|
@@ -19187,7 +19187,7 @@ app25.post("/upload", requireAdminSession, async (c) => {
|
|
|
19187
19187
|
const tmpPath = resolve24(tmpDir, `${uid}.part`);
|
|
19188
19188
|
const out = createWriteStream2(tmpPath);
|
|
19189
19189
|
const t0 = Date.now();
|
|
19190
|
-
let
|
|
19190
|
+
let received2 = 0;
|
|
19191
19191
|
let lastLogged = 0;
|
|
19192
19192
|
const LOG_EVERY = 64 * 1024 * 1024;
|
|
19193
19193
|
let writeError = null;
|
|
@@ -19212,9 +19212,9 @@ app25.post("/upload", requireAdminSession, async (c) => {
|
|
|
19212
19212
|
const { done, value } = await reader.read();
|
|
19213
19213
|
if (done) break;
|
|
19214
19214
|
if (!value) continue;
|
|
19215
|
-
|
|
19216
|
-
if (
|
|
19217
|
-
console.error(`[data-upload] op=reject-size uid=${uid} received=${
|
|
19215
|
+
received2 += value.byteLength;
|
|
19216
|
+
if (received2 > ceiling) {
|
|
19217
|
+
console.error(`[data-upload] op=reject-size uid=${uid} received=${received2} ceiling=${ceiling}`);
|
|
19218
19218
|
await reader.cancel().catch(() => {
|
|
19219
19219
|
});
|
|
19220
19220
|
await cleanup();
|
|
@@ -19236,9 +19236,9 @@ app25.post("/upload", requireAdminSession, async (c) => {
|
|
|
19236
19236
|
out.once("error", onErr);
|
|
19237
19237
|
});
|
|
19238
19238
|
}
|
|
19239
|
-
if (
|
|
19240
|
-
lastLogged =
|
|
19241
|
-
console.error(`[data-upload] op=streaming uid=${uid} received=${
|
|
19239
|
+
if (received2 - lastLogged >= LOG_EVERY) {
|
|
19240
|
+
lastLogged = received2;
|
|
19241
|
+
console.error(`[data-upload] op=streaming uid=${uid} received=${received2}`);
|
|
19242
19242
|
}
|
|
19243
19243
|
}
|
|
19244
19244
|
await new Promise((res, rej) => {
|
|
@@ -19254,7 +19254,7 @@ app25.post("/upload", requireAdminSession, async (c) => {
|
|
|
19254
19254
|
return c.json({ error: message }, 500);
|
|
19255
19255
|
}
|
|
19256
19256
|
const relativeDest = `${destRel}/${finalName}`;
|
|
19257
|
-
console.error(`[data-upload] op=committed uid=${uid} path="${relativeDest}" bytes=${
|
|
19257
|
+
console.error(`[data-upload] op=committed uid=${uid} path="${relativeDest}" bytes=${received2} token=${token} rel="${relpath ?? ""}" ms=${Date.now() - t0}`);
|
|
19258
19258
|
void indexFile(accountId, relativeDest).catch((err) => {
|
|
19259
19259
|
console.error(`[data-upload] op=index-failed uid=${uid} dest="${relativeDest}" err="${err instanceof Error ? err.message : String(err)}"`);
|
|
19260
19260
|
});
|
|
@@ -19262,7 +19262,7 @@ app25.post("/upload", requireAdminSession, async (c) => {
|
|
|
19262
19262
|
return c.json({
|
|
19263
19263
|
path: relativeDest,
|
|
19264
19264
|
filename: finalName,
|
|
19265
|
-
sizeBytes:
|
|
19265
|
+
sizeBytes: received2,
|
|
19266
19266
|
mimeType
|
|
19267
19267
|
});
|
|
19268
19268
|
});
|
|
@@ -24534,7 +24534,7 @@ function readChannelAdmins(accountDir, channel) {
|
|
|
24534
24534
|
return { adminPhones, accountManagers };
|
|
24535
24535
|
}
|
|
24536
24536
|
const tg = config.telegram ?? {};
|
|
24537
|
-
const
|
|
24537
|
+
const byBot2 = [];
|
|
24538
24538
|
const seen = /* @__PURE__ */ new Set();
|
|
24539
24539
|
const adminUsers = [];
|
|
24540
24540
|
if (Array.isArray(tg.bots)) {
|
|
@@ -24543,7 +24543,7 @@ function readChannelAdmins(accountDir, channel) {
|
|
|
24543
24543
|
const b = raw;
|
|
24544
24544
|
if (b.role !== "admin" || typeof b.id !== "string" || b.id.length === 0) continue;
|
|
24545
24545
|
const users = Array.isArray(b.adminUsers) ? b.adminUsers.filter((u) => typeof u === "number") : [];
|
|
24546
|
-
|
|
24546
|
+
byBot2.push({ botId: b.id, adminUsers: users });
|
|
24547
24547
|
for (const u of users) {
|
|
24548
24548
|
if (seen.has(u)) continue;
|
|
24549
24549
|
seen.add(u);
|
|
@@ -24551,7 +24551,7 @@ function readChannelAdmins(accountDir, channel) {
|
|
|
24551
24551
|
}
|
|
24552
24552
|
}
|
|
24553
24553
|
}
|
|
24554
|
-
return { adminUsers, byBot };
|
|
24554
|
+
return { adminUsers, byBot: byBot2 };
|
|
24555
24555
|
}
|
|
24556
24556
|
function registeredAccountForDestination(houseDir, houseAccountId, destination) {
|
|
24557
24557
|
const { adminPhones, accountManagers } = readChannelAdmins(houseDir, "whatsapp");
|
|
@@ -24610,8 +24610,8 @@ function listDispatchDestinations(input) {
|
|
|
24610
24610
|
admins.push({ channel: "whatsapp", destination: phone, label: "House admin" });
|
|
24611
24611
|
}
|
|
24612
24612
|
}
|
|
24613
|
-
const { byBot } = readChannelAdmins(resolve31(accountsDir, accountId), "telegram");
|
|
24614
|
-
const telegram =
|
|
24613
|
+
const { byBot: byBot2 } = readChannelAdmins(resolve31(accountsDir, accountId), "telegram");
|
|
24614
|
+
const telegram = byBot2.flatMap((b) => b.adminUsers.map((id) => ({ botId: b.botId, id }))).sort((a, b) => a.id - b.id || a.botId.localeCompare(b.botId)).map(({ botId, id }) => ({
|
|
24615
24615
|
channel: "telegram",
|
|
24616
24616
|
destination: String(id),
|
|
24617
24617
|
label: "Telegram admin",
|
|
@@ -24771,16 +24771,33 @@ app51.get("/", requireAdminSession, async (c) => {
|
|
|
24771
24771
|
}
|
|
24772
24772
|
const session = getSession();
|
|
24773
24773
|
try {
|
|
24774
|
+
const since = since24h();
|
|
24774
24775
|
const res = await session.run(
|
|
24775
24776
|
`MATCH (e:Event {accountId: $accountId})
|
|
24776
24777
|
WHERE ${AUTOMATION_WHERE}
|
|
24777
24778
|
RETURN ${ROUTINE_COLS}
|
|
24778
24779
|
ORDER BY e.nextRun`,
|
|
24779
|
-
{ accountId, since
|
|
24780
|
+
{ accountId, since }
|
|
24780
24781
|
);
|
|
24781
24782
|
const routines = res.records.map(mapRoutine);
|
|
24782
|
-
|
|
24783
|
-
|
|
24783
|
+
let workflowRuns24h = null;
|
|
24784
|
+
try {
|
|
24785
|
+
const wf = await session.run(
|
|
24786
|
+
`MATCH (r:WorkflowRun)-[:RUN_OF]->(w:Workflow {accountId: $accountId})
|
|
24787
|
+
WHERE r.accountId = $accountId AND r.startedAt >= $since
|
|
24788
|
+
AND (NOT r:Trashed AND r.deletedAt IS NULL)
|
|
24789
|
+
AND (NOT w:Trashed AND w.deletedAt IS NULL)
|
|
24790
|
+
RETURN count(r) AS runs24h`,
|
|
24791
|
+
{ accountId, since }
|
|
24792
|
+
);
|
|
24793
|
+
const raw = wf.records[0].get("runs24h");
|
|
24794
|
+
workflowRuns24h = typeof raw === "object" && raw !== null && "toNumber" in raw ? raw.toNumber() : Number(raw);
|
|
24795
|
+
} catch (err) {
|
|
24796
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
24797
|
+
console.error(`[admin:routines] op=workflow-runs-fail accountId=${accountId.slice(0, 8)} err="${message}"`);
|
|
24798
|
+
}
|
|
24799
|
+
console.log(`[admin:routines] op=list accountId=${accountId.slice(0, 8)} count=${routines.length} workflowRuns24h=${workflowRuns24h ?? "unknown"}`);
|
|
24800
|
+
return c.json({ routines, workflowRuns24h });
|
|
24784
24801
|
} catch (err) {
|
|
24785
24802
|
const message = err instanceof Error ? err.message : String(err);
|
|
24786
24803
|
console.error(`[admin:routines] op=list-fail err="${message}"`);
|
|
@@ -31609,15 +31626,20 @@ var InboundHub3 = class {
|
|
|
31609
31626
|
return count;
|
|
31610
31627
|
}
|
|
31611
31628
|
/** The channel server confirmed it received (emitted) a drained message. The
|
|
31612
|
-
* message has reached the agent; drop it from in-flight. Returns
|
|
31613
|
-
*
|
|
31629
|
+
* message has reached the agent; drop it from in-flight. Returns the payload
|
|
31630
|
+
* that was dropped, or null when no in-flight message matched.
|
|
31631
|
+
*
|
|
31632
|
+
* Task 2408 — the payload rather than a bare boolean, because this is the one
|
|
31633
|
+
* point holding both the message id and the message. The delivered-versus-
|
|
31634
|
+
* answered census must skip a `source: 'schedule'` inbound, whose turn ends
|
|
31635
|
+
* deliberately silent, and the ack site is where that fact is still in hand. */
|
|
31614
31636
|
ack(key2, messageId) {
|
|
31615
31637
|
const s = this.keys.get(key2);
|
|
31616
|
-
if (!s) return
|
|
31638
|
+
if (!s) return null;
|
|
31617
31639
|
const i = s.inFlight.findIndex((e) => e.payload.messageId === messageId);
|
|
31618
|
-
if (i < 0) return
|
|
31619
|
-
s.inFlight.splice(i, 1);
|
|
31620
|
-
return
|
|
31640
|
+
if (i < 0) return null;
|
|
31641
|
+
const [dropped] = s.inFlight.splice(i, 1);
|
|
31642
|
+
return dropped.payload;
|
|
31621
31643
|
}
|
|
31622
31644
|
/** A key's channel server disconnected (session ended/restarting).
|
|
31623
31645
|
* Subsequent messages queue again until re-attach + ready, so nothing is lost
|
|
@@ -31763,6 +31785,87 @@ function createTelegramChannelRoutes(deps) {
|
|
|
31763
31785
|
return app77;
|
|
31764
31786
|
}
|
|
31765
31787
|
|
|
31788
|
+
// app/lib/telegram/gateway/telegram-inbound-census.ts
|
|
31789
|
+
var ANSWER_THRESHOLD_MS = 3e4;
|
|
31790
|
+
var GAP_NAME_LIMIT = 10;
|
|
31791
|
+
var received = 0;
|
|
31792
|
+
var answered2 = 0;
|
|
31793
|
+
var outstanding = /* @__PURE__ */ new Map();
|
|
31794
|
+
function noteReceived(key2, botId, messageId, now) {
|
|
31795
|
+
received += 1;
|
|
31796
|
+
const list = outstanding.get(key2);
|
|
31797
|
+
if (list) list.push({ messageId, botId, receivedAt: now });
|
|
31798
|
+
else outstanding.set(key2, [{ messageId, botId, receivedAt: now }]);
|
|
31799
|
+
}
|
|
31800
|
+
function noteAnswered2(key2) {
|
|
31801
|
+
const list = outstanding.get(key2);
|
|
31802
|
+
if (!list || list.length === 0) return;
|
|
31803
|
+
list.shift();
|
|
31804
|
+
if (list.length === 0) outstanding.delete(key2);
|
|
31805
|
+
answered2 += 1;
|
|
31806
|
+
}
|
|
31807
|
+
function readTelegramInboundCensus(now) {
|
|
31808
|
+
const gaps = [];
|
|
31809
|
+
for (const [key2, list] of outstanding) {
|
|
31810
|
+
for (const o of list) {
|
|
31811
|
+
const ageMs2 = now - o.receivedAt;
|
|
31812
|
+
if (ageMs2 > ANSWER_THRESHOLD_MS) gaps.push({ messageId: o.messageId, botId: o.botId, key: key2, ageMs: ageMs2 });
|
|
31813
|
+
}
|
|
31814
|
+
}
|
|
31815
|
+
gaps.sort((a, b) => b.ageMs - a.ageMs);
|
|
31816
|
+
return { received, answered: answered2, gaps };
|
|
31817
|
+
}
|
|
31818
|
+
function buildTelegramNotifyReconcileLines(input) {
|
|
31819
|
+
const named = input.gaps.slice(0, GAP_NAME_LIMIT);
|
|
31820
|
+
const lines = [
|
|
31821
|
+
`[telegram-native] op=telegram-notify-reconcile received=${input.received} answered=${input.answered} answerGap=${input.gaps.length} named=${named.length}`
|
|
31822
|
+
];
|
|
31823
|
+
for (const g of named) {
|
|
31824
|
+
lines.push(
|
|
31825
|
+
`[telegram-native] op=telegram-answer-gap messageId=${g.messageId} botId=${g.botId} key=${g.key} ageMs=${g.ageMs}`
|
|
31826
|
+
);
|
|
31827
|
+
}
|
|
31828
|
+
return lines;
|
|
31829
|
+
}
|
|
31830
|
+
function runTelegramNotifyReconcile(now) {
|
|
31831
|
+
for (const line of buildTelegramNotifyReconcileLines(readTelegramInboundCensus(now))) console.error(line);
|
|
31832
|
+
}
|
|
31833
|
+
|
|
31834
|
+
// app/lib/telegram/gateway/telegram-spawn-census.ts
|
|
31835
|
+
var byBot = /* @__PURE__ */ new Map();
|
|
31836
|
+
function bucket(botId) {
|
|
31837
|
+
let c = byBot.get(botId);
|
|
31838
|
+
if (!c) {
|
|
31839
|
+
c = { attempted: 0, ok: 0, failed: 0 };
|
|
31840
|
+
byBot.set(botId, c);
|
|
31841
|
+
}
|
|
31842
|
+
return c;
|
|
31843
|
+
}
|
|
31844
|
+
function noteSpawnAttempt2(botId) {
|
|
31845
|
+
bucket(botId).attempted += 1;
|
|
31846
|
+
}
|
|
31847
|
+
function noteSpawnOk2(botId) {
|
|
31848
|
+
bucket(botId).ok += 1;
|
|
31849
|
+
}
|
|
31850
|
+
function noteSpawnFailed2(botId) {
|
|
31851
|
+
bucket(botId).failed += 1;
|
|
31852
|
+
}
|
|
31853
|
+
function readTelegramSpawnCensus(botId) {
|
|
31854
|
+
const c = byBot.get(botId) ?? { attempted: 0, ok: 0, failed: 0 };
|
|
31855
|
+
return { ...c, spawnGap: Math.max(0, c.attempted - (c.ok + c.failed)) };
|
|
31856
|
+
}
|
|
31857
|
+
function buildTelegramSpawnCensusLines(input) {
|
|
31858
|
+
return [...new Set(input.botIds)].map((botId) => {
|
|
31859
|
+
const c = input.countsFor(botId);
|
|
31860
|
+
return `[telegram-native] op=telegram-spawn-census botId=${botId} attempted=${c.attempted} ok=${c.ok} failed=${c.failed} spawnGap=${c.spawnGap}`;
|
|
31861
|
+
});
|
|
31862
|
+
}
|
|
31863
|
+
function runTelegramSpawnCensus(botIds) {
|
|
31864
|
+
for (const line of buildTelegramSpawnCensusLines({ botIds, countsFor: readTelegramSpawnCensus })) {
|
|
31865
|
+
console.error(line);
|
|
31866
|
+
}
|
|
31867
|
+
}
|
|
31868
|
+
|
|
31766
31869
|
// app/lib/telegram/gateway/telegram-gateway.ts
|
|
31767
31870
|
var QUEUED_THRESHOLD_MS3 = 3e4;
|
|
31768
31871
|
var ACK_THRESHOLD_MS3 = 3e4;
|
|
@@ -31785,9 +31888,12 @@ var TelegramGateway = class {
|
|
|
31785
31888
|
if (count > 0) console.error(`[telegram-native] op=drained key=${key2} count=${count}`);
|
|
31786
31889
|
},
|
|
31787
31890
|
onReceived: (key2, messageId) => {
|
|
31788
|
-
const
|
|
31891
|
+
const acked = this.hub.ack(key2, messageId);
|
|
31892
|
+
if (acked !== null && (acked.source ?? "user") === "user") {
|
|
31893
|
+
noteReceived(key2, parseTelegramChannelKey(key2)?.botId ?? "unknown", messageId, Date.now());
|
|
31894
|
+
}
|
|
31789
31895
|
console.error(
|
|
31790
|
-
`[telegram-native] op=channel-received key=${key2} messageId=${messageId}${
|
|
31896
|
+
`[telegram-native] op=channel-received key=${key2} messageId=${messageId}${acked !== null ? "" : " note=unknown"}`
|
|
31791
31897
|
);
|
|
31792
31898
|
}
|
|
31793
31899
|
});
|
|
@@ -31879,6 +31985,7 @@ var TelegramGateway = class {
|
|
|
31879
31985
|
if (!hadSubscriber && !this.spawning.has(key2)) {
|
|
31880
31986
|
this.spawning.add(key2);
|
|
31881
31987
|
console.error(`[telegram-native] op=spawn-trigger key=${key2} botId=${input.botId} role=${input.role}`);
|
|
31988
|
+
noteSpawnAttempt2(input.botId);
|
|
31882
31989
|
try {
|
|
31883
31990
|
await this.deps.ensureChannelSession({
|
|
31884
31991
|
accountId: input.accountId,
|
|
@@ -31903,6 +32010,7 @@ var TelegramGateway = class {
|
|
|
31903
32010
|
const reply = this.replies.get(key2);
|
|
31904
32011
|
if (!reply) throw new Error(`telegram-gateway: no reply route for key ${key2}`);
|
|
31905
32012
|
await reply(text);
|
|
32013
|
+
noteAnswered2(key2);
|
|
31906
32014
|
}
|
|
31907
32015
|
};
|
|
31908
32016
|
|
|
@@ -31969,11 +32077,13 @@ function buildTelegramEnsureSession(deps) {
|
|
|
31969
32077
|
console.error(
|
|
31970
32078
|
`[telegram-native] op=spawn-failed botId=${input.botId} key=${req.channelKey} role=public agent=${input.agentSlug} error=${result2.error} status=${result2.status}`
|
|
31971
32079
|
);
|
|
32080
|
+
noteSpawnFailed2(input.botId);
|
|
31972
32081
|
return;
|
|
31973
32082
|
}
|
|
31974
32083
|
console.error(
|
|
31975
32084
|
`${TAG51} op=spawn botId=${input.botId} sessionId=${result2.sessionId} targetAccountId=${input.accountId} role=public`
|
|
31976
32085
|
);
|
|
32086
|
+
noteSpawnOk2(input.botId);
|
|
31977
32087
|
return;
|
|
31978
32088
|
}
|
|
31979
32089
|
const result = await deps.managerRcSpawn(req);
|
|
@@ -31981,11 +32091,13 @@ function buildTelegramEnsureSession(deps) {
|
|
|
31981
32091
|
console.error(
|
|
31982
32092
|
`[telegram-native] op=spawn-failed botId=${input.botId} key=${req.channelKey} role=admin error=${result.error} status=${result.status}`
|
|
31983
32093
|
);
|
|
32094
|
+
noteSpawnFailed2(input.botId);
|
|
31984
32095
|
return;
|
|
31985
32096
|
}
|
|
31986
32097
|
console.error(
|
|
31987
32098
|
`${TAG51} op=spawn botId=${input.botId} sessionId=${req.sessionId} targetAccountId=${input.accountId} role=admin`
|
|
31988
32099
|
);
|
|
32100
|
+
noteSpawnOk2(input.botId);
|
|
31989
32101
|
deps.followers.get(req.channelKey)?.abort();
|
|
31990
32102
|
let ac;
|
|
31991
32103
|
ac = deps.startFileFollower({
|
|
@@ -32606,19 +32718,19 @@ function backfillMisfiledRecords(params) {
|
|
|
32606
32718
|
for (const m of messages) {
|
|
32607
32719
|
const key2 = connectionKeyFromMessageId(m.messageId);
|
|
32608
32720
|
if (!key2 || key2 === houseAccountId || !isTargetAccount(key2)) continue;
|
|
32609
|
-
let
|
|
32610
|
-
if (!
|
|
32611
|
-
|
|
32612
|
-
byTarget.set(key2,
|
|
32721
|
+
let bucket2 = byTarget.get(key2);
|
|
32722
|
+
if (!bucket2) {
|
|
32723
|
+
bucket2 = { messageIds: /* @__PURE__ */ new Set(), msgKeyIds: /* @__PURE__ */ new Set() };
|
|
32724
|
+
byTarget.set(key2, bucket2);
|
|
32613
32725
|
}
|
|
32614
|
-
|
|
32615
|
-
|
|
32726
|
+
bucket2.messageIds.add(m.messageId);
|
|
32727
|
+
bucket2.msgKeyIds.add(m.msgKeyId);
|
|
32616
32728
|
}
|
|
32617
32729
|
if (byTarget.size === 0) continue;
|
|
32618
32730
|
const reactionTargets = new Set(readReactions(houseAccountId, remoteJid).map((r) => r.targetMsgKeyId));
|
|
32619
|
-
for (const [target,
|
|
32620
|
-
const carried = new Set([...
|
|
32621
|
-
const out = moveRecordsBetweenStores(houseAccountId, target, remoteJid,
|
|
32731
|
+
for (const [target, bucket2] of byTarget) {
|
|
32732
|
+
const carried = new Set([...bucket2.msgKeyIds].filter((k) => reactionTargets.has(k)));
|
|
32733
|
+
const out = moveRecordsBetweenStores(houseAccountId, target, remoteJid, bucket2.messageIds, carried);
|
|
32622
32734
|
movedRecords += out.movedRecords;
|
|
32623
32735
|
movedReactions += out.movedReactions;
|
|
32624
32736
|
}
|
|
@@ -32716,8 +32828,8 @@ function pubkeyPath(brand) {
|
|
|
32716
32828
|
}
|
|
32717
32829
|
var memo = null;
|
|
32718
32830
|
function memoKey(mtimeMs, account) {
|
|
32719
|
-
const
|
|
32720
|
-
return `${mtimeMs}:${
|
|
32831
|
+
const bucket2 = Math.floor(Date.now() / 6e4);
|
|
32832
|
+
return `${mtimeMs}:${bucket2}:${account.accountId}:${account.customerEmail ?? ""}`;
|
|
32721
32833
|
}
|
|
32722
32834
|
var VALID_TIERS = /* @__PURE__ */ new Set(["solo", "family", "pro", "max"]);
|
|
32723
32835
|
function resolveEntitlement(brand, account) {
|
|
@@ -34443,6 +34555,20 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
34443
34555
|
now: Date.now()
|
|
34444
34556
|
});
|
|
34445
34557
|
for (const line of lines) console.error(line);
|
|
34558
|
+
try {
|
|
34559
|
+
runTelegramNotifyReconcile(Date.now());
|
|
34560
|
+
} catch (err) {
|
|
34561
|
+
console.error(
|
|
34562
|
+
`[telegram-native] op=telegram-notify-reconcile-rejected detail=${err instanceof Error ? err.message : String(err)}`
|
|
34563
|
+
);
|
|
34564
|
+
}
|
|
34565
|
+
try {
|
|
34566
|
+
runTelegramSpawnCensus(accounts.flatMap((a) => listBotEntries(a.telegram).map((e) => e.id)));
|
|
34567
|
+
} catch (err) {
|
|
34568
|
+
console.error(
|
|
34569
|
+
`[telegram-native] op=telegram-spawn-census-rejected detail=${err instanceof Error ? err.message : String(err)}`
|
|
34570
|
+
);
|
|
34571
|
+
}
|
|
34446
34572
|
};
|
|
34447
34573
|
registerLoop({
|
|
34448
34574
|
name: "telegram-audit",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{nt as e,ot as t}from"./useMediaQuery-DIm6yGOl.js";import"./useVoiceRecorder-q9U5ahfg.js";import"./AdminShell-BVKfxSgh.js";import{n}from"./page-DcKH1PVD.js";import"./useCopyFeedback-Ae_va0Ps.js";var r=t(),i=e();(0,r.createRoot)(document.getElementById(`root`)).render((0,i.jsx)(n,{}));
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Z as e}from"./useMediaQuery-DIm6yGOl.js";var t=e(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]);export{t};
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Z as e}from"./useMediaQuery-DIm6yGOl.js";var t=e(`clock`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 6v6l4 2`,key:`mmk7yg`}]]);export{t};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{nt as e,ot as t}from"./useMediaQuery-DIm6yGOl.js";import"./useVoiceRecorder-q9U5ahfg.js";import{t as n}from"./page-CogD1Hho.js";import"./graph-labels-Byp2RkVg.js";var r=t(),i=e();(0,r.createRoot)(document.getElementById(`root`)).render((0,i.jsx)(n,{}));
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Z as e}from"./useMediaQuery-DIm6yGOl.js";var t=e(`play`,[[`path`,{d:`M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z`,key:`10ikf1`}]]);export{t};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{o as e,t}from"./chunk-CltuBf4Z.js";import{F as n,G as r,L as i,M as a,O as o,V as s,Y as c,Z as l,_ as u,at as d,ct as f,f as p,j as m,k as h,m as g,nt as _,ot as v,v as y}from"./useMediaQuery-DIm6yGOl.js";import{A as b,m as x,t as S}from"./AdminShell-BVKfxSgh.js";import{t as C}from"./clock-B_xWWLQW.js";import{t as w}from"./triangle-alert-D7zwttJW.js";import{t as ee}from"./wrench-BmXV4Tmh.js";import{r as T}from"./file-download-DiQesOd2.js";var te=l(`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=l(`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=l(`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=v(),O=e(f(),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 re(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 N={timeMode:`at`,minute:0,hour:9,interval:1,window:null,dayMode:`every`,weekdays:[],dayOfMonth:1};function P(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 F(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=P(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{...N,...f,timeMode:`everyMinutes`,minute:0,interval:e,window:t}}return c.kind===`fixed`?{...N,...f,timeMode:`at`,minute:s.value,hour:c.value}:c.kind===`any`?{...N,...f,timeMode:`everyHours`,minute:s.value,interval:1,window:null}:{...N,...f,timeMode:`everyHours`,minute:s.value,interval:c.step,window:c.rangeStart===null?null:{start:c.rangeStart,end:c.rangeEnd}}}function I(e){return e.dayMode===`dayOfMonth`?[String(e.dayOfMonth),`*`]:e.dayMode===`weekdays`&&e.weekdays.length>0?[`*`,[...e.weekdays].sort((e,t)=>e-t).join(`,`)]:[`*`,`*`]}function L(e){let[t,n]=I(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 R={scheduled:`live`,suspended:`stood-down`,due:`inert`,cancelled:`inert`,completed:`inert`};function z(e){return e==null||!Object.hasOwn(R,e)?`unknown`:R[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.`}},V={control:`none`,note:`This routine's status is not one this dashboard recognises, so no start or stop is offered.`};function ie(e){return e==null||!Object.hasOwn(B,e)?V:B[e]}var H={finished:`live`,gated:`live`,started:`in-flight`,accepted:`in-flight`,open:`in-flight`,failed:`error`,"no-destination":`warning`};function U(e){return e==null||!Object.hasOwn(H,e)?`unknown`:H[e]}function ae(e){return e===`gated`?`skipped: no work`:e??`unknown`}var W=_(),G=[{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`}],K=Array.from({length:24},(e,t)=>t),q=e=>String(e).padStart(2,`0`),J={timeMode:`at`,minute:0,hour:9,interval:1,window:null,dayMode:`every`,weekdays:[],dayOfMonth:1};function oe({recurrence:e,onChange:t,disabled:n}){let r=e?F(e):J,[i,a]=(0,O.useState)(r??J),[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,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Schedule (advanced)`}),(0,W.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,W.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(L(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,W.jsxs)(`div`,{className:`routine-sched`,children:[(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`How often`}),(0,W.jsxs)(`select`,{"aria-label":`How often`,value:i.timeMode,disabled:n,onChange:e=>u(e.target.value),children:[(0,W.jsx)(`option`,{value:`at`,children:`At a time of day`}),(0,W.jsx)(`option`,{value:`everyMinutes`,children:`Every few minutes`}),(0,W.jsx)(`option`,{value:`everyHours`,children:`Every few hours`})]})]}),i.timeMode===`at`&&(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Time of day`}),(0,W.jsx)(`input`,{type:`time`,"aria-label":`Time of day`,value:`${q(i.hour)}:${q(i.minute)}`,disabled:n,onChange:e=>f(e.target.value)})]}),i.timeMode===`everyMinutes`&&(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Minutes between runs`}),(0,W.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,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Hours between runs`}),(0,W.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,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Minute of the hour`}),(0,W.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,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`label`,{className:`cal-modal-field routine-sched-check`,children:[(0,W.jsx)(`input`,{type:`checkbox`,"aria-label":`Only between certain hours`,checked:i.window!==null,disabled:n,onChange:e=>m(e.target.checked)}),(0,W.jsx)(`span`,{children:`Only between certain hours`})]}),i.window!==null&&(0,W.jsxs)(`div`,{className:`routine-sched-row`,children:[(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`From hour`}),(0,W.jsx)(`select`,{"aria-label":`From hour`,value:i.window.start,disabled:n,onChange:e=>h(`start`,e.target.value),children:K.map(e=>(0,W.jsxs)(`option`,{value:e,children:[q(e),`:00`]},e))})]}),(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`To hour`}),(0,W.jsx)(`select`,{"aria-label":`To hour`,value:i.window.end,disabled:n,onChange:e=>h(`end`,e.target.value),children:K.map(e=>(0,W.jsxs)(`option`,{value:e,children:[q(e),`:00`]},e))})]})]})]}),(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Which days`}),(0,W.jsxs)(`select`,{"aria-label":`Which days`,value:i.dayMode,disabled:n,onChange:e=>d(e.target.value),children:[(0,W.jsx)(`option`,{value:`every`,children:`Every day`}),(0,W.jsx)(`option`,{value:`weekdays`,children:`Specific days`}),i.timeMode===`at`&&(0,W.jsx)(`option`,{value:`dayOfMonth`,children:`A day of the month`})]})]}),i.dayMode===`weekdays`&&(0,W.jsxs)(`div`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Days`}),(0,W.jsx)(`div`,{className:`routine-weekdays`,children:G.map(e=>(0,W.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,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Day of month`}),(0,W.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,W.jsx)(`option`,{value:e,children:e},e))})]})]})}function Y(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 se(e){if(e.name)return`${e.name} · ${e.label}`;let t=e.channel===`whatsapp`?Y(e.destination):e.destination;return`${e.label} · ${t}`}function ce({eventStatus:e}){let t=z(e);return(0,W.jsx)(`span`,{className:`routine-status-dot is-${t}`,"data-state":t,"aria-hidden":`true`})}function le(e){return e.agentChannel==null?e.actionPlugin==null?`trigger`:`deterministic`:e.gateTool==null?`agent-every-fire`:`checked-agent`}var ue={"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 de(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:fe(t.type,t)}]:[]}):[]}function fe(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 pe(e,t){if(!e)return`—`;let n=Date.parse(e);return Number.isFinite(n)?u(new Date(n).toISOString(),t):e}function me(e){return e?e.split(`
|
|
2
|
-
`).filter(e=>e.trim()!==``).reverse():[]}function X({routine:e,adminFetch:t,onClose:n,onSaved:r,onDeleted:o,onViewRuns:c}){let{zone:l}=y(),[u,d]=(0,O.useState)(!1),[f,h]=(0,O.useState)(!1),[_,v]=(0,O.useState)(null),[b,S]=(0,O.useState)(e),[w,T]=(0,O.useState)(!1),D=b.agentChannel!=null,k=le(b),A=de(b.gateArgs),j=ie(b.eventStatus),M=j.control===`resume`,[N,P]=(0,O.useState)(!1),[F,I]=(0,O.useState)(e.agentPrompt??``),[L,R]=(0,O.useState)(e.name??``),[z,B]=(0,O.useState)(e.description??``),[V,H]=(0,O.useState)(e.recurrence),[U,ae]=(0,O.useState)(e.agentChannel??``),[G,K]=(0,O.useState)(e.agentDestination??``),[q,J]=(0,O.useState)(null),[Y,fe]=(0,O.useState)(null),X=D||b.actionPlugin==null,Z=me(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(!u||!X||q!==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||J(t.destinations)}).catch(t=>{e||(J([]),fe(t instanceof Error?t.message:`Could not load destinations`))}),()=>{e=!0}},[u,X,q,t]);let he=(q??[]).filter(e=>e.channel===U),ge=U.length>0&&G.length>0,_e=L.trim().length===0&&(b.name??``).length>0||U.length>0&&G.length===0||ge&&F.trim().length===0,Q=(0,O.useCallback)(()=>{let e={},t=U.length>0&&G.length>0,n=L.trim();n!==(b.name??``)&&(e.name=n),(D||t)&&F!==(b.agentPrompt??``)&&(e.agentPrompt=F);let r=z.trim().length>0?z:null;return r!==(b.description??null)&&(e.description=r),V!=null&&V!==(b.recurrence??null)&&(e.recurrence=V),t&&(U!==(b.agentChannel??``)||G!==(b.agentDestination??``))?(e.agentChannel=U,e.agentDestination=G):!t&&U===``&&(b.agentChannel??``)!==``&&(e.agentChannel=null,e.agentDestination=null),e},[D,L,F,z,V,U,G,b]),ve=(0,O.useCallback)(async()=>{let n=Q();if(Object.keys(n).length===0){d(!1);return}h(!0),v(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),R(a.routine.name??``),I(a.routine.agentPrompt??``),B(a.routine.description??``),H(a.routine.recurrence),ae(a.routine.agentChannel??``),K(a.routine.agentDestination??``),r(a.routine),d(!1)}catch(e){v(e instanceof Error?e.message:`Save failed`)}finally{h(!1)}},[t,Q,e.eventId,r]),ye=(0,O.useCallback)(async()=>{if(f)return;if(!N){T(!1),P(!0);return}let n=M?`resume`:`suspend`;h(!0),v(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),P(!1)}catch(e){v(e instanceof Error?e.message:`${n} failed`),P(!1)}finally{h(!1)}},[t,f,N,M,e.eventId,r]),be=(0,O.useCallback)(async()=>{if(!f){if(!w){P(!1),T(!0);return}h(!0),v(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}`)}o(e.eventId)}catch(e){v(e instanceof Error?e.message:`Delete failed`),T(!1)}finally{h(!1)}}},[t,f,w,e.eventId,o]);return(0,W.jsx)(`div`,{className:`cal-modal-overlay`,onClick:()=>{f||n()},children:(0,W.jsxs)(`div`,{className:`cal-modal ${!u||D||ge?`cal-modal-wide`:`cal-modal-dispatch`}`,role:`dialog`,"aria-modal":`true`,"aria-label":u?`Edit routine`:`Routine detail`,onClick:e=>e.stopPropagation(),children:[(0,W.jsxs)(`div`,{className:`cal-modal-header`,children:[(0,W.jsxs)(`span`,{className:`cal-modal-kind`,children:[(0,W.jsx)(x,{size:13}),` Routine`]}),(0,W.jsx)(`button`,{type:`button`,className:`cal-modal-close`,onClick:n,"aria-label":`Close`,autoFocus:!0,disabled:f,children:(0,W.jsx)(m,{size:16})})]}),!u&&(0,W.jsxs)(`div`,{className:`cal-modal-body`,children:[(0,W.jsx)(`div`,{className:`cal-modal-title`,children:b.name??`Untitled routine`}),(0,W.jsxs)(`div`,{className:`cal-modal-row`,children:[(0,W.jsx)(C,{size:14}),(0,W.jsx)(`span`,{children:b.recurrence?re(b.recurrence):`One-time`})]}),(0,W.jsxs)(`div`,{className:`cal-modal-row cal-modal-meta`,children:[(0,W.jsx)(ce,{eventStatus:b.eventStatus}),(0,W.jsxs)(`span`,{children:[`Status: `,b.eventStatus??`unknown`]})]}),(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsxs)(`span`,{children:[`Next run: `,pe(b.nextRun,l)]})}),(0,W.jsxs)(`div`,{className:`cal-modal-row cal-modal-meta`,children:[(0,W.jsx)(E,{size:14}),(0,W.jsxs)(`span`,{children:[`Last run: `,pe(b.lastTriggered,l),b.lastDispatchResult?` (${b.lastDispatchResult})`:``]})]}),b.description&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsx)(`span`,{children:`Description`})}),(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-row-top routine-prose`,children:(0,W.jsx)(`span`,{children:b.description})})]}),ue[k]&&(0,W.jsxs)(`div`,{className:`cal-modal-row cal-modal-meta`,"data-testid":`routine-mode`,children:[(0,W.jsx)(x,{size:14}),(0,W.jsxs)(`span`,{children:[ue[k],k===`agent-every-fire`&&b.gateWaived?`: ${b.gateWaived}`:``]})]}),D?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`div`,{className:`cal-modal-row`,children:[(0,W.jsx)(g,{channel:b.agentChannel,size:14}),(0,W.jsxs)(`span`,{children:[p[b.agentChannel]??b.agentChannel,` to `,b.agentDestination??`—`]})]}),b.gateTool!=null&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsx)(`span`,{children:`Checks before the agent runs`})}),(0,W.jsxs)(`div`,{className:`cal-modal-row`,children:[(0,W.jsx)(ee,{size:14}),(0,W.jsxs)(`span`,{children:[b.gatePlugin,`.`,b.gateTool]})]}),A.map((e,t)=>(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,"data-testid":`gate-check`,children:(0,W.jsxs)(`span`,{children:[e.kind,e.target?` · ${e.target}`:``]})},t))]}),(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsx)(`span`,{children:`Instruction sent to the agent`})}),(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-row-top routine-prose`,children:(0,W.jsx)(`span`,{children:b.agentPrompt??`No instruction sent to the agent.`})})]}):b.actionPlugin?(0,W.jsxs)(`div`,{className:`cal-modal-row`,children:[(0,W.jsx)(ee,{size:14}),(0,W.jsxs)(`span`,{children:[b.actionPlugin,`.`,b.actionTool,b.actionArgs?` ${b.actionArgs}`:``]})]}):(0,W.jsxs)(`div`,{className:`cal-modal-row`,children:[(0,W.jsx)(C,{size:14}),(0,W.jsx)(`span`,{children:`Scheduled trigger (no dispatch)`})]}),Z.length===0?(0,W.jsxs)(`div`,{className:`cal-modal-row cal-modal-meta`,children:[(0,W.jsx)(E,{size:14}),(0,W.jsx)(`span`,{children:`No history recorded.`})]}):(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`div`,{className:`cal-modal-row cal-modal-meta`,children:[(0,W.jsx)(E,{size:14}),(0,W.jsxs)(`span`,{children:[`History (`,Z.length,` `,Z.length===1?`entry`:`entries`,`)`]})]}),(0,W.jsx)(`div`,{className:`routine-history`,children:Z.map((e,t)=>(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:e},t))})]})]}),u&&(0,W.jsxs)(`div`,{className:`cal-modal-body`,children:[(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Name`}),(0,W.jsx)(`input`,{type:`text`,value:L,onChange:e=>R(e.target.value),disabled:f,maxLength:200,placeholder:`The routine's title, shown on the card`})]}),X&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Send to`}),(0,W.jsxs)(`div`,{className:`cal-modal-field-inline`,children:[(0,W.jsxs)(`select`,{value:U,disabled:f,onChange:e=>{ae(e.target.value),K(``)},children:[(0,W.jsx)(`option`,{value:``,children:`None (no dispatch)`}),(0,W.jsx)(`option`,{value:`whatsapp`,children:`WhatsApp`}),(0,W.jsx)(`option`,{value:`telegram`,children:`Telegram`})]}),U!==``&&(0,W.jsx)(g,{channel:U,size:16})]})]}),U!==``&&(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Destination`}),(0,W.jsxs)(`select`,{value:G,disabled:f||q===null,onChange:e=>K(e.target.value),children:[(0,W.jsx)(`option`,{value:``,children:q===null?`Loading destinations`:he.length===0?`No registered destinations`:`Choose a destination`}),G!==``&&!he.some(e=>e.destination===G)&&(0,W.jsxs)(`option`,{value:G,children:[G,` (not in the current list)`]}),he.map(e=>(0,W.jsx)(`option`,{value:e.destination,children:se(e)},e.destination))]})]}),Y&&(0,W.jsxs)(`div`,{className:`cal-modal-error`,children:[`Could not load destinations: `,Y]})]}),(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Description`}),(0,W.jsx)(`input`,{type:`text`,value:z,onChange:e=>B(e.target.value),disabled:f,placeholder:`One line: what this routine is for`})]}),(D||ge)&&(0,W.jsxs)(`label`,{className:`cal-modal-field`,children:[(0,W.jsx)(`span`,{children:`Instruction sent to the agent`}),(0,W.jsx)(`textarea`,{className:`cal-modal-textarea`,value:F,onChange:e=>I(e.target.value),disabled:f,rows:16,placeholder:`What should the agent do when this routine fires?`})]}),(0,W.jsx)(oe,{recurrence:b.recurrence,onChange:H,disabled:f})]}),_&&(0,W.jsx)(`div`,{className:`cal-modal-error`,children:_}),(0,W.jsxs)(`div`,{className:`cal-modal-actions`,children:[!u&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:()=>{T(!1),P(!1),d(!0)},disabled:f,children:[(0,W.jsx)(i,{size:14}),` Edit`]}),(0,W.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:()=>c(b),disabled:f,children:[(0,W.jsx)(E,{size:14}),` Runs`]}),j.control===`none`?(0,W.jsx)(`span`,{className:`cal-modal-confirm-text`,children:j.note}):(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:ye,disabled:f,children:[f&&N?(0,W.jsx)(s,{size:14,className:`spin`}):M?(0,W.jsx)(ne,{size:14}):(0,W.jsx)(te,{size:14}),N?M?`Confirm resume`:`Confirm suspend`:M?`Resume`:`Suspend`]}),N&&(0,W.jsx)(`span`,{className:`cal-modal-confirm-text`,children:M?`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,W.jsxs)(`button`,{type:`button`,className:`cal-modal-btn cal-modal-btn-danger`,onClick:be,disabled:f,children:[f&&w?(0,W.jsx)(s,{size:14,className:`spin`}):(0,W.jsx)(a,{size:14}),w?`Confirm delete`:`Delete`]})]}),u&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`button`,{type:`button`,className:`cal-modal-btn cal-modal-btn-primary`,onClick:ve,disabled:f||_e,children:[f?(0,W.jsx)(s,{size:14,className:`spin`}):null,` Save`]}),(0,W.jsx)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:()=>{d(!1),v(null)},disabled:f,children:`Cancel`})]})]})]})})}function Z(e,t){if(!e)return`—`;let n=Date.parse(e);return Number.isFinite(n)?u(new Date(n).toISOString(),t):e}function he(e){return e===null?`—`:e<1e3?`${e} ms`:`${(e/1e3).toFixed(1)} s`}function ge({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,W.jsx)(`div`,{className:`cal-modal-overlay`,onClick:n,children:(0,W.jsxs)(`div`,{className:`cal-modal cal-modal-wide`,role:`dialog`,"aria-modal":`true`,"aria-label":`Run detail`,onClick:e=>e.stopPropagation(),children:[(0,W.jsxs)(`div`,{className:`cal-modal-header`,children:[(0,W.jsx)(`span`,{className:`cal-modal-kind`,children:`Run`}),(0,W.jsx)(`button`,{type:`button`,className:`cal-modal-close`,onClick:n,"aria-label":`Close`,autoFocus:!0,children:(0,W.jsx)(m,{size:16})})]}),(0,W.jsxs)(`div`,{className:`cal-modal-body`,children:[(0,W.jsx)(`div`,{className:`cal-modal-title`,children:t??`Untitled routine`}),e.outputExcerpt!==null&&(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-row-top routine-prose`,"data-testid":`run-output`,children:(0,W.jsx)(`span`,{children:e.outputExcerpt})}),e.outputExcerpt===null&&e.status===`finished`&&(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,"data-testid":`run-output-none`,children:(0,W.jsx)(`span`,{children:`This run finished without sending anything.`})}),(0,W.jsx)(`div`,{className:`cal-modal-row`,children:(0,W.jsx)(`span`,{children:ae(e.status)})}),(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsxs)(`span`,{children:[`Due: `,Z(e.scheduledFor,r)]})}),(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsxs)(`span`,{children:[`Started: `,Z(e.startedAt,r)]})}),(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsxs)(`span`,{children:[`Dispatch ended: `,Z(e.endedAt,r),` (`,he(e.ranMs),`)`]})}),(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsxs)(`span`,{children:[`Output seen: `,Z(e.finishedAt,r)]})}),(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsxs)(`span`,{children:[`Sent to: `,e.target,` · `,e.mode,` · `,e.kind]})}),(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsxs)(`span`,{children:[`Transport: `,e.dispatchResult??`—`,e.httpStatus===null?``:` (HTTP ${e.httpStatus})`]})}),e.error&&(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-row-top routine-prose`,children:(0,W.jsx)(`span`,{children:e.error})}),(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsxs)(`span`,{children:[`Conversation: `,e.sessionKey??`—`,e.transcriptOffset===null?``:` at byte ${e.transcriptOffset}`]})}),!e.bounded&&e.status!==`gated`&&(0,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.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,W.jsx)(`div`,{className:`cal-modal-row cal-modal-meta`,children:(0,W.jsxs)(`span`,{children:[`Run `,e.runId]})})]})]})})}function _e({status:e}){let t=U(e);return(0,W.jsx)(`span`,{className:`routine-status-dot is-${t}`,"data-state":t,"aria-hidden":`true`})}var Q=500;function ve(e,t){if(!e)return`—`;let n=Date.parse(e);return Number.isFinite(n)?u(new Date(n).toISOString(),t):e}function ye(e){return e===null?`—`:e<1e3?`${e} ms`:`${(e/1e3).toFixed(1)} s`}var be={channel:`a channel`,destination:`a destination`,prompt:`an instruction`};function xe(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 be)){let e=t.map(e=>be[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 Se(e){return e.status===`no-destination`?e.error?xe(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 Ce(e){let t=e.indexOf(`:`);return t<=0?{channel:null,destination:e}:{channel:e.slice(0,t),destination:e.slice(t+1)}}function we(e){return e.outputExcerpt===null?e.status===`finished`?`Finished and sent nothing.`:null:e.outputExcerpt}function Te({routine:e,adminFetch:t,cacheKey:i,from:a=`card`,onBack:o}){let{zone:l}=y(),[u,d]=(0,O.useState)([]),[f,m]=(0,O.useState)(!0),[h,_]=(0,O.useState)(null),[v,b]=(0,O.useState)(null),x=(0,O.useRef)(0),S=(0,O.useCallback)(()=>{let n=!1,r=++x.current,i=()=>n||r!==x.current;return m(!0),_(null),t(`/api/admin/routines/${encodeURIComponent(e.eventId)}/runs?limit=${Q}&from=${a}`).then(async e=>{if(i())return;if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();i()||d(Array.isArray(t.runs)?t.runs:[])}).catch(e=>{i()||(_(e instanceof Error?e.message:`Failed to load`),d([]))}).finally(()=>{i()||m(!1)}),()=>{n=!0}},[t,e.eventId,a]);(0,O.useEffect)(()=>S(),[S]);let C=(0,O.useCallback)(()=>{T(i,e.eventId)},[i,e.eventId]);return(0,W.jsxs)(`div`,{className:`cal-page`,children:[(0,W.jsx)(`header`,{className:`cal-header`,children:(0,W.jsxs)(`div`,{className:`cal-nav`,children:[(0,W.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:o,children:[(0,W.jsx)(c,{size:14}),` Routines`]}),(0,W.jsx)(`span`,{className:`cal-range-label runs-title`,"data-testid":`runs-title`,title:e.name??`Untitled routine`,children:e.name??`Untitled routine`}),(0,W.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,W.jsx)(s,{size:14,className:`spin`}):(0,W.jsx)(n,{size:14}),` Refresh`]}),u.length>0&&(0,W.jsx)(`div`,{className:`routine-bulk-actions`,children:(0,W.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:C,children:[(0,W.jsx)(r,{size:14}),` Download all runs`]})})]})}),(0,W.jsxs)(`div`,{className:`cal-body`,children:[h&&(0,W.jsxs)(`div`,{className:`cal-error`,children:[`Could not load runs: `,h]}),!h&&!f&&u.length===0&&(0,W.jsxs)(`div`,{className:`cal-empty`,"data-testid":`runs-empty`,children:[(0,W.jsx)(`p`,{children:`Nothing to show for this routine.`}),(0,W.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,W.jsxs)(`p`,{children:[`For a repeating routine, the server log settles the middle one: a`,(0,W.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.`]})]}),u.length>=Q&&(0,W.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,W.jsx)(`div`,{className:`routine-list`,children:u.map(e=>{let t=Se(e),n=we(e),{channel:r,destination:i}=Ce(e.target);return(0,W.jsxs)(`button`,{type:`button`,className:`admin-card admin-card--padded routine-card`,"data-testid":`run-row-${e.runId}`,onClick:()=>b(e),children:[(0,W.jsxs)(`span`,{className:`admin-card-title routine-card-title run-card-title`,children:[(0,W.jsx)(_e,{status:e.status}),` `,ae(e.status)]}),(0,W.jsx)(`span`,{className:`routine-card-sched`,children:ye(e.ranMs)}),(0,W.jsx)(`span`,{className:`routine-card-target`,children:r?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(g,{channel:r,size:13}),` `,p[r]??r,` to `,r===`whatsapp`?Y(i):i]}):i}),(0,W.jsxs)(`span`,{className:`routine-card-meta`,children:[`Due `,ve(e.scheduledFor,l)]}),n&&(0,W.jsx)(`span`,{className:`routine-card-meta run-card-output`,children:n}),t&&(0,W.jsx)(`span`,{className:`routine-card-meta run-card-detail`,children:t})]},e.runId)})})]}),v&&(0,W.jsx)(ge,{run:v,routineName:e.name,onClose:()=>b(null)})]})}t(((e,t)=>{t.exports={}}))();function Ee(e){return e.agentChannel&&e.agentDestination&&e.agentPrompt?!0:!!(e.actionPlugin&&e.actionTool)}function De(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 Oe(e){return e?re(e):`One-time`}function ke(e,t){if(!e)return`—`;let n=Date.parse(e);return Number.isFinite(n)?u(new Date(n).toISOString(),t):e}function Ae(){let[e,t]=(0,O.useState)(null),[n,r]=(0,O.useState)(!1),[i,a]=(0,O.useState)(void 0),[s,c]=(0,O.useState)(null),[l,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&&c(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 g=(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,W.jsx)(h,{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,W.jsx)(S,{cacheKey:e,businessName:i,sessionId:s,onLogout:g,onDisconnect:y,disconnecting:_,userName:l,userAvatar:d,role:p,children:(0,W.jsx)(je,{cacheKey:e})})}):(0,W.jsx)(`div`,{className:`cal-page`,children:(0,W.jsxs)(`div`,{className:`cal-empty`,children:[(0,W.jsx)(`p`,{children:`You are not signed in.`}),(0,W.jsxs)(`p`,{children:[`Open the `,(0,W.jsx)(`a`,{href:`/`,className:`cal-link`,children:`main admin page`}),` and log in, then return here.`]})]})}):(0,W.jsx)(o,{surface:`gate`})}function je({cacheKey:e}){let{zone:t}=y(),{adminFetch:r,cacheKey:i,sessionRefetchNonce:a}=d({initialCacheKey:e,surface:`routines`}),[c,l]=(0,O.useState)([]),[u,f]=(0,O.useState)(!1),[m,h]=(0,O.useState)(!1),[_,v]=(0,O.useState)(null),[b,S]=(0,O.useState)(null),[T,E]=(0,O.useState)(null),D=(0,O.useCallback)(()=>{let e=!1;return f(!0),v(null),r(`/api/admin/routines`).then(async t=>{if(e)return;if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();l(Array.isArray(n.routines)?n.routines:[])}).catch(t=>{e||(v(t instanceof Error?t.message:`Failed to load`),l([]))}).finally(()=>{e||(f(!1),h(!0))}),()=>{e=!0}},[r]);(0,O.useEffect)(()=>D(),[D,a]);let k=(0,O.useCallback)(e=>{l(t=>t.map(t=>t.eventId===e.eventId?e:t)),S(e)},[]),A=(0,O.useCallback)(e=>{l(t=>t.filter(t=>t.eventId!==e)),S(null)},[]),[j,M]=(0,O.useState)(!1),[re,N]=(0,O.useState)(null),P=c.filter(e=>e.eventStatus===`scheduled`).length,F=c.filter(e=>e.suspendedInBulk).length,I=(0,O.useCallback)(async e=>{M(!0),N(null);try{let t=await r(`/api/admin/routines/${e}`,{method:`POST`});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`HTTP ${t.status}`)}let n=await t.json(),i=n.refused?.length??0;N(e===`suspend-all`?`Suspended ${n.suspended??0}. Nothing runs on its own until you resume it.`:`Resumed ${n.restored??0}${i>0?`. ${i} could not be resumed and stayed suspended`:``}. Routines you suspended one at a time are still suspended.`),D()}catch(e){N(e instanceof Error?e.message:`Failed`)}finally{M(!1)}},[r,D]);return m?T?(0,W.jsx)(Te,{routine:T,adminFetch:r,cacheKey:i,from:`modal`,onBack:()=>E(null)}):(0,W.jsxs)(`div`,{className:`cal-page`,children:[(0,W.jsx)(`header`,{className:`cal-header`,children:(0,W.jsxs)(`div`,{className:`cal-nav`,children:[(0,W.jsxs)(`span`,{className:`cal-range-label`,children:[(0,W.jsx)(x,{size:16}),` Routines`]}),(0,W.jsxs)(`div`,{className:`routine-bulk-actions`,children:[(0,W.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,"data-testid":`routines-refresh`,onClick:D,disabled:u,title:`Refresh routines`,"aria-label":`Refresh routines`,children:[u?(0,W.jsx)(s,{size:14,className:`spin`}):(0,W.jsx)(n,{size:14}),` Refresh`]}),(0,W.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:()=>I(`suspend-all`),disabled:j||P===0,children:[(0,W.jsx)(te,{size:14}),` Suspend all (`,P,`)`]}),(0,W.jsxs)(`button`,{type:`button`,className:`cal-modal-btn`,onClick:()=>I(`resume-all`),disabled:j||F===0,children:[(0,W.jsx)(ne,{size:14}),` Resume all (`,F,`)`]})]})]})}),(0,W.jsxs)(`div`,{className:`cal-body`,children:[re&&(0,W.jsx)(`div`,{className:`cal-modal-confirm-text`,children:re}),_&&(0,W.jsxs)(`div`,{className:`cal-error`,children:[`Could not load routines: `,_]}),!_&&!u&&c.length===0&&(0,W.jsx)(`div`,{className:`cal-empty`,children:(0,W.jsx)(`p`,{children:`No routines yet.`})}),(0,W.jsx)(`div`,{className:`routine-list`,children:c.map(e=>(0,W.jsxs)(`div`,{role:`button`,tabIndex:0,className:`admin-card admin-card--padded routine-card`,"data-testid":`routine-card-${e.eventId}`,onClick:()=>S(e),onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),S(e))},children:[(0,W.jsx)(`span`,{className:`admin-card-title routine-card-title`,title:e.name??`Untitled routine`,children:e.name??`Untitled routine`}),(0,W.jsxs)(`span`,{className:`routine-card-sched`,children:[(0,W.jsx)(C,{size:13}),` `,Oe(e.recurrence)]}),e.description&&(0,W.jsx)(`span`,{className:`routine-card-desc`,children:e.description}),(()=>{let t=e.eventStatus===`scheduled`&&!Ee(e)?De(e):null;return t===null?(0,W.jsx)(`span`,{className:`routine-card-target`,children:e.agentChannel?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(g,{channel:e.agentChannel,size:13}),` `,p[e.agentChannel]??e.agentChannel,` to `,e.agentDestination??`—`]}):e.actionPlugin?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(ee,{size:13}),` `,e.actionPlugin,`.`,e.actionTool]}):(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(C,{size:13}),` Scheduled trigger`]})}):(0,W.jsxs)(`span`,{className:`routine-card-target routine-card-target--gap`,children:[(0,W.jsx)(w,{size:13}),` `,xe(t)]})})(),(()=>{let t=[],n=ue[le(e)];return n&&t.push(n),e.runs24h>0&&t.push(`24h: ${e.runs24h} ${e.runs24h===1?`fire`:`fires`}, ${e.gated24h} skipped`),t.length===0?null:(0,W.jsx)(`span`,{className:`routine-card-gate`,"data-testid":`routine-gate-${e.eventId}`,children:t.join(` · `)})})(),(0,W.jsxs)(`span`,{className:`routine-card-meta`,children:[(0,W.jsx)(ce,{eventStatus:e.eventStatus}),`Next: `,ke(e.nextRun,t),` · `,e.eventStatus??`unknown`]})]},e.eventId))})]}),b&&(0,W.jsx)(X,{routine:b,adminFetch:r,onClose:()=>S(null),onSaved:k,onDeleted:A,onViewRuns:e=>{S(null),E(e)}})]}):(0,W.jsx)(o,{surface:`gate`})}(0,D.createRoot)(document.getElementById(`root`)).render((0,W.jsx)(Ae,{}));
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|