@symerian/symi 3.4.30 → 3.4.31
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/{agent-O3PihJOY.js → agent-ZFfYdexc.js} +10 -10
- package/dist/{agents-C2MpIr16.js → agents-C8naPegc.js} +5 -5
- package/dist/{audit-yf3H4Y1h.js → audit-DOfexJi4.js} +8 -8
- package/dist/{auth-choice-CyBcsQ9T.js → auth-choice-DxH-c3vK.js} +4 -4
- package/dist/{banner-D7__HlM-.js → banner-D7zYLyA8.js} +1 -1
- package/dist/{browser-cli-B_6WWHm_.js → browser-cli-MYIql1Ic.js} +3 -3
- package/dist/build-info.json +1 -1
- package/dist/bundled/boot-md/handler.js +4 -4
- package/dist/bundled/session-memory/handler.js +4 -4
- package/dist/{call-IfleM0ap.js → call-D9U2Sfhp.js} +1 -1
- package/dist/{channel-options-B5974x-7.js → channel-options-9PzSNQLG.js} +1 -1
- package/dist/{channels-cli-C6Nv9mzy.js → channels-cli-C3XnNkE5.js} +30 -30
- package/dist/{chrome-DT1fIVG1.js → chrome-B4P7ycw5.js} +7 -7
- package/dist/{chrome-DJCkCRLf.js → chrome-ClVIwINy.js} +1 -1
- package/dist/{cli-DZoms4qg.js → cli-DhTdzhjk.js} +26 -26
- package/dist/{command-registry--D98SJ6k.js → command-registry-BOwku-e8.js} +11 -11
- package/dist/{completion-cli-CHYvpIPw.js → completion-cli-KZYbGY4H.js} +2 -2
- package/dist/{config-BTSBEAnk.js → config-Byd2Y9rr.js} +5 -5
- package/dist/{config-cli-DstpcB33.js → config-cli-CJ1CRfG8.js} +5 -5
- package/dist/{config-guard-CCJrDmON.js → config-guard-zt0zhFHl.js} +2 -2
- package/dist/{config-validation-YCrMlM9Z.js → config-validation-CRazk6Kd.js} +1 -1
- package/dist/{configure-B-UvSZZ7.js → configure-CFY_XEps.js} +10 -10
- package/dist/{control-service-CwRG4M_O.js → control-service-DN6-IdFk.js} +4 -4
- package/dist/{cron-cli-DUETe3Of.js → cron-cli-fmiz43Pz.js} +3 -3
- package/dist/{daemon-cli-Dy5eY4M7.js → daemon-cli-BilAL40g.js} +6 -6
- package/dist/{daemon-runtime-ChztAKDA.js → daemon-runtime-D4KHzQq2.js} +1 -1
- package/dist/{deliver-59sRVaYQ.js → deliver-BkCYBlzi.js} +4 -4
- package/dist/{deliver-BHmK4isn.js → deliver-CnsfN7km.js} +1 -1
- package/dist/{devices-cli-BCZ2HHjT.js → devices-cli-D7HdOwRI.js} +2 -2
- package/dist/{directory-cli-BVGd0l0T.js → directory-cli-ed6QacBC.js} +1 -1
- package/dist/{dns-cli-DH-ksmiI.js → dns-cli-RPa1dGTQ.js} +1 -1
- package/dist/{docs-cli-BuX8FDdh.js → docs-cli-ZTdS_Gak.js} +2 -2
- package/dist/{doctor-completion-C4Sf8CFV.js → doctor-completion-DpGX8dau.js} +1 -1
- package/dist/{doctor-config-flow-BhmF6EAq.js → doctor-config-flow-CIrG_yW_.js} +4 -4
- package/dist/entry.js +3 -3
- package/dist/{exec-approvals-cli-CyXTXgft.js → exec-approvals-cli-65pcsa1y.js} +6 -6
- package/dist/{frontmatter-BH3ExkUY.js → frontmatter-B4levtVg.js} +2 -2
- package/dist/{gateway-cli-fT43bqlv.js → gateway-cli-CTi7Wl2k.js} +50 -50
- package/dist/{gateway-rpc-BEqCo2JK.js → gateway-rpc-2VPLhMhx.js} +1 -1
- package/dist/{glass-ui-ws-BfMKuf9v.js → glass-ui-ws-Bah_A-jn.js} +38 -38
- package/dist/{gmail-setup-utils-Cz9Tb30q.js → gmail-setup-utils-C9WBC6Cd.js} +1 -1
- package/dist/{health-DDxrkioj.js → health-B5rRzhyV.js} +3 -3
- package/dist/{hooks-cli-Btgk__9z.js → hooks-cli-CSDCGO-W.js} +29 -29
- package/dist/{hooks-status-BaV4_YaJ.js → hooks-status-OorbLcc2.js} +2 -2
- package/dist/index.js +0 -0
- package/dist/{lifecycle-core-B0tG8ERp.js → lifecycle-core-BRc-XqTk.js} +2 -2
- package/dist/llm-slug-generator.js +4 -4
- package/dist/{logs-cli-CUhZrDw7.js → logs-cli-D5phVUOT.js} +3 -3
- package/dist/{manager-BeNnzSJv.js → manager-BfhHvsI9.js} +1 -1
- package/dist/{manager-Di9qtuZF.js → manager-DzBH9uQG.js} +1 -1
- package/dist/{memory-BDeydRz3.js → memory-BCj0cj5v.js} +3 -3
- package/dist/{memory-cli-D4hZiGr5.js → memory-cli-9WUMBHol.js} +3 -3
- package/dist/{model-catalog-DPnCNs5N.js → model-catalog-CD2kTz4V.js} +2 -2
- package/dist/{model-picker-DuPommMc.js → model-picker-CVd5UuXV.js} +2 -2
- package/dist/{models-cli-CL5K06Wu.js → models-cli-rd4eX_6P.js} +30 -30
- package/dist/{models-config-CPlvO1b0.js → models-config-oxaGiRUT.js} +1 -1
- package/dist/{models-B0wNKA18.js → models-sbKIrJBG.js} +9 -9
- package/dist/{node-cli-CWWMajKF.js → node-cli-ClLXSdFL.js} +9 -9
- package/dist/{nodes-cli-YmE7S-JB.js → nodes-cli-DY38p5In.js} +3 -3
- package/dist/{onboard-HqUZVKyD.js → onboard-BAyp_UFm.js} +7 -7
- package/dist/{onboard-channels-BbF5-N3g.js → onboard-channels-CUpkV_IJ.js} +1 -1
- package/dist/{onboard-custom-63SI3jrk.js → onboard-custom-BMgLK-vo.js} +2 -2
- package/dist/{onboard-helpers-Cb3WFLl9.js → onboard-helpers-DIQjpQ-s.js} +2 -2
- package/dist/{onboard-hooks-DXXg3YH9.js → onboard-hooks-KZKmj5Dk.js} +3 -3
- package/dist/{onboard-remote-CqtCrqtm.js → onboard-remote-C-_NUgBl.js} +1 -1
- package/dist/{onboard-skills-CS3l5fhH.js → onboard-skills-CwvicFTi.js} +3 -3
- package/dist/{onboarding-Be_HJIFA.js → onboarding-BxCNNo75.js} +11 -11
- package/dist/{onboarding.finalize-dsCUTKCQ.js → onboarding.finalize-DgMPXTtO.js} +18 -18
- package/dist/{onboarding.gateway-config-Ctd1_QW4.js → onboarding.gateway-config-BAaWvPSX.js} +4 -4
- package/dist/{outbound-send-deps-DPsU_Xdy.js → outbound-send-deps-qhFaNYAY.js} +1 -1
- package/dist/{pairing-cli-PtlNv7Gr.js → pairing-cli-CFkiSx8t.js} +1 -1
- package/dist/{pi-embedded-helpers-CVKIHnFv.js → pi-embedded-helpers-CRG5LMS7.js} +1 -1
- package/dist/{pi-tools.policy-8_wTu7v2.js → pi-tools.policy-De6xHjVL.js} +2 -2
- package/dist/{plugin-registry-BG51uZOA.js → plugin-registry-BNe5jtPK.js} +2 -2
- package/dist/plugin-sdk/index.js +6 -6
- package/dist/{plugins-cli-B-zVOiQN.js → plugins-cli-CWj33_Hj.js} +27 -27
- package/dist/{program-BOh0XGsA.js → program-Z2OLlhsB.js} +33 -33
- package/dist/{prompt-select-styled-Bj-hrPCx.js → prompt-select-styled-BNwbBBcH.js} +16 -16
- package/dist/{provider-auth-helpers-BK6NFk2Q.js → provider-auth-helpers-5qb15Hje.js} +2 -2
- package/dist/{push-apns-CMxk3Hxf.js → push-apns-D6qV5P4h.js} +1 -1
- package/dist/{pw-ai-C5MJKzUM.js → pw-ai-BsEf8C15.js} +1 -1
- package/dist/{pw-ai-CE2TBGif.js → pw-ai-C7mvVllB.js} +2 -2
- package/dist/{qr-cli-BeHlC33g.js → qr-cli-oENcXq8d.js} +1 -1
- package/dist/{redact-identifier-B1VHIbnd.js → redact-identifier-ZE8OIUof.js} +1 -1
- package/dist/{register.agent-COv5OPLQ.js → register.agent-DpiHPMca.js} +36 -36
- package/dist/{register.configure-RhKVlfWH.js → register.configure-DRFaroYF.js} +40 -40
- package/dist/{register.maintenance-BAK-DiQY.js → register.maintenance-BGNNTt_1.js} +38 -38
- package/dist/{register.message-CCBmn5ja.js → register.message-R4AIHhlU.js} +28 -28
- package/dist/{register.onboard-B3jO_Goy.js → register.onboard-Cl-_Suyv.js} +13 -13
- package/dist/{register.setup-CYSISTDO.js → register.setup-Dt98v2V3.js} +15 -15
- package/dist/{register.status-health-sessions-CGbg9k6d.js → register.status-health-sessions-DiX5lVyr.js} +23 -23
- package/dist/{register.subclis-loifbhVx.js → register.subclis-DVObuR_P.js} +28 -28
- package/dist/{replies-Dj640LxQ.js → replies-VTJu1jUK.js} +1 -1
- package/dist/{routes-B5y-oAKp.js → routes-DOFg6X5M.js} +3 -3
- package/dist/{rpc-qWm1bRo5.js → rpc-BIHKXdlN.js} +1 -1
- package/dist/{run-main-B7Ria3zD.js → run-main-NAgYKzSu.js} +44 -44
- package/dist/{sandbox-BJgHc4Vu.js → sandbox-EB7cFSML.js} +6 -6
- package/dist/{sandbox-cli-CSudrHYL.js → sandbox-cli-D4dy6sUK.js} +8 -8
- package/dist/{security-cli-B2lCR2xX.js → security-cli-DwCKOrFm.js} +11 -11
- package/dist/{send-CY9na-Jw.js → send-CkRtuQbr.js} +1 -1
- package/dist/{server-context-DdWWaDf6.js → server-context-ww1jytet.js} +5 -5
- package/dist/{server-methods-Dk_EnINI.js → server-methods-BDiZyPvS.js} +23 -23
- package/dist/{server-node-events-BHegSgG9.js → server-node-events-9cY40B4m.js} +29 -29
- package/dist/{session-utils-CAVPV2Hh.js → session-utils-CStjqGE6.js} +3 -3
- package/dist/{sessions-BDM9kNY0.js → sessions-BSRHJH8T.js} +3 -3
- package/dist/{sessions-CqLQkkWg.js → sessions-CInbrqsF.js} +1 -1
- package/dist/{shared-CpwtQRJB.js → shared-DEAo94kI.js} +1 -1
- package/dist/{skill-commands-CRQniaHy.js → skill-commands-BkKfrbHt.js} +2 -2
- package/dist/{skills-CTcjFd_F.js → skills-CFLijAZ-.js} +1 -1
- package/dist/{skills-cli-9Mlb7VRg.js → skills-cli-BbagnO6p.js} +5 -5
- package/dist/{skills-install-D5ikt72d.js → skills-install-dLRO1KGp.js} +2 -2
- package/dist/{skills-remote-BASG1Doo.js → skills-remote-DQVB-3Pj.js} +1 -1
- package/dist/{skills-status-1iVfuVIG.js → skills-status-HWybfj0K.js} +2 -2
- package/dist/{status-Bci6O3aA.js → status-BSrVEUoJ.js} +2 -2
- package/dist/{status-D5RhVO0A.js → status-FIp7UKru.js} +12 -12
- package/dist/{status.update-D5CachQ_.js → status.update-Cm8Fm8QD.js} +1 -1
- package/dist/{subagent-registry-CsXaK_sy.js → subagent-registry-DqryocLT.js} +31 -31
- package/dist/{synthesis-dplLmFIP.js → synthesis-CS-lrEGy.js} +4 -4
- package/dist/{synthesis-BoZf8BeO.js → synthesis-DKhH0YwU.js} +26 -26
- package/dist/{system-cli-D5FffFX5.js → system-cli-DYSI6cIB.js} +3 -3
- package/dist/{systemd-hints-CufcSfMk.js → systemd-hints-EIfW5y8K.js} +1 -1
- package/dist/{tui-DZ8gksSZ.js → tui-C20rHOeB.js} +4 -4
- package/dist/{tui-cli-CyBJYh9u.js → tui-cli-JwlzHCza.js} +11 -11
- package/dist/{unified-runner-BFLLzEHE.js → unified-runner-AM9tFC5q.js} +10 -10
- package/dist/{update-cli-yW6Xl6fs.js → update-cli-BYfA3RPc.js} +41 -41
- package/dist/{update-runner-CIgLduhH.js → update-runner-CBG8p9iG.js} +1 -1
- package/dist/{webhooks-cli-4bmyKzwb.js → webhooks-cli-MuG_QGLp.js} +4 -4
- package/dist/{with-timeout-bWr6yBeX.js → with-timeout-BvxaeAo6.js} +1 -1
- package/dist/{workspace-DxscDsm6.js → workspace-D0d7Gi4-.js} +1 -1
- package/extensions/memory-core/node_modules/.bin/symi +0 -0
- package/extensions/msteams/node_modules/.bin/symi +0 -0
- package/extensions/outlook/node_modules/.bin/symi +0 -0
- package/extensions/slack/node_modules/.bin/symi +0 -0
- package/package.json +108 -79
- package/dist/control-ui/css/revert-red-theme.md +0 -141
- package/dist/control-ui/css/style.css +0 -5843
- package/dist/control-ui/css/style.css.backup-2026-03-03-162525 +0 -3546
- package/dist/control-ui/css/style.css.backup-before-red-2026-03-03-162525 +0 -3546
- package/dist/control-ui/css/style.css.backup-before-red-theme-2026-03-03-162530 +0 -3546
- package/dist/control-ui/css/style.css.pre-2row +0 -2165
- package/dist/control-ui/css/style.css.pre-brand +0 -1776
- package/dist/control-ui/css/style.css.pre-history +0 -1974
- package/dist/control-ui/css/style.css.pre-nav +0 -2264
- package/dist/control-ui/css/style.css.pre-newsession +0 -1898
- package/dist/control-ui/css/style.css.pre-queue +0 -2195
- package/dist/control-ui/css/style.css.pre-red-prompt +0 -2524
- package/dist/control-ui/css/style.css.pre-stop +0 -2239
- package/dist/control-ui/css/style.css.pre-textarea +0 -2184
- package/dist/control-ui/css/style.css.pre-watchdog +0 -1848
- package/dist/control-ui/css/style.css.red-theme +0 -2999
- package/dist/control-ui/index.html +0 -1042
- package/dist/control-ui/js/app.js +0 -1304
- package/dist/control-ui/js/app.js.pre-2row +0 -463
- package/dist/control-ui/js/app.js.pre-heartbeat-filter +0 -595
- package/dist/control-ui/js/app.js.pre-newsession +0 -408
- package/dist/control-ui/js/app.js.pre-queue +0 -476
- package/dist/control-ui/js/app.js.pre-stop +0 -564
- package/dist/control-ui/js/app.js.pre-textarea +0 -467
- package/dist/control-ui/js/app.js.pre-watchdog +0 -293
- package/dist/control-ui/js/connections.js +0 -438
- package/dist/control-ui/js/gateway.js +0 -233
- package/dist/control-ui/js/gateway.js.pre-stop +0 -110
- package/dist/control-ui/js/history.js +0 -732
- package/dist/control-ui/js/logs.js +0 -238
- package/dist/control-ui/js/menu.js +0 -230
- package/dist/control-ui/js/menu.js.pre-nav +0 -66
- package/dist/control-ui/js/metrics.js +0 -53
- package/dist/control-ui/js/models.js +0 -138
- package/dist/control-ui/js/render.js +0 -882
- package/dist/control-ui/js/render.test.js +0 -112
- package/dist/control-ui/js/scheduling.js +0 -461
- package/dist/control-ui/js/settings.js +0 -909
- package/dist/control-ui/js/slash-autocomplete.js +0 -168
- package/dist/control-ui/js/subagents.js +0 -560
- package/dist/control-ui/js/utils.js +0 -29
- package/dist/control-ui/vendor/highlight.min.js +0 -2518
- package/dist/control-ui/vendor/marked.min.js +0 -69
|
@@ -1,560 +0,0 @@
|
|
|
1
|
-
// ── Subagents Panel ─────────────────────────────────────────────────────────
|
|
2
|
-
// Displays active subagents and allows spawning new ones via quick-deploy or custom.
|
|
3
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
4
|
-
|
|
5
|
-
"use strict";
|
|
6
|
-
|
|
7
|
-
(function () {
|
|
8
|
-
// ── Agent Presets ──────────────────────────────────────────────────────────
|
|
9
|
-
const AGENT_PRESETS = {
|
|
10
|
-
research: {
|
|
11
|
-
label: "Research Agent",
|
|
12
|
-
taskTemplate: "Research and summarize: ",
|
|
13
|
-
model: "sonnet",
|
|
14
|
-
thinking: "",
|
|
15
|
-
},
|
|
16
|
-
review: {
|
|
17
|
-
label: "Code Review Agent",
|
|
18
|
-
taskTemplate: "Review this code and provide detailed feedback:\n",
|
|
19
|
-
model: "sonnet",
|
|
20
|
-
thinking: "",
|
|
21
|
-
},
|
|
22
|
-
writer: {
|
|
23
|
-
label: "Writer Agent",
|
|
24
|
-
taskTemplate: "Draft content for: ",
|
|
25
|
-
model: "sonnet",
|
|
26
|
-
thinking: "",
|
|
27
|
-
},
|
|
28
|
-
analyst: {
|
|
29
|
-
label: "Analyst Agent",
|
|
30
|
-
taskTemplate: "Analyze and report on: ",
|
|
31
|
-
model: "sonnet",
|
|
32
|
-
thinking: "",
|
|
33
|
-
},
|
|
34
|
-
planner: {
|
|
35
|
-
label: "Planner Agent",
|
|
36
|
-
taskTemplate: "Create an action plan for: ",
|
|
37
|
-
model: "sonnet",
|
|
38
|
-
thinking: "",
|
|
39
|
-
},
|
|
40
|
-
debug: {
|
|
41
|
-
label: "Debug Agent",
|
|
42
|
-
taskTemplate: "Debug and fix this issue:\n",
|
|
43
|
-
model: "sonnet",
|
|
44
|
-
thinking: "",
|
|
45
|
-
},
|
|
46
|
-
docs: {
|
|
47
|
-
label: "Documentation Agent",
|
|
48
|
-
taskTemplate: "Write documentation for: ",
|
|
49
|
-
model: "sonnet",
|
|
50
|
-
thinking: "",
|
|
51
|
-
},
|
|
52
|
-
test: {
|
|
53
|
-
label: "Test Agent",
|
|
54
|
-
taskTemplate: "Write tests for: ",
|
|
55
|
-
model: "sonnet",
|
|
56
|
-
thinking: "",
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
// ── State ──────────────────────────────────────────────────────────────────
|
|
61
|
-
let subagents = [];
|
|
62
|
-
let stagedAgents = []; // Array of { id, type, label, task, model, thinking }
|
|
63
|
-
let _pollInterval = null;
|
|
64
|
-
let editingAgentId = null; // Track which staged agent is being edited
|
|
65
|
-
|
|
66
|
-
// ── DOM Elements ───────────────────────────────────────────────────────────
|
|
67
|
-
const _panel = document.getElementById("subagents-panel");
|
|
68
|
-
const list = document.getElementById("subagents-list");
|
|
69
|
-
const emptyState = document.getElementById("subagents-empty");
|
|
70
|
-
const countBadge = document.getElementById("subagents-count");
|
|
71
|
-
const spawnBtn = document.getElementById("subagent-spawn-btn");
|
|
72
|
-
|
|
73
|
-
// Quick deploy elements
|
|
74
|
-
const quickDeployBtns = document.querySelectorAll(".quick-deploy-btn");
|
|
75
|
-
const _stagingBox = document.getElementById("staging-box");
|
|
76
|
-
const stagingChips = document.getElementById("staging-chips");
|
|
77
|
-
const stagingDeployBtn = document.getElementById("staging-deploy-btn");
|
|
78
|
-
|
|
79
|
-
// Modal elements
|
|
80
|
-
const modalOverlay = document.getElementById("subagent-modal-overlay");
|
|
81
|
-
const modalClose = document.getElementById("subagent-modal-close");
|
|
82
|
-
const modalCancel = document.getElementById("subagent-modal-cancel");
|
|
83
|
-
const modalSubmit = document.getElementById("subagent-modal-submit");
|
|
84
|
-
const taskInput = document.getElementById("subagent-task");
|
|
85
|
-
const labelInput = document.getElementById("subagent-label");
|
|
86
|
-
const modelSelect = document.getElementById("subagent-model");
|
|
87
|
-
const thinkingSelect = document.getElementById("subagent-thinking");
|
|
88
|
-
|
|
89
|
-
// ── Icons ──────────────────────────────────────────────────────────────────
|
|
90
|
-
const ICONS = {
|
|
91
|
-
running: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
92
|
-
<circle cx="12" cy="12" r="3"/>
|
|
93
|
-
<path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>
|
|
94
|
-
</svg>`,
|
|
95
|
-
completed: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
96
|
-
<path d="M20 6L9 17l-5-5"/>
|
|
97
|
-
</svg>`,
|
|
98
|
-
error: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
99
|
-
<circle cx="12" cy="12" r="10"/>
|
|
100
|
-
<path d="M15 9l-6 6M9 9l6 6"/>
|
|
101
|
-
</svg>`,
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
// ── Staging Management ─────────────────────────────────────────────────────
|
|
105
|
-
function addToStaging(agentType) {
|
|
106
|
-
const preset = AGENT_PRESETS[agentType];
|
|
107
|
-
if (!preset) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const stagedAgent = {
|
|
112
|
-
id: crypto.randomUUID(),
|
|
113
|
-
type: agentType,
|
|
114
|
-
label: preset.label,
|
|
115
|
-
task: preset.taskTemplate,
|
|
116
|
-
model: preset.model,
|
|
117
|
-
thinking: preset.thinking,
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
stagedAgents.push(stagedAgent);
|
|
121
|
-
renderStagingChips();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function removeFromStaging(agentId) {
|
|
125
|
-
stagedAgents = stagedAgents.filter((a) => a.id !== agentId);
|
|
126
|
-
renderStagingChips();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function renderStagingChips() {
|
|
130
|
-
stagingChips.innerHTML = "";
|
|
131
|
-
|
|
132
|
-
if (stagedAgents.length === 0) {
|
|
133
|
-
stagingChips.innerHTML = '<span class="staging-empty">Select agents above</span>';
|
|
134
|
-
stagingDeployBtn.disabled = true;
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
stagingDeployBtn.disabled = false;
|
|
139
|
-
|
|
140
|
-
for (const agent of stagedAgents) {
|
|
141
|
-
const chip = document.createElement("div");
|
|
142
|
-
chip.className = "staging-chip";
|
|
143
|
-
chip.setAttribute("data-agent-id", agent.id);
|
|
144
|
-
|
|
145
|
-
chip.innerHTML = `
|
|
146
|
-
<span class="staging-chip-name">${escHtml(agent.label.replace(" Agent", ""))}</span>
|
|
147
|
-
<span class="staging-chip-remove" title="Remove">×</span>
|
|
148
|
-
`;
|
|
149
|
-
|
|
150
|
-
// Click chip to edit
|
|
151
|
-
chip.addEventListener("click", (e) => {
|
|
152
|
-
if (e.target.classList.contains("staging-chip-remove")) {
|
|
153
|
-
e.stopPropagation();
|
|
154
|
-
removeFromStaging(agent.id);
|
|
155
|
-
} else {
|
|
156
|
-
openModalForEdit(agent);
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
stagingChips.appendChild(chip);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// ── Deploy Staged Agents ───────────────────────────────────────────────────
|
|
165
|
-
async function deployAllStaged() {
|
|
166
|
-
if (stagedAgents.length === 0) {
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (!window.gateway?.connected) {
|
|
170
|
-
alert("Gateway not connected");
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
stagingDeployBtn.disabled = true;
|
|
175
|
-
stagingDeployBtn.innerHTML = `
|
|
176
|
-
<svg class="spin" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
177
|
-
<circle cx="12" cy="12" r="10" stroke-dasharray="60" stroke-dashoffset="20"/>
|
|
178
|
-
</svg>
|
|
179
|
-
Deploying...
|
|
180
|
-
`;
|
|
181
|
-
|
|
182
|
-
const toSpawn = [...stagedAgents];
|
|
183
|
-
let successCount = 0;
|
|
184
|
-
|
|
185
|
-
for (const agent of toSpawn) {
|
|
186
|
-
try {
|
|
187
|
-
const uuid = crypto.randomUUID();
|
|
188
|
-
const sessionKey = `agent:main:subagent:${uuid}`;
|
|
189
|
-
|
|
190
|
-
await window.gateway.rpc("agent", {
|
|
191
|
-
message: agent.task,
|
|
192
|
-
sessionKey: sessionKey,
|
|
193
|
-
deliver: false,
|
|
194
|
-
lane: "subagent",
|
|
195
|
-
label: agent.label,
|
|
196
|
-
model: agent.model || undefined,
|
|
197
|
-
thinking: agent.thinking || undefined,
|
|
198
|
-
timeout: 300,
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
successCount++;
|
|
202
|
-
} catch (err) {
|
|
203
|
-
console.error("[subagents] Failed to spawn:", agent.label, err);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Clear staging
|
|
208
|
-
stagedAgents = [];
|
|
209
|
-
renderStagingChips();
|
|
210
|
-
|
|
211
|
-
// Reset button
|
|
212
|
-
stagingDeployBtn.innerHTML = `
|
|
213
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
214
|
-
<path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/>
|
|
215
|
-
</svg>
|
|
216
|
-
Deploy
|
|
217
|
-
`;
|
|
218
|
-
|
|
219
|
-
// Refresh subagents list
|
|
220
|
-
setTimeout(fetchSubagents, 500);
|
|
221
|
-
|
|
222
|
-
if (successCount < toSpawn.length) {
|
|
223
|
-
alert(`Deployed ${successCount} of ${toSpawn.length} agents. Check console for errors.`);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// ── Render Active Subagents ────────────────────────────────────────────────
|
|
228
|
-
function render() {
|
|
229
|
-
// Update count badge
|
|
230
|
-
const activeCount = subagents.filter((s) => s.status === "active" || !s.endedAt).length;
|
|
231
|
-
countBadge.textContent = activeCount > 0 ? activeCount : "";
|
|
232
|
-
|
|
233
|
-
// Clear existing items (except empty state)
|
|
234
|
-
const items = list.querySelectorAll(".subagent-item");
|
|
235
|
-
items.forEach((item) => item.remove());
|
|
236
|
-
|
|
237
|
-
if (subagents.length === 0) {
|
|
238
|
-
emptyState.style.display = "";
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
emptyState.style.display = "none";
|
|
243
|
-
|
|
244
|
-
// Sort: running first, then by startedAt descending
|
|
245
|
-
const sorted = [...subagents].toSorted((a, b) => {
|
|
246
|
-
const aRunning = a.status === "active" || !a.endedAt;
|
|
247
|
-
const bRunning = b.status === "active" || !b.endedAt;
|
|
248
|
-
if (aRunning !== bRunning) {
|
|
249
|
-
return bRunning ? 1 : -1;
|
|
250
|
-
}
|
|
251
|
-
return (b.startedAt || 0) - (a.startedAt || 0);
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
// Only show top 5
|
|
255
|
-
const visible = sorted.slice(0, 5);
|
|
256
|
-
|
|
257
|
-
for (const sub of visible) {
|
|
258
|
-
const status = getStatus(sub);
|
|
259
|
-
const runtime = formatRuntime(sub);
|
|
260
|
-
|
|
261
|
-
const item = document.createElement("div");
|
|
262
|
-
item.className = "subagent-item";
|
|
263
|
-
item.setAttribute("data-status", status);
|
|
264
|
-
item.setAttribute("data-run-id", sub.runId || "");
|
|
265
|
-
|
|
266
|
-
item.innerHTML = `
|
|
267
|
-
<div class="subagent-icon">${ICONS[status] || ICONS.running}</div>
|
|
268
|
-
<div class="subagent-info">
|
|
269
|
-
<div class="subagent-label">${escHtml(sub.label || "Subagent")}</div>
|
|
270
|
-
<div class="subagent-task">${escHtml(truncate(sub.task || "", 40))}</div>
|
|
271
|
-
</div>
|
|
272
|
-
<div class="subagent-runtime">${runtime}</div>
|
|
273
|
-
`;
|
|
274
|
-
|
|
275
|
-
item.addEventListener("click", () => showSubagentDetails(sub));
|
|
276
|
-
list.appendChild(item);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
function getStatus(sub) {
|
|
281
|
-
// Use status from backend if available
|
|
282
|
-
if (sub.status === "active") {
|
|
283
|
-
return "running";
|
|
284
|
-
}
|
|
285
|
-
if (sub.status === "completed") {
|
|
286
|
-
return "completed";
|
|
287
|
-
}
|
|
288
|
-
if (sub.status === "error" || sub.status === "timeout") {
|
|
289
|
-
return "error";
|
|
290
|
-
}
|
|
291
|
-
// Fallback for old format
|
|
292
|
-
if (!sub.endedAt) {
|
|
293
|
-
return "running";
|
|
294
|
-
}
|
|
295
|
-
if (sub.outcome?.status === "ok") {
|
|
296
|
-
return "completed";
|
|
297
|
-
}
|
|
298
|
-
return "error";
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
function formatRuntime(sub) {
|
|
302
|
-
const start = sub.startedAt;
|
|
303
|
-
const end = sub.endedAt || Date.now();
|
|
304
|
-
if (!start) {
|
|
305
|
-
return "--";
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
const seconds = Math.floor((end - start) / 1000);
|
|
309
|
-
if (seconds < 60) {
|
|
310
|
-
return `${seconds}s`;
|
|
311
|
-
}
|
|
312
|
-
const minutes = Math.floor(seconds / 60);
|
|
313
|
-
const secs = seconds % 60;
|
|
314
|
-
if (minutes < 60) {
|
|
315
|
-
return `${minutes}m${secs > 0 ? secs + "s" : ""}`;
|
|
316
|
-
}
|
|
317
|
-
const hours = Math.floor(minutes / 60);
|
|
318
|
-
const mins = minutes % 60;
|
|
319
|
-
return `${hours}h${mins}m`;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
function truncate(str, len) {
|
|
323
|
-
if (str.length <= len) {
|
|
324
|
-
return str;
|
|
325
|
-
}
|
|
326
|
-
return str.slice(0, len - 1) + "…";
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// ── Fetch Subagents ────────────────────────────────────────────────────────
|
|
330
|
-
async function fetchSubagents() {
|
|
331
|
-
if (!window.gateway?.connected) {
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
try {
|
|
336
|
-
const result = await window.gateway.rpc("subagents.list", {
|
|
337
|
-
sessionKey: window.SESSION_KEY || "agent:main:main",
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
if (result?.subagents) {
|
|
341
|
-
subagents = result.subagents;
|
|
342
|
-
render();
|
|
343
|
-
}
|
|
344
|
-
} catch (err) {
|
|
345
|
-
console.debug("[subagents] Failed to fetch:", err.message);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// ── Show Subagent Details ──────────────────────────────────────────────────
|
|
350
|
-
function showSubagentDetails(sub) {
|
|
351
|
-
const status = getStatus(sub);
|
|
352
|
-
const statusText =
|
|
353
|
-
status === "running" ? "Running" : status === "completed" ? "Completed" : "Failed";
|
|
354
|
-
|
|
355
|
-
const details = [
|
|
356
|
-
`Status: ${statusText}`,
|
|
357
|
-
`Task: ${sub.task || "N/A"}`,
|
|
358
|
-
`Label: ${sub.label || "N/A"}`,
|
|
359
|
-
`Model: ${sub.model || "Default"}`,
|
|
360
|
-
`Runtime: ${formatRuntime(sub)}`,
|
|
361
|
-
`Session: ${sub.childSessionKey || "N/A"}`,
|
|
362
|
-
].join("\n");
|
|
363
|
-
|
|
364
|
-
console.log("[subagent]", details);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// ── Modal Controls ─────────────────────────────────────────────────────────
|
|
368
|
-
function openModal() {
|
|
369
|
-
editingAgentId = null;
|
|
370
|
-
modalOverlay.classList.add("open");
|
|
371
|
-
modalOverlay.setAttribute("aria-hidden", "false");
|
|
372
|
-
taskInput.focus();
|
|
373
|
-
document.addEventListener("keydown", onModalKey);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
function openModalForEdit(stagedAgent) {
|
|
377
|
-
editingAgentId = stagedAgent.id;
|
|
378
|
-
|
|
379
|
-
// Pre-fill form with staged agent config
|
|
380
|
-
taskInput.value = stagedAgent.task;
|
|
381
|
-
labelInput.value = stagedAgent.label;
|
|
382
|
-
modelSelect.value = stagedAgent.model || "";
|
|
383
|
-
thinkingSelect.value = stagedAgent.thinking || "";
|
|
384
|
-
|
|
385
|
-
modalOverlay.classList.add("open");
|
|
386
|
-
modalOverlay.setAttribute("aria-hidden", "false");
|
|
387
|
-
taskInput.focus();
|
|
388
|
-
|
|
389
|
-
// Position cursor at end of task template
|
|
390
|
-
taskInput.setSelectionRange(taskInput.value.length, taskInput.value.length);
|
|
391
|
-
|
|
392
|
-
document.addEventListener("keydown", onModalKey);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
function closeModal() {
|
|
396
|
-
modalOverlay.classList.remove("open");
|
|
397
|
-
modalOverlay.setAttribute("aria-hidden", "true");
|
|
398
|
-
document.removeEventListener("keydown", onModalKey);
|
|
399
|
-
// Reset form
|
|
400
|
-
taskInput.value = "";
|
|
401
|
-
labelInput.value = "";
|
|
402
|
-
modelSelect.value = "";
|
|
403
|
-
thinkingSelect.value = "";
|
|
404
|
-
editingAgentId = null;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
function onModalKey(e) {
|
|
408
|
-
if (e.key === "Escape") {
|
|
409
|
-
closeModal();
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// ── Spawn/Save Subagent ────────────────────────────────────────────────────
|
|
414
|
-
async function spawnOrSaveSubagent() {
|
|
415
|
-
const task = taskInput.value.trim();
|
|
416
|
-
if (!task) {
|
|
417
|
-
taskInput.focus();
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
const label = labelInput.value.trim() || "Subagent";
|
|
422
|
-
const model = modelSelect.value || undefined;
|
|
423
|
-
const thinking = thinkingSelect.value || undefined;
|
|
424
|
-
|
|
425
|
-
// If editing a staged agent, update it instead of spawning
|
|
426
|
-
if (editingAgentId) {
|
|
427
|
-
const agent = stagedAgents.find((a) => a.id === editingAgentId);
|
|
428
|
-
if (agent) {
|
|
429
|
-
agent.task = task;
|
|
430
|
-
agent.label = label;
|
|
431
|
-
agent.model = model;
|
|
432
|
-
agent.thinking = thinking;
|
|
433
|
-
renderStagingChips();
|
|
434
|
-
}
|
|
435
|
-
closeModal();
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// Otherwise, spawn immediately (custom spawn)
|
|
440
|
-
modalSubmit.disabled = true;
|
|
441
|
-
modalSubmit.innerHTML = `
|
|
442
|
-
<svg class="spin" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
443
|
-
<circle cx="12" cy="12" r="10" stroke-dasharray="60" stroke-dashoffset="20"/>
|
|
444
|
-
</svg>
|
|
445
|
-
Spawning...
|
|
446
|
-
`;
|
|
447
|
-
|
|
448
|
-
try {
|
|
449
|
-
if (!window.gateway?.connected) {
|
|
450
|
-
throw new Error("Gateway not connected");
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
const uuid = crypto.randomUUID();
|
|
454
|
-
const sessionKey = `agent:main:subagent:${uuid}`;
|
|
455
|
-
|
|
456
|
-
await window.gateway.rpc("agent", {
|
|
457
|
-
message: task,
|
|
458
|
-
sessionKey: sessionKey,
|
|
459
|
-
deliver: false,
|
|
460
|
-
lane: "subagent",
|
|
461
|
-
label: label,
|
|
462
|
-
model: model,
|
|
463
|
-
thinking: thinking,
|
|
464
|
-
timeout: 300,
|
|
465
|
-
});
|
|
466
|
-
|
|
467
|
-
closeModal();
|
|
468
|
-
setTimeout(fetchSubagents, 500);
|
|
469
|
-
} catch (err) {
|
|
470
|
-
console.error("[subagents] Spawn failed:", err);
|
|
471
|
-
alert("Failed to spawn subagent: " + (err.message || "Unknown error"));
|
|
472
|
-
} finally {
|
|
473
|
-
modalSubmit.disabled = false;
|
|
474
|
-
modalSubmit.innerHTML = `
|
|
475
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
476
|
-
<path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/>
|
|
477
|
-
</svg>
|
|
478
|
-
Spawn
|
|
479
|
-
`;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// ── Initialize ─────────────────────────────────────────────────────────────
|
|
484
|
-
function init() {
|
|
485
|
-
// Quick deploy buttons
|
|
486
|
-
quickDeployBtns.forEach((btn) => {
|
|
487
|
-
btn.addEventListener("click", () => {
|
|
488
|
-
const agentType = btn.getAttribute("data-agent");
|
|
489
|
-
if (agentType) {
|
|
490
|
-
addToStaging(agentType);
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
// Staging deploy button
|
|
496
|
-
if (stagingDeployBtn) {
|
|
497
|
-
stagingDeployBtn.addEventListener("click", deployAllStaged);
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
// Custom spawn button
|
|
501
|
-
if (spawnBtn) {
|
|
502
|
-
spawnBtn.addEventListener("click", openModal);
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
// Modal controls
|
|
506
|
-
if (modalClose) {
|
|
507
|
-
modalClose.addEventListener("click", closeModal);
|
|
508
|
-
}
|
|
509
|
-
if (modalCancel) {
|
|
510
|
-
modalCancel.addEventListener("click", closeModal);
|
|
511
|
-
}
|
|
512
|
-
if (modalSubmit) {
|
|
513
|
-
modalSubmit.addEventListener("click", spawnOrSaveSubagent);
|
|
514
|
-
}
|
|
515
|
-
if (modalOverlay) {
|
|
516
|
-
modalOverlay.addEventListener("click", (e) => {
|
|
517
|
-
if (e.target === modalOverlay) {
|
|
518
|
-
closeModal();
|
|
519
|
-
}
|
|
520
|
-
});
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// Submit on Enter in task field (with Ctrl/Cmd)
|
|
524
|
-
if (taskInput) {
|
|
525
|
-
taskInput.addEventListener("keydown", (e) => {
|
|
526
|
-
if ((e.ctrlKey || e.metaKey) && e.key === "Enter") {
|
|
527
|
-
void spawnOrSaveSubagent();
|
|
528
|
-
}
|
|
529
|
-
});
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
// Initial render of staging (empty)
|
|
533
|
-
renderStagingChips();
|
|
534
|
-
|
|
535
|
-
// Initial fetch
|
|
536
|
-
void fetchSubagents();
|
|
537
|
-
|
|
538
|
-
// Poll every 5 seconds
|
|
539
|
-
_pollInterval = setInterval(fetchSubagents, 5000);
|
|
540
|
-
|
|
541
|
-
// Also fetch on gateway connect
|
|
542
|
-
window.addEventListener("gateway:connected", fetchSubagents);
|
|
543
|
-
window.addEventListener("gateway:hello", fetchSubagents);
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
// Start when DOM is ready
|
|
547
|
-
if (document.readyState === "loading") {
|
|
548
|
-
document.addEventListener("DOMContentLoaded", init);
|
|
549
|
-
} else {
|
|
550
|
-
init();
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
// Expose for external use
|
|
554
|
-
window.subagentsPanel = {
|
|
555
|
-
refresh: fetchSubagents,
|
|
556
|
-
open: openModal,
|
|
557
|
-
addToStaging: addToStaging,
|
|
558
|
-
deployAll: deployAllStaged,
|
|
559
|
-
};
|
|
560
|
-
})();
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// ── Glass UI Shared Utilities ──────────────────────────────────────────
|
|
2
|
-
// Single source of truth for common functions used across Glass UI modules.
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Escape HTML special characters to prevent XSS attacks.
|
|
6
|
-
* Handles null/undefined safely via nullish coalescing.
|
|
7
|
-
* @param {*} t - Value to escape (converted to string)
|
|
8
|
-
* @returns {string} HTML-safe string
|
|
9
|
-
*/
|
|
10
|
-
function escHtml(t) {
|
|
11
|
-
return String(t ?? "")
|
|
12
|
-
.replace(/&/g, "&")
|
|
13
|
-
.replace(/</g, "<")
|
|
14
|
-
.replace(/>/g, ">")
|
|
15
|
-
.replace(/"/g, """)
|
|
16
|
-
.replace(/'/g, "'");
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Escape a value for use in HTML attributes.
|
|
21
|
-
* Alias for escHtml since both require the same escaping.
|
|
22
|
-
*/
|
|
23
|
-
function escAttr(t) {
|
|
24
|
-
return escHtml(t);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Expose globally for use by other Glass UI scripts
|
|
28
|
-
window.escHtml = escHtml;
|
|
29
|
-
window.escAttr = escAttr;
|