@symerian/symi 3.5.19 → 3.5.21
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-D0Z4r5fr.js → agent-DgVWcnlD.js} +1 -1
- package/dist/{agent-DCDT-MPE.js → agent-NT0EKnK_.js} +18 -18
- package/dist/{agent-scope-DOrZjOnW.js → agent-scope-Bnsyyeci.js} +18 -18
- package/dist/{agents-CdkBeP0d.js → agents-Dlcpc1K3.js} +3 -3
- package/dist/{agents.config-B7sNDvhz.js → agents.config-DA0ISLi7.js} +1 -1
- package/dist/{audit-B7deV4Lp.js → audit-CPloCzEZ.js} +2 -2
- package/dist/{audit-BCStg-Hv.js → audit-CXIXYDRx.js} +20 -20
- package/dist/{auth-choice-BIGcxSzP.js → auth-choice--DymOp5O.js} +2 -2
- package/dist/{auth-choice-B3DU-aBr.js → auth-choice-BtXIQPTU.js} +11 -11
- package/dist/{auth-profiles-Ce7R_25e.js → auth-profiles-D5nYBj_Z.js} +2 -2
- package/dist/{auth-token-Cr28IDKY.js → auth-token-fgnCQEHT.js} +3 -3
- package/dist/{banner-ChNdzPjD.js → banner-CY_9VW7E.js} +1 -1
- package/dist/{browser-cli-C9xaKW8l.js → browser-cli-C5VVk6C9.js} +3 -3
- package/dist/{browser-cli-BTg8SVs-.js → browser-cli-DOTM7UBC.js} +9 -9
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +4 -4
- package/dist/bundled/session-memory/handler.js +4 -4
- package/dist/{call-BccaLPi8.js → call-Bpjj5p7I.js} +9 -9
- package/dist/{call-DZg43vv8.js → call-C2urR5Fj.js} +1 -1
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{channel-options-CUptVX8c.js → channel-options-XRJiHUm5.js} +1 -1
- package/dist/{channel-options-LLmAnD_L.js → channel-options-rFgJaKzJ.js} +1 -1
- package/dist/{channels-cli-xoromnio.js → channels-cli-CQ4M05oy.js} +57 -57
- package/dist/{channels-cli-B0OQvVUL.js → channels-cli-QMHCRAb5.js} +9 -9
- package/dist/{chrome-DJChpTwP.js → chrome-38OnGyuN.js} +2 -2
- package/dist/{chrome-CmQwGAuL.js → chrome-3jl2ulOE.js} +4 -4
- package/dist/{chrome-DNssqQJs.js → chrome-OTJg3QKn.js} +4 -4
- package/dist/{cli-C7v-sID8.js → cli-B-uoiYP2.js} +45 -45
- package/dist/{cli-CMNR7ULk.js → cli-BafqEuaj.js} +6 -6
- package/dist/{client-k0MT6NBw.js → client-CTrfpKT3.js} +7 -2
- package/dist/{client-DCxeV1bw.js → client-yVTJ5jx5.js} +6 -1
- package/dist/{command-registry-CXcvXjUR.js → command-registry-CLm8TAH3.js} +11 -11
- package/dist/{commands-registry-Ca5hh7nh.js → commands-registry-CwXsDVuO.js} +1 -1
- package/dist/{completion-cli-DJ1YCeSg.js → completion-cli-Cn_81QBb.js} +12 -12
- package/dist/{completion-cli-B1Fg6Lmg.js → completion-cli-DOBXkVwG.js} +2 -2
- package/dist/{config-B4jkreCN.js → config-BngIfn5l.js} +2 -2
- package/dist/{config-cli-D5DlWt6T.js → config-cli-B1cPkJ4p.js} +4 -4
- package/dist/{config-cli-CQ1FAvY_.js → config-cli-BgHYqFH1.js} +1 -1
- package/dist/{config-guard-BRm3RiOi.js → config-guard-DStz4_V2.js} +6 -6
- package/dist/{config-validation-Cdyg1BZB.js → config-validation-Dxj9LRzr.js} +1 -1
- package/dist/{configure-bhJB2Dti.js → configure-C7zmSgvC.js} +14 -14
- package/dist/{configure-DG1lf0Ld.js → configure-DmzM0S7L.js} +6 -6
- package/dist/{consolidate-DymnvvYm.js → consolidate-CO32_TEx.js} +6 -6
- package/dist/{control-service-D8kKOts5.js → control-service-CUreKVeY.js} +4 -4
- package/dist/control-ui/css/style.css +478 -80
- package/dist/control-ui/index.html +54 -127
- package/dist/control-ui/js/render.js +11 -227
- package/dist/control-ui/js/scheduling.js +85 -224
- package/dist/control-ui/js/subagents.js +78 -394
- package/dist/control-ui/js/symframe-awaiting.js +301 -0
- package/dist/control-ui/js/symframe-pin-store.js +104 -0
- package/dist/control-ui/js/symframe-substrate.js +395 -0
- package/dist/control-ui/js/symframe.js +244 -6
- package/dist/{control-ui-assets-CJQ97d4u.js → control-ui-assets-B8B9z_Ll.js} +1 -1
- package/dist/{cost-cli-DWiVCOCx.js → cost-cli-D-ssjcRF.js} +3 -3
- package/dist/{cron-cli-8RaBr1CM.js → cron-cli-BNBs3zue.js} +3 -3
- package/dist/{cron-cli-fW3wtftG.js → cron-cli-otPeKxmi.js} +7 -7
- package/dist/{daemon-cli-Y6clFgva.js → daemon-cli-DDqeG2nd.js} +2 -2
- package/dist/{daemon-cli-0EiZTQ2A.js → daemon-cli-qDdMg615.js} +11 -11
- package/dist/daemon-cli.js +6 -1
- package/dist/{daemon-runtime-DlQla_dA.js → daemon-runtime-CKn0wmCk.js} +10 -10
- package/dist/{deliver-B04yNX82.js → deliver-BiWlR84Y.js} +4 -4
- package/dist/{deliver-lTZLIQqf.js → deliver-CWMFmMCv.js} +2 -2
- package/dist/{deliver-q23ar_Pm.js → deliver-f3cIWxXT.js} +4 -4
- package/dist/{deps-Bf9dt2UO.js → deps-CdibsPMx.js} +1 -1
- package/dist/{devices-cli-C2gQTsB0.js → devices-cli-BJ3rVWOw.js} +2 -2
- package/dist/{devices-cli-DfiSkZ7k.js → devices-cli-DDPwF2Nx.js} +6 -6
- package/dist/{diagnostics-DlZODdRf.js → diagnostics-CYkqD5lP.js} +5 -5
- package/dist/{directory-cli-Bm5QYEo-.js → directory-cli-giqTe8Yg.js} +3 -3
- package/dist/{dm-policy-shared-CeFt0nch.js → dm-policy-shared-B61_yf6G.js} +1 -1
- package/dist/{dns-cli-CubLq4j9.js → dns-cli-Dssz4RqF.js} +3 -3
- package/dist/{docs-cli-PS8m1er7.js → docs-cli-Ct1STieY.js} +1 -1
- package/dist/{doctor-completion-CfF0J8fs.js → doctor-completion-CL7MyXlo.js} +2 -2
- package/dist/{doctor-completion-ScxFfN93.js → doctor-completion-k0HiL05o.js} +1 -1
- package/dist/{doctor-config-flow-C52W1uUK.js → doctor-config-flow-ljVnQJjo.js} +9 -9
- package/dist/entry.js +1 -1
- package/dist/{exec-approvals-cli-Cl-vWA1q.js → exec-approvals-cli-Cau1vPQI.js} +4 -4
- package/dist/{exec-approvals-cli-BaKWIf56.js → exec-approvals-cli-DsBoQu5H.js} +13 -13
- package/dist/extensionAPI.js +4 -4
- package/dist/{file-lock-BVUYnlQv.js → file-lock-2AecMjCa.js} +8 -8
- package/dist/{fs-safe-BdejYjW8.js → fs-safe-B0Is-oLk.js} +6 -6
- package/dist/{gateway-cli-kq5EWlnF.js → gateway-cli-DG_2YZ8B.js} +98 -98
- package/dist/{gateway-cli-CK-5nguV.js → gateway-cli-DgmGygc6.js} +16 -16
- package/dist/{gateway-rpc-Bzg_TTKP.js → gateway-rpc-Kv0-8W2E.js} +1 -1
- package/dist/{gateway-rpc-D12UaJS5.js → gateway-rpc-gaoD882s.js} +1 -1
- package/dist/{glass-ui-ws-B6p0iPsO.js → glass-ui-ws-Bof7krDJ.js} +67 -67
- package/dist/{glass-ui-ws-CVr0_1gT.js → glass-ui-ws-Dl45d7eU.js} +13 -13
- package/dist/{health-CPU9rQGj.js → health-CMbUI4aN.js} +4 -4
- package/dist/{health-CJb2CYtg.js → health-znS85U-F.js} +1 -1
- package/dist/{hooks-cli-DbgVZaP4.js → hooks-cli-Cb9BzCOY.js} +7 -7
- package/dist/{hooks-cli-13HCu5Xs.js → hooks-cli-Cgjor7F-.js} +59 -59
- package/dist/{image-ops-L70xVnpG.js → image-ops-BzCBIakN.js} +10 -10
- package/dist/index.js +52 -52
- package/dist/{inspect-CGKsaVZ4.js → inspect-DzYUb_Dl.js} +4 -4
- package/dist/{install-safe-path-B2JrFspY.js → install-safe-path-BrpA09f2.js} +11 -11
- package/dist/{installs-D890uIIW.js → installs-bnDlOSq2.js} +10 -10
- package/dist/{internal-DVCddhhN.js → internal-csqU78gW.js} +9 -9
- package/dist/{lifecycle-core-wFwnK_mD.js → lifecycle-core-cSR_xiIO.js} +5 -5
- package/dist/llm-slug-generator.js +4 -4
- package/dist/{local-roots-CgDCgCuM.js → local-roots-2Jb79HZ8.js} +1 -1
- package/dist/{logs-cli-R16VTptK.js → logs-cli-Kr145PO_.js} +7 -7
- package/dist/{logs-cli-CQeK5fn7.js → logs-cli-LiAjkog2.js} +3 -3
- package/dist/{manager-CxFs8Z_F.js → manager-CceVgXHV.js} +1 -1
- package/dist/{manager-B2SWSuad.js → manager-Cv4xI8sP.js} +1 -1
- package/dist/{manager-CHLdCC6u.js → manager-DG6PODgu.js} +15 -15
- package/dist/{manager-BhEbaYDa.js → manager-V4UCf0Av.js} +1 -1
- package/dist/{memory-DFpqcIst.js → memory-A2D5e8dL.js} +2 -2
- package/dist/{memory-DavRjdTi.js → memory-BFnx3v3_.js} +5 -5
- package/dist/{memory-cli-DZnq3S6s.js → memory-cli-1zjVJITN.js} +2 -2
- package/dist/{memory-cli-B-Cp1Sb1.js → memory-cli-CHNghdrm.js} +12 -12
- package/dist/{model-MUMSB_7d.js → model-Cwbcw-km.js} +1 -1
- package/dist/{model-auth-1EAQvYRv.js → model-auth-_C07_3Yr.js} +2 -2
- package/dist/{model-catalog-IWi6-nY9.js → model-catalog-BWurV7gl.js} +3 -3
- package/dist/{model-picker-Cf6UgQEh.js → model-picker-Dpkr5xBW.js} +5 -5
- package/dist/{model-selection-7wdmO-Iw.js → model-selection-CCTzD29o.js} +1 -1
- package/dist/{models-Cht7Mzvs.js → models-BYev6YAG.js} +3 -3
- package/dist/{models-cli-B_motPDX.js → models-cli-BbK8HMKa.js} +55 -55
- package/dist/{models-cli-DXswzgUR.js → models-cli-Fa5r1QYP.js} +9 -9
- package/dist/{models-config-B5Xxy-c-.js → models-config-DlXge3Sd.js} +8 -8
- package/dist/{node-cli-D-gsjRXY.js → node-cli-BPnBosC4.js} +27 -27
- package/dist/{node-cli-VmKhIXuP.js → node-cli-Cv7x1gGu.js} +1 -1
- package/dist/{node-service-BH08wY5j.js → node-service-Cc18m-uk.js} +1 -1
- package/dist/{nodes-cli-BMvxQGCp.js → nodes-cli-CN_m6PO5.js} +10 -10
- package/dist/{nodes-cli-D199d74o.js → nodes-cli-DaHOBbd4.js} +3 -3
- package/dist/{nodes-screen-De9ma6e1.js → nodes-screen-Cp5QP3ET.js} +4 -4
- package/dist/{npm-registry-spec-DTqn-NXZ.js → npm-registry-spec-C-muP97-.js} +9 -9
- package/dist/{onboard-DFJcbABp.js → onboard-B2IcTMv-.js} +15 -15
- package/dist/{onboard-CdRA8BRG.js → onboard-D-m6WTZl.js} +3 -3
- package/dist/{onboard-channels-fadyQGBK.js → onboard-channels-Z-Jkrk5-.js} +1 -1
- package/dist/{onboard-channels-Ca7ZFQ2Y.js → onboard-channels-wfGO5Zlh.js} +4 -4
- package/dist/{onboard-custom-BcRYreNG.js → onboard-custom-DnDrvxSg.js} +3 -3
- package/dist/{onboard-helpers-CQBpac8h.js → onboard-helpers-BKejzolA.js} +8 -8
- package/dist/{onboard-helpers-BcLPSb5N.js → onboard-helpers-Dhr98nj8.js} +1 -1
- package/dist/{onboard-hooks-2SCajRKc.js → onboard-hooks-D9jHwImb.js} +1 -1
- package/dist/{onboard-remote-Bo3tpC9N.js → onboard-remote-DZdMxd1Q.js} +1 -1
- package/dist/{onboard-remote-BWK5Ths4.js → onboard-remote-y3ZmP90U.js} +1 -1
- package/dist/{onboard-skills-BLl8HPJO.js → onboard-skills-2SUv-W7i.js} +1 -1
- package/dist/{onboard-skills-DvacccqZ.js → onboard-skills-BFhHfrt9.js} +3 -3
- package/dist/{onboarding-ojb2rFkA.js → onboarding-BckHLQMV.js} +7 -7
- package/dist/{onboarding-BywueA1d.js → onboarding-DqlPV372.js} +12 -12
- package/dist/{onboarding.finalize-DdxBQpUU.js → onboarding.finalize-Bwjv3jew.js} +31 -31
- package/dist/{onboarding.finalize-DHvlZi9G.js → onboarding.finalize-CbH_ShIW.js} +9 -9
- package/dist/{onboarding.gateway-config-DPBNWNV6.js → onboarding.gateway-config-CiRo9EMt.js} +8 -8
- package/dist/{onboarding.gateway-config-ZK9517uR.js → onboarding.gateway-config-sNSeEykB.js} +3 -3
- package/dist/{openai-model-default-BkuuK-Di.js → openai-model-default-De-UAjwg.js} +2 -2
- package/dist/{pairing-cli-Rsae0KnN.js → pairing-cli-CBMMCNnx.js} +5 -5
- package/dist/{pairing-store-BNhJOnWn.js → pairing-store-Be-ZQK87.js} +1 -1
- package/dist/{pairing-token-Dcy37-4s.js → pairing-token-B703A1U3.js} +7 -7
- package/dist/{paths-DObzwe08.js → paths-BWqg8NZT.js} +1 -1
- package/dist/{pi-auth-json-Db8XJVGL.js → pi-auth-json-D-vdh-nY.js} +6 -6
- package/dist/{pi-embedded-DJE9TMwq.js → pi-embedded-B9rtlNMc.js} +32 -16
- package/dist/{pi-embedded-helpers-D-OFjhdI.js → pi-embedded-helpers-j1JrlsI0.js} +6 -6
- package/dist/{pi-tools.policy-H2t-Xkfc.js → pi-tools.policy-CvAqjEH9.js} +3 -3
- package/dist/{plugin-auto-enable-DJBhDIMq.js → plugin-auto-enable-BXSJTxI7.js} +1 -1
- package/dist/{plugin-registry-tG7NXc3Y.js → plugin-registry-B43UosQh.js} +3 -3
- package/dist/{plugin-registry-Tlmjr-LX.js → plugin-registry-CS4WgHbu.js} +1 -1
- package/dist/plugin-sdk/gateway/protocol/schema/logs-chat.d.ts +1 -1
- package/dist/plugin-sdk/infra/symframe-broadcast.d.ts +18 -6
- package/dist/{plugins-cli-CRKD8aho.js → plugins-cli-BV2wbjfI.js} +54 -54
- package/dist/{plugins-cli-Cm0G_-Y5.js → plugins-cli-BY42hyHP.js} +7 -7
- package/dist/{ports-r7LBic2V.js → ports-Bi3V_3n9.js} +1 -1
- package/dist/{ports-gxLM5ahL.js → ports-CB_Iu83U.js} +2 -2
- package/dist/{program-DEmAlwmD.js → program-P9F1DxBa.js} +12 -12
- package/dist/{program-context-DRCRbDpu.js → program-context-BmXxHUKe.js} +40 -40
- package/dist/{prompt-select-styled-pomsR-zf.js → prompt-select-styled-B2ah467m.js} +7 -7
- package/dist/{prompt-select-styled-B41Tx9aC.js → prompt-select-styled-BlQZX6pK.js} +38 -38
- package/dist/{provider-auth-helpers-rKWs_r7a.js → provider-auth-helpers-Bgb_Bfp9.js} +1 -1
- package/dist/{provider-auth-helpers-CdQwOam7.js → provider-auth-helpers-WLwb6tL4.js} +6 -6
- package/dist/{push-apns-eCM0qmrY.js → push-apns-CBGvXev_.js} +4 -4
- package/dist/{push-apns-CZPUHftn.js → push-apns-DnSCjFu7.js} +1 -1
- package/dist/{pw-ai-BiBvIJzd.js → pw-ai-CP5pn3eU.js} +7 -7
- package/dist/{pw-ai-v__CyAlM.js → pw-ai-DOAsQ5NX.js} +1 -1
- package/dist/{pw-ai-DLsdzdgc.js → pw-ai-DY_6l11g.js} +1 -1
- package/dist/{qmd-manager-C8-M4Pru.js → qmd-manager-Dxyue7B1.js} +19 -19
- package/dist/{qr-cli-1sCVaPcF.js → qr-cli-DHw6muwK.js} +3 -3
- package/dist/{register.agent-BQPvYYdn.js → register.agent-BuEcmVg0.js} +12 -12
- package/dist/{register.agent-N1hoqMFR.js → register.agent-CXdTiqyP.js} +67 -67
- package/dist/{register.configure-BHHZ44xB.js → register.configure-DVcn-gCO.js} +70 -70
- package/dist/{register.configure-BAc3P4Z-.js → register.configure-YDKJ-KQg.js} +14 -14
- package/dist/{register.maintenance-lX0a3Hzl.js → register.maintenance-BiGvpEj-.js} +13 -13
- package/dist/{register.maintenance-DDgy5Iyy.js → register.maintenance-cpspl8D6.js} +67 -67
- package/dist/{register.message-Br-IH_0z.js → register.message-BIuLbESM.js} +7 -7
- package/dist/{register.message-B4lDhHpE.js → register.message-BjcYy5UG.js} +47 -47
- package/dist/{register.onboard-B-GoYJIc.js → register.onboard-C4vIASed.js} +6 -6
- package/dist/{register.onboard-Bv0s2_KV.js → register.onboard-D4RN92s2.js} +25 -25
- package/dist/{register.setup-DQ6KLkAI.js → register.setup-BvoXF0xl.js} +28 -28
- package/dist/{register.setup-4lNdC98i.js → register.setup-D-Jt2e1d.js} +6 -6
- package/dist/{register.status-health-sessions-Cg7bK5K2.js → register.status-health-sessions-BY9hMD1s.js} +8 -8
- package/dist/{register.status-health-sessions-ByGn71_M.js → register.status-health-sessions-DjDvCXBn.js} +41 -41
- package/dist/{register.subclis-FMlcLBX0.js → register.subclis-Cibmeapc.js} +20 -20
- package/dist/{replies-CbXXjn9X.js → replies-B_3j7R_Q.js} +1 -1
- package/dist/{reply-prefix-BFNeXT65.js → reply-prefix-CtZtkTJK.js} +1 -1
- package/dist/{resolve-route-C1IIA6kH.js → resolve-route-Du0VftVs.js} +1 -1
- package/dist/{routes-ivqbutvM.js → routes-BwTUoI5h.js} +10 -10
- package/dist/{rpc-Dk1Az_d8.js → rpc-BnAKPQDB.js} +1 -1
- package/dist/{rpc-JAmDaTYt.js → rpc-CwxSZZOx.js} +1 -1
- package/dist/{run-main-DSyeVDsT.js → run-main-BhEQjKtM.js} +20 -20
- package/dist/{sandbox-BkznAPKO.js → sandbox-CZGTCone.js} +18 -18
- package/dist/{sandbox-cli-Bb9cBtBH.js → sandbox-cli-DEtGT_4y.js} +13 -13
- package/dist/{security-cli-DmgGLP83.js → security-cli-CS-ZT1LE.js} +3 -3
- package/dist/{security-cli-D47LQbpf.js → security-cli-DJd7Fcdy.js} +29 -29
- package/dist/{send-B0jHSNMF.js → send-CxjvucMO.js} +7 -7
- package/dist/{server-context-ChcbJgNo.js → server-context-DXdk410X.js} +5 -5
- package/dist/{server-methods-DGBBt49x.js → server-methods-CWxr5b-w.js} +19 -13
- package/dist/{server-methods-BkHB2MOW.js → server-methods-DfVfzYqq.js} +68 -62
- package/dist/{server-node-events-C186LRm0.js → server-node-events-B0yC6hi1.js} +48 -48
- package/dist/{server-node-events-D-Akk3uq.js → server-node-events-ClDEcUTJ.js} +8 -8
- package/dist/{service-e6MzlLCd.js → service-CRZoXO_n.js} +15 -15
- package/dist/{session-dirs-C9E2G0yZ.js → session-dirs-a00Ad2SO.js} +2 -2
- package/dist/{session-utils-Cs1jlD-q.js → session-utils-CJhcRx3E.js} +14 -14
- package/dist/{sessions-Dxf5Kjig.js → sessions-BCc3THTm.js} +10 -10
- package/dist/{shared-1xPo9ygd.js → shared-C39SiDDJ.js} +1 -1
- package/dist/{shared-COtpr3Ad.js → shared-Dh-O8nRd.js} +3 -3
- package/dist/{skill-commands-DDGGlq68.js → skill-commands-DWvXs3lz.js} +4 -4
- package/dist/{skill-scanner-BCgVcIwi.js → skill-scanner-CIlHPszT.js} +5 -5
- package/dist/{skills-BwDmcZdt.js → skills-CYcBtLGH.js} +4 -4
- package/dist/{skills-cli-B-7TY-vS.js → skills-cli-CD9s3cgm.js} +7 -7
- package/dist/{skills-install-Dwzsjoc8.js → skills-install-BTa9IuQ6.js} +3 -3
- package/dist/{skills-remote-bz71Bstn.js → skills-remote-BcRQTDsZ.js} +3 -3
- package/dist/{skills-status-BKX1PjCc.js → skills-status-DLnCHUZ2.js} +1 -1
- package/dist/{sqlite-Cod7C5ba.js → sqlite-BpogPlQW.js} +5 -5
- package/dist/{status-CFgCSaDq.js → status-BWxLtb3D.js} +23 -23
- package/dist/{status-poPDyC8O.js → status-Doq8T1zj.js} +3 -3
- package/dist/{status-Bahhq7OQ.js → status-K1k4g3Ai.js} +1 -1
- package/dist/{status-D9LC5P_Y.js → status-ojZB_Lrf.js} +5 -5
- package/dist/{status.update-DGJi0OLl.js → status.update-CKfyV6zw.js} +3 -3
- package/dist/{subagent-registry-V2o45tIn.js → subagent-registry-BOt7g9hn.js} +21 -10
- package/dist/{symframe-cli-bxdpivve.js → symframe-cli-CrUtJw_7.js} +31 -7
- package/dist/{symframe-cli-ppdMo15M.js → symframe-cli-D1CtN3pf.js} +37 -13
- package/dist/{symi-root-BQ0IpoW2.js → symi-root-DeCVdZB4.js} +2 -2
- package/dist/{synthesis-B2EyHFXy.js → synthesis-BIQLrbys.js} +6 -6
- package/dist/{synthesis-BlJyO1E_.js → synthesis-Bc2QkGvt.js} +4 -4
- package/dist/{synthesis-CPSq83PP.js → synthesis-VZNnlUTf.js} +45 -45
- package/dist/{synthesis-C2WbvLOI.js → synthesis-yl24Ovw4.js} +4 -4
- package/dist/{system-cli-nPyjUPBH.js → system-cli-CvN-Wq9U.js} +3 -3
- package/dist/{system-cli-BroqLjZ6.js → system-cli-r7WJj0Xh.js} +7 -7
- package/dist/{systemd-CUIM0n5P.js → systemd-CsoVnIbM.js} +5 -5
- package/dist/{systemd-hints-CsrzMCTD.js → systemd-hints-QISwLlFU.js} +6 -6
- package/dist/{systemd-linger-BzYk7A6M.js → systemd-linger-BnhuRdbt.js} +1 -1
- package/dist/{tui-Bp9k5skv.js → tui-BxgdImL_.js} +2 -2
- package/dist/{tui-DzROrE20.js → tui-J7Jxp-FF.js} +7 -7
- package/dist/{tui-cli-BHBF8O-3.js → tui-cli-DR48dU_C.js} +19 -19
- package/dist/{tui-cli-Dv4hBFdc.js → tui-cli-DqvgN5ng.js} +3 -3
- package/dist/{unified-runner-CIQIkbvi.js → unified-runner-BV5TdNFv.js} +32 -16
- package/dist/{unified-runner-CduaBH_0.js → unified-runner-DXjH-prv.js} +117 -106
- package/dist/{update-yYduAjKd.js → update-Cb0Fmxic.js} +3 -3
- package/dist/{update-check-BCL_K7kx.js → update-check-u6Jgr1cz.js} +5 -5
- package/dist/{update-cli-WcLxjBiY.js → update-cli-CKpjWtlv.js} +77 -77
- package/dist/{update-cli-BKnHBe8a.js → update-cli-Dn6QQZLd.js} +14 -14
- package/dist/{update-runner-BLV8SI96.js → update-runner-G2YgEATs.js} +15 -15
- package/dist/{webhooks-cli-D5k-Y2A8.js → webhooks-cli-DjUITimx.js} +4 -4
- package/dist/{with-timeout-DPR4A2dx.js → with-timeout-CLrF-Yr_.js} +1 -1
- package/dist/{workspace-dirs-jKFQf7of.js → workspace-dirs-DCICLTHx.js} +1 -1
- package/dist/{wsl-CglTdtlb.js → wsl-DTi7eX-V.js} +2 -2
- package/extensions/memory-core/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +12 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/outlook/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
// ── Symframe Substrate ─────────────────────────────────────────────────
|
|
2
|
+
// Stage B of the Dynamic Glass Panel arc — see ~/Documents/dynamic-glass-panel.md.
|
|
3
|
+
//
|
|
4
|
+
// The substrate is the ambient reasoning layer that lives BEHIND the
|
|
5
|
+
// foreground cards in the symframe. It's the single move that converts
|
|
6
|
+
// the panel from "card list with a tagline" into a felt "window into
|
|
7
|
+
// the agent's mind" — there is always something alive in the negative
|
|
8
|
+
// space, even when no specific card is being pushed.
|
|
9
|
+
//
|
|
10
|
+
// What this module owns:
|
|
11
|
+
// - The substrate container (#symframe-substrate)
|
|
12
|
+
// - The live trace (the in-flight thinking entry, pinned at top with a
|
|
13
|
+
// pulsing dot — full opacity, no blur)
|
|
14
|
+
// - Recent reasoning entries (every block routed through the old
|
|
15
|
+
// reasoning-feed window globals — `appendToReasoningPanel`,
|
|
16
|
+
// `injectReasoningRunSeparator`, `openLiveThinking`,
|
|
17
|
+
// `updateLiveThinking`, `closeLiveThinking`, `clearReasoningPanel`)
|
|
18
|
+
// - Per-entry decay tick: opacity / blur / scale / height collapse as
|
|
19
|
+
// a function of (now - entry.createdAt). See DECAY_TIERS below.
|
|
20
|
+
// - Quiet-mind empty state when the substrate has no entries
|
|
21
|
+
//
|
|
22
|
+
// Backward-compatible surface:
|
|
23
|
+
// This module DEFINES the same six window globals that render.js used
|
|
24
|
+
// to expose for the reasoning panel. Script load order in index.html
|
|
25
|
+
// loads render.js first then this file, so our definitions override.
|
|
26
|
+
// app.js (~12 call sites) is unchanged.
|
|
27
|
+
//
|
|
28
|
+
// Layout:
|
|
29
|
+
// The substrate is one of two children of .symframe-stack (the other
|
|
30
|
+
// is .symframe-cards). Both share a single CSS grid cell via
|
|
31
|
+
// grid-area: overlay, with the substrate at z-index 0 and cards at
|
|
32
|
+
// z-index 1. Cards have backdrop-filter so the substrate is visible
|
|
33
|
+
// THROUGH them — the agent's mind breathes behind whatever artifacts
|
|
34
|
+
// are foregrounded.
|
|
35
|
+
|
|
36
|
+
"use strict";
|
|
37
|
+
|
|
38
|
+
(function () {
|
|
39
|
+
const substrate = document.getElementById("symframe-substrate");
|
|
40
|
+
if (!substrate) {
|
|
41
|
+
// Substrate not in DOM — nothing to do. The 6 window globals stay
|
|
42
|
+
// bound to render.js's no-op-on-missing-DOM implementations.
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ── Decay tiers ─────────────────────────────────────────────────────
|
|
47
|
+
// Each entry carries dataset.createdAt; the tick reads its age and
|
|
48
|
+
// looks up the matching tier. Tiers are evaluated in order; first
|
|
49
|
+
// match (age < maxAge) wins. Constants tuned per the plan §5.2; expect
|
|
50
|
+
// to revisit live.
|
|
51
|
+
const DECAY_TIERS = [
|
|
52
|
+
{ maxAge: 10_000, opacity: 1.0, blur: 0, scale: 1.0, texture: false },
|
|
53
|
+
{ maxAge: 30_000, opacity: 0.85, blur: 1, scale: 1.0, texture: false },
|
|
54
|
+
{ maxAge: 120_000, opacity: 0.55, blur: 2, scale: 1.0, texture: false },
|
|
55
|
+
{ maxAge: 600_000, opacity: 0.25, blur: 4, scale: 0.97, texture: false },
|
|
56
|
+
{ maxAge: Infinity, opacity: 0.08, blur: 6, scale: 0.94, texture: true },
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
const DECAY_TICK_MS = 1000;
|
|
60
|
+
|
|
61
|
+
// ── Live trace state ────────────────────────────────────────────────
|
|
62
|
+
// The "live" entry is the in-flight thinking stream. It's pinned at
|
|
63
|
+
// the top of the substrate, exempt from decay, and has a pulsing dot.
|
|
64
|
+
// When closeLiveThinking fires, the live class is dropped and the
|
|
65
|
+
// entry starts decaying like any other.
|
|
66
|
+
let liveEntry = null;
|
|
67
|
+
let liveBody = null;
|
|
68
|
+
let liveBuffer = "";
|
|
69
|
+
|
|
70
|
+
// Decay tick handle. Pauses when page is hidden (Page Visibility API)
|
|
71
|
+
// so a backgrounded tab doesn't burn CPU on substrate-only animation.
|
|
72
|
+
let decayHandle = null;
|
|
73
|
+
|
|
74
|
+
// ── DOM helpers ─────────────────────────────────────────────────────
|
|
75
|
+
function escHtml(s) {
|
|
76
|
+
return String(s ?? "")
|
|
77
|
+
.replace(/&/g, "&")
|
|
78
|
+
.replace(/</g, "<")
|
|
79
|
+
.replace(/>/g, ">")
|
|
80
|
+
.replace(/"/g, """)
|
|
81
|
+
.replace(/'/g, "'");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function ensureEmptyRemoved() {
|
|
85
|
+
const empty = substrate.querySelector(".substrate-empty");
|
|
86
|
+
if (empty) {
|
|
87
|
+
empty.remove();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function renderQuietMind() {
|
|
92
|
+
if (substrate.querySelector(".substrate-empty")) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const empty = document.createElement("div");
|
|
96
|
+
empty.className = "substrate-empty";
|
|
97
|
+
empty.innerHTML = `
|
|
98
|
+
<span class="substrate-quiet-dot" aria-hidden="true"></span>
|
|
99
|
+
<span class="substrate-quiet-label">quiet mind</span>
|
|
100
|
+
`;
|
|
101
|
+
substrate.appendChild(empty);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function insertAtTopRespectingLive(entry) {
|
|
105
|
+
// Live entry stays at index 0; everything else prepends after it.
|
|
106
|
+
if (liveEntry && substrate.firstChild === liveEntry) {
|
|
107
|
+
liveEntry.after(entry);
|
|
108
|
+
} else {
|
|
109
|
+
substrate.prepend(entry);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ── Decay ────────────────────────────────────────────────────────────
|
|
114
|
+
function applyDecay(el, age) {
|
|
115
|
+
let tier = DECAY_TIERS[DECAY_TIERS.length - 1];
|
|
116
|
+
for (const t of DECAY_TIERS) {
|
|
117
|
+
if (age < t.maxAge) {
|
|
118
|
+
tier = t;
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
el.style.setProperty("--substrate-opacity", String(tier.opacity));
|
|
123
|
+
el.style.setProperty("--substrate-blur", `${tier.blur}px`);
|
|
124
|
+
el.style.setProperty("--substrate-scale", String(tier.scale));
|
|
125
|
+
el.classList.toggle("substrate-texture", tier.texture);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function tickDecay() {
|
|
129
|
+
const now = Date.now();
|
|
130
|
+
const entries = substrate.querySelectorAll(".substrate-entry:not(.substrate-live)");
|
|
131
|
+
for (const e of entries) {
|
|
132
|
+
const createdAt = Number(e.dataset.createdAt) || now;
|
|
133
|
+
applyDecay(e, now - createdAt);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function startDecayTick() {
|
|
138
|
+
if (decayHandle) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
decayHandle = setInterval(tickDecay, DECAY_TICK_MS);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function stopDecayTick() {
|
|
145
|
+
if (decayHandle) {
|
|
146
|
+
clearInterval(decayHandle);
|
|
147
|
+
decayHandle = null;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
document.addEventListener("visibilitychange", () => {
|
|
152
|
+
if (document.hidden) {
|
|
153
|
+
stopDecayTick();
|
|
154
|
+
} else if (substrate.querySelector(".substrate-entry:not(.substrate-live)")) {
|
|
155
|
+
startDecayTick();
|
|
156
|
+
tickDecay(); // immediate catch-up after a long pause
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// ── Entry builders ──────────────────────────────────────────────────
|
|
161
|
+
// Returns an HTMLElement or null (null = skip, e.g. empty block).
|
|
162
|
+
// Class names mirror the existing reasoning-* set so the badge/body
|
|
163
|
+
// styles from style.css continue to apply unchanged.
|
|
164
|
+
function buildEntryForBlock(block) {
|
|
165
|
+
const entry = document.createElement("div");
|
|
166
|
+
entry.className = "substrate-entry reasoning-entry";
|
|
167
|
+
entry.dataset.createdAt = String(Date.now());
|
|
168
|
+
|
|
169
|
+
switch (block.type) {
|
|
170
|
+
case "text": {
|
|
171
|
+
const text = (block.text ?? "").trim();
|
|
172
|
+
if (!text) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
entry.innerHTML = `
|
|
176
|
+
<div class="reasoning-entry-header">
|
|
177
|
+
<span class="reasoning-entry-badge badge-narration">✦ NOTE</span>
|
|
178
|
+
<span class="reasoning-entry-name">${escHtml(text.split("\n")[0].slice(0, 60))}${text.length > 60 ? "…" : ""}</span>
|
|
179
|
+
</div>
|
|
180
|
+
`;
|
|
181
|
+
return entry;
|
|
182
|
+
}
|
|
183
|
+
case "thinking": {
|
|
184
|
+
const text = (block.thinking ?? "").trim();
|
|
185
|
+
if (!text) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
entry.innerHTML = `
|
|
189
|
+
<div class="reasoning-entry-header">
|
|
190
|
+
<span class="reasoning-entry-badge badge-think">◈ THINK</span>
|
|
191
|
+
<span class="reasoning-entry-name">${escHtml(text.split("\n")[0].slice(0, 60))}${text.length > 60 ? "…" : ""}</span>
|
|
192
|
+
</div>
|
|
193
|
+
<div class="reasoning-think-body">${escHtml(text)}</div>
|
|
194
|
+
`;
|
|
195
|
+
return entry;
|
|
196
|
+
}
|
|
197
|
+
case "tool_use":
|
|
198
|
+
case "toolCall": {
|
|
199
|
+
const name = block.name ?? "tool";
|
|
200
|
+
const inputData = block.input ?? block.arguments ?? {};
|
|
201
|
+
const inputJson = inputData ? JSON.stringify(inputData, null, 2) : "{}";
|
|
202
|
+
let preview = "";
|
|
203
|
+
try {
|
|
204
|
+
const obj = typeof inputData === "string" ? JSON.parse(inputData) : inputData;
|
|
205
|
+
const keys = Object.keys(obj ?? {});
|
|
206
|
+
if (keys.length) {
|
|
207
|
+
const val = String(obj[keys[0]]).slice(0, 50);
|
|
208
|
+
preview = `${keys[0]}: ${val}${val.length >= 50 ? "…" : ""}`;
|
|
209
|
+
}
|
|
210
|
+
} catch {
|
|
211
|
+
/* ignore */
|
|
212
|
+
}
|
|
213
|
+
entry.innerHTML = `
|
|
214
|
+
<div class="reasoning-entry-header">
|
|
215
|
+
<span class="reasoning-entry-badge badge-tool">⚙ TOOL</span>
|
|
216
|
+
<span class="reasoning-entry-name">${escHtml(name)}</span>
|
|
217
|
+
</div>
|
|
218
|
+
${preview ? `<div class="reasoning-tool-preview">${escHtml(preview)}</div>` : ""}
|
|
219
|
+
<div class="reasoning-tool-detail">${escHtml(inputJson)}</div>
|
|
220
|
+
`;
|
|
221
|
+
entry.style.cursor = "pointer";
|
|
222
|
+
entry.addEventListener("click", () => entry.classList.toggle("expanded"));
|
|
223
|
+
return entry;
|
|
224
|
+
}
|
|
225
|
+
case "tool_result": {
|
|
226
|
+
const content = Array.isArray(block.content)
|
|
227
|
+
? block.content.map((b) => b.text ?? "").join("\n")
|
|
228
|
+
: String(block.content ?? "");
|
|
229
|
+
const chars = content.length;
|
|
230
|
+
const isError = block.is_error === true;
|
|
231
|
+
entry.innerHTML = `
|
|
232
|
+
<div class="reasoning-entry-header">
|
|
233
|
+
<span class="reasoning-entry-badge badge-result">${isError ? "⚠ ERROR" : "↩ RESULT"}</span>
|
|
234
|
+
<span class="reasoning-entry-name">${chars} chars</span>
|
|
235
|
+
</div>
|
|
236
|
+
<div class="reasoning-result-meta">${escHtml(content.slice(0, 80))}${chars > 80 ? "…" : ""}</div>
|
|
237
|
+
`;
|
|
238
|
+
return entry;
|
|
239
|
+
}
|
|
240
|
+
default:
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// ── Window globals (preserve render.js signatures) ──────────────────
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Append a finished block to the substrate. Block shapes match what
|
|
249
|
+
* app.js produces from agent events: { type:"text"|"thinking"|
|
|
250
|
+
* "tool_use"|"toolCall"|"tool_result", ... }.
|
|
251
|
+
*/
|
|
252
|
+
window.appendToReasoningPanel = function (block) {
|
|
253
|
+
ensureEmptyRemoved();
|
|
254
|
+
const entry = buildEntryForBlock(block);
|
|
255
|
+
if (!entry) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
insertAtTopRespectingLive(entry);
|
|
259
|
+
startDecayTick();
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Inject a horizontal-rule + timestamp separator marking a new agent
|
|
264
|
+
* run. Called from app.js on lifecycle:start.
|
|
265
|
+
*/
|
|
266
|
+
window.injectReasoningRunSeparator = function () {
|
|
267
|
+
ensureEmptyRemoved();
|
|
268
|
+
const sep = document.createElement("div");
|
|
269
|
+
sep.className = "substrate-entry substrate-run-sep reasoning-run-sep";
|
|
270
|
+
sep.dataset.createdAt = String(Date.now());
|
|
271
|
+
const now = new Date();
|
|
272
|
+
const hhmm = now.toLocaleTimeString("en-US", {
|
|
273
|
+
hour: "2-digit",
|
|
274
|
+
minute: "2-digit",
|
|
275
|
+
hour12: false,
|
|
276
|
+
});
|
|
277
|
+
sep.innerHTML = `<span class="reasoning-run-sep-label">RUN · ${hhmm}</span>`;
|
|
278
|
+
insertAtTopRespectingLive(sep);
|
|
279
|
+
startDecayTick();
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Clear all substrate entries and restore the quiet-mind empty state.
|
|
284
|
+
* Called from app.js on session reset.
|
|
285
|
+
*/
|
|
286
|
+
window.clearReasoningPanel = function () {
|
|
287
|
+
substrate.innerHTML = "";
|
|
288
|
+
liveEntry = null;
|
|
289
|
+
liveBody = null;
|
|
290
|
+
liveBuffer = "";
|
|
291
|
+
stopDecayTick();
|
|
292
|
+
renderQuietMind();
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Open the live thinking entry — pinned at top, exempt from decay,
|
|
297
|
+
* with a pulsing dot. Called when streaming starts.
|
|
298
|
+
*/
|
|
299
|
+
window.openLiveThinking = function () {
|
|
300
|
+
if (liveEntry) {
|
|
301
|
+
return; // already open
|
|
302
|
+
}
|
|
303
|
+
ensureEmptyRemoved();
|
|
304
|
+
liveBuffer = "";
|
|
305
|
+
const entry = document.createElement("div");
|
|
306
|
+
entry.className = "substrate-entry substrate-live reasoning-entry";
|
|
307
|
+
entry.id = "substrate-live-entry";
|
|
308
|
+
entry.innerHTML = `
|
|
309
|
+
<div class="reasoning-entry-header">
|
|
310
|
+
<span class="substrate-live-dot" aria-hidden="true"></span>
|
|
311
|
+
<span class="reasoning-entry-badge badge-think">◈ THINKING</span>
|
|
312
|
+
<span class="reasoning-entry-name" id="substrate-live-name">…</span>
|
|
313
|
+
</div>
|
|
314
|
+
<div class="reasoning-think-body" id="substrate-live-body"></div>
|
|
315
|
+
`;
|
|
316
|
+
substrate.prepend(entry);
|
|
317
|
+
liveEntry = entry;
|
|
318
|
+
liveBody = entry.querySelector("#substrate-live-body");
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Append text to the live thinking entry's body. Idempotent on open —
|
|
323
|
+
* calls openLiveThinking if no live entry exists yet.
|
|
324
|
+
*/
|
|
325
|
+
window.updateLiveThinking = function (text) {
|
|
326
|
+
if (!liveEntry) {
|
|
327
|
+
window.openLiveThinking();
|
|
328
|
+
}
|
|
329
|
+
if (typeof text !== "string" || !text) {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
liveBuffer += text;
|
|
333
|
+
if (liveBody) {
|
|
334
|
+
liveBody.textContent = liveBuffer;
|
|
335
|
+
}
|
|
336
|
+
// Update name preview to the first line
|
|
337
|
+
const nameEl = liveEntry?.querySelector("#substrate-live-name");
|
|
338
|
+
if (nameEl) {
|
|
339
|
+
const firstLine = liveBuffer.split("\n")[0].slice(0, 60);
|
|
340
|
+
nameEl.textContent = firstLine + (liveBuffer.length > 60 ? "…" : "");
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Close the live thinking entry: drop the live class so it starts
|
|
346
|
+
* decaying like any other entry, and stamp its createdAt to "now" so
|
|
347
|
+
* the decay timer starts from when it finished, not when it opened.
|
|
348
|
+
*/
|
|
349
|
+
window.closeLiveThinking = function () {
|
|
350
|
+
if (!liveEntry) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
liveEntry.classList.remove("substrate-live");
|
|
354
|
+
liveEntry.removeAttribute("id");
|
|
355
|
+
liveEntry.dataset.createdAt = String(Date.now());
|
|
356
|
+
const nameEl = liveEntry.querySelector("#substrate-live-name");
|
|
357
|
+
if (nameEl) {
|
|
358
|
+
nameEl.removeAttribute("id");
|
|
359
|
+
}
|
|
360
|
+
const bodyEl = liveEntry.querySelector("#substrate-live-body");
|
|
361
|
+
if (bodyEl) {
|
|
362
|
+
bodyEl.removeAttribute("id");
|
|
363
|
+
}
|
|
364
|
+
liveEntry = null;
|
|
365
|
+
liveBody = null;
|
|
366
|
+
liveBuffer = "";
|
|
367
|
+
startDecayTick();
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
// Extract thinking text from a content array — used by streaming code
|
|
371
|
+
// in app.js to extract just the thinking portion from a content
|
|
372
|
+
// array (Anthropic-style multi-block messages). Recursive on
|
|
373
|
+
// content.content to handle wrapper-shape messages.
|
|
374
|
+
window.extractThinkingText = function (content) {
|
|
375
|
+
if (!content) {
|
|
376
|
+
return "";
|
|
377
|
+
}
|
|
378
|
+
if (typeof content === "string") {
|
|
379
|
+
return "";
|
|
380
|
+
}
|
|
381
|
+
if (Array.isArray(content)) {
|
|
382
|
+
return content
|
|
383
|
+
.filter((b) => b?.type === "thinking")
|
|
384
|
+
.map((b) => b.thinking ?? "")
|
|
385
|
+
.join("");
|
|
386
|
+
}
|
|
387
|
+
if (content?.content) {
|
|
388
|
+
return window.extractThinkingText(content.content);
|
|
389
|
+
}
|
|
390
|
+
return "";
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
// ── Initial state ───────────────────────────────────────────────────
|
|
394
|
+
renderQuietMind();
|
|
395
|
+
})();
|
|
@@ -358,7 +358,21 @@
|
|
|
358
358
|
const titleSpan = document.createElement("span");
|
|
359
359
|
titleSpan.textContent = card.title || "";
|
|
360
360
|
header.appendChild(titleSpan);
|
|
361
|
-
|
|
361
|
+
// Stage C: pin glyph for pinned cards. Click toggles unpin.
|
|
362
|
+
if (card.pinned) {
|
|
363
|
+
const pinGlyph = document.createElement("button");
|
|
364
|
+
pinGlyph.className = "symframe-card-pin";
|
|
365
|
+
pinGlyph.type = "button";
|
|
366
|
+
pinGlyph.setAttribute("aria-label", "Unpin");
|
|
367
|
+
pinGlyph.title = "Pinned — click to unpin";
|
|
368
|
+
pinGlyph.textContent = "📌";
|
|
369
|
+
pinGlyph.addEventListener("click", (e) => {
|
|
370
|
+
e.preventDefault();
|
|
371
|
+
e.stopPropagation();
|
|
372
|
+
unpin(card.id);
|
|
373
|
+
});
|
|
374
|
+
header.appendChild(pinGlyph);
|
|
375
|
+
} else if (card.dismissable && !card.sticky) {
|
|
362
376
|
const dismiss = document.createElement("button");
|
|
363
377
|
dismiss.className = "symframe-card-dismiss";
|
|
364
378
|
dismiss.type = "button";
|
|
@@ -535,6 +549,12 @@
|
|
|
535
549
|
* Remove a card from the registry + DOM. Sticky cards refuse removal
|
|
536
550
|
* unless force=true is passed (defensive — the system panels really
|
|
537
551
|
* shouldn't disappear via stray API calls).
|
|
552
|
+
*
|
|
553
|
+
* Stage C: pinned cards behave like sticky for the user-side dismiss
|
|
554
|
+
* button (× hidden in the header) but `remove` still drops them when
|
|
555
|
+
* called — the pin survives in localStorage and the card re-appears
|
|
556
|
+
* on the next reload. To actually drop a pinned card permanently,
|
|
557
|
+
* the agent / user must unpin first.
|
|
538
558
|
*/
|
|
539
559
|
function remove(id, force = false) {
|
|
540
560
|
const entry = cards.get(id);
|
|
@@ -553,17 +573,193 @@
|
|
|
553
573
|
return true;
|
|
554
574
|
}
|
|
555
575
|
|
|
576
|
+
// ── Stage C: dwell / release / recall / pin / unpin ────────────────
|
|
577
|
+
// The CRUD vocabulary (add/update/remove) treats the panel as a
|
|
578
|
+
// notification list. These verbs treat it as a mind-window: cards
|
|
579
|
+
// can be foregrounded ("dwell"), softly let go of ("release"),
|
|
580
|
+
// brought back ("recall"), or persisted across sessions ("pin").
|
|
581
|
+
|
|
582
|
+
const RECENTLY_RELEASED_MAX = 10;
|
|
583
|
+
/** @type {Array<{id:string, card:object, releasedAt:number}>} */
|
|
584
|
+
const recentlyReleased = [];
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Pull a card to the top of the stack with a brief cyan border pulse.
|
|
588
|
+
* Implementation: prepend the element (newest-first stack order
|
|
589
|
+
* normally has it there if it was just added, but for older cards
|
|
590
|
+
* this lifts them up), then add a `dwelling` class for a 600ms
|
|
591
|
+
* CSS pulse animation. Sticky cards aren't reordered (they live at
|
|
592
|
+
* the anchored end of the stack by design).
|
|
593
|
+
*/
|
|
594
|
+
function dwell(id) {
|
|
595
|
+
const entry = cards.get(id);
|
|
596
|
+
if (!entry) {
|
|
597
|
+
console.warn(`[symframe] dwell: unknown id ${id}`);
|
|
598
|
+
return false;
|
|
599
|
+
}
|
|
600
|
+
if (!entry.element) {
|
|
601
|
+
console.warn(`[symframe] dwell: card ${id} has no element`);
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
if (!entry.sticky) {
|
|
605
|
+
// Re-prepend to bring to top of ephemeral stack.
|
|
606
|
+
container.prepend(entry.element);
|
|
607
|
+
}
|
|
608
|
+
entry.element.classList.remove("symframe-dwelling");
|
|
609
|
+
// Re-flow so the animation restarts even on repeated dwell calls.
|
|
610
|
+
void entry.element.offsetWidth;
|
|
611
|
+
entry.element.classList.add("symframe-dwelling");
|
|
612
|
+
setTimeout(() => entry.element?.classList.remove("symframe-dwelling"), 700);
|
|
613
|
+
return true;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Soft-dismiss a card. Animated fade + scale; on animation end the
|
|
618
|
+
* element is removed from the registry and DOM. Unlike `remove`,
|
|
619
|
+
* `release` records the card in a session ring buffer so `recall(id)`
|
|
620
|
+
* can bring it back. Sticky cards refuse release without force=true.
|
|
621
|
+
*/
|
|
622
|
+
function release(id, force = false) {
|
|
623
|
+
const entry = cards.get(id);
|
|
624
|
+
if (!entry) {
|
|
625
|
+
return false;
|
|
626
|
+
}
|
|
627
|
+
if (entry.sticky && !force) {
|
|
628
|
+
console.warn(`[symframe] release: refusing sticky card '${id}' without force=true`);
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
// Snapshot for recall (strip the live DOM element)
|
|
632
|
+
const snapshot = { ...entry };
|
|
633
|
+
delete snapshot.element;
|
|
634
|
+
recentlyReleased.unshift({
|
|
635
|
+
id,
|
|
636
|
+
card: snapshot,
|
|
637
|
+
releasedAt: Date.now(),
|
|
638
|
+
});
|
|
639
|
+
if (recentlyReleased.length > RECENTLY_RELEASED_MAX) {
|
|
640
|
+
recentlyReleased.length = RECENTLY_RELEASED_MAX;
|
|
641
|
+
}
|
|
642
|
+
// Animate then drop
|
|
643
|
+
const el = entry.element;
|
|
644
|
+
if (el) {
|
|
645
|
+
el.classList.add("symframe-releasing");
|
|
646
|
+
const cleanup = () => {
|
|
647
|
+
cards.delete(id);
|
|
648
|
+
if (el.parentElement === container) {
|
|
649
|
+
el.remove();
|
|
650
|
+
}
|
|
651
|
+
updateCount();
|
|
652
|
+
};
|
|
653
|
+
// Fail-safe: drop after the CSS transition window even if the
|
|
654
|
+
// transitionend event doesn't fire (browser bug, reduced motion).
|
|
655
|
+
const handle = setTimeout(cleanup, 900);
|
|
656
|
+
el.addEventListener(
|
|
657
|
+
"transitionend",
|
|
658
|
+
() => {
|
|
659
|
+
clearTimeout(handle);
|
|
660
|
+
cleanup();
|
|
661
|
+
},
|
|
662
|
+
{ once: true },
|
|
663
|
+
);
|
|
664
|
+
} else {
|
|
665
|
+
cards.delete(id);
|
|
666
|
+
updateCount();
|
|
667
|
+
}
|
|
668
|
+
return true;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Re-summon a recently-released card from the session ring buffer.
|
|
673
|
+
* Calling `recall(id)` without an id recalls the most-recent release.
|
|
674
|
+
* If the id isn't in the buffer or the card already exists, no-op.
|
|
675
|
+
*/
|
|
676
|
+
function recall(id) {
|
|
677
|
+
const recordIdx = id
|
|
678
|
+
? recentlyReleased.findIndex((r) => r.id === id)
|
|
679
|
+
: recentlyReleased.length > 0
|
|
680
|
+
? 0
|
|
681
|
+
: -1;
|
|
682
|
+
if (recordIdx < 0) {
|
|
683
|
+
console.warn(`[symframe] recall: nothing to recall${id ? ` for id ${id}` : ""}`);
|
|
684
|
+
return false;
|
|
685
|
+
}
|
|
686
|
+
const [record] = recentlyReleased.splice(recordIdx, 1);
|
|
687
|
+
if (cards.has(record.id)) {
|
|
688
|
+
// Already restored elsewhere — no-op.
|
|
689
|
+
return false;
|
|
690
|
+
}
|
|
691
|
+
add(record.card);
|
|
692
|
+
return true;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/** Snapshot of recently-released cards (most-recent first). */
|
|
696
|
+
function listRecentlyReleased() {
|
|
697
|
+
return recentlyReleased.slice();
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Pin a card to localStorage so it survives reload + /new. Idempotent
|
|
702
|
+
* on id. The card is marked `pinned: true` so the dismiss button is
|
|
703
|
+
* hidden. Calling pin on an unknown id is a no-op.
|
|
704
|
+
*/
|
|
705
|
+
function pin(id) {
|
|
706
|
+
const entry = cards.get(id);
|
|
707
|
+
if (!entry) {
|
|
708
|
+
console.warn(`[symframe] pin: unknown id ${id}`);
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
if (typeof window.symframePinStore?.pin !== "function") {
|
|
712
|
+
console.warn("[symframe] pin: pin-store unavailable");
|
|
713
|
+
return false;
|
|
714
|
+
}
|
|
715
|
+
const snapshot = { ...entry };
|
|
716
|
+
delete snapshot.element;
|
|
717
|
+
snapshot.pinned = true;
|
|
718
|
+
snapshot.dismissable = false;
|
|
719
|
+
window.symframePinStore.pin(snapshot);
|
|
720
|
+
// Update live entry so the chrome reflects the pin (no dismiss btn,
|
|
721
|
+
// pin glyph in header).
|
|
722
|
+
entry.pinned = true;
|
|
723
|
+
entry.dismissable = false;
|
|
724
|
+
if (entry.element) {
|
|
725
|
+
const newEl = renderCardElement(entry);
|
|
726
|
+
entry.element.replaceWith(newEl);
|
|
727
|
+
entry.element = newEl;
|
|
728
|
+
}
|
|
729
|
+
return true;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/** Inverse of pin. Removes from localStorage; does NOT drop the card. */
|
|
733
|
+
function unpin(id) {
|
|
734
|
+
const entry = cards.get(id);
|
|
735
|
+
if (typeof window.symframePinStore?.unpin === "function") {
|
|
736
|
+
window.symframePinStore.unpin(id);
|
|
737
|
+
}
|
|
738
|
+
if (entry) {
|
|
739
|
+
entry.pinned = false;
|
|
740
|
+
entry.dismissable = true;
|
|
741
|
+
if (entry.element) {
|
|
742
|
+
const newEl = renderCardElement(entry);
|
|
743
|
+
entry.element.replaceWith(newEl);
|
|
744
|
+
entry.element = newEl;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
return true;
|
|
748
|
+
}
|
|
749
|
+
|
|
556
750
|
/** Snapshot of all registered cards. */
|
|
557
751
|
function list() {
|
|
558
752
|
return Array.from(cards.values());
|
|
559
753
|
}
|
|
560
754
|
|
|
561
|
-
// Auto-register the
|
|
562
|
-
// existing JS for each panel (subagents.js, scheduling.js
|
|
563
|
-
//
|
|
755
|
+
// Auto-register the sticky panels that already live in the DOM. The
|
|
756
|
+
// existing JS for each panel (subagents.js, scheduling.js) keeps
|
|
757
|
+
// targeting them by id and is unaffected.
|
|
758
|
+
// Stage B (3.5.20): reasoning was removed from this list — its DOM
|
|
759
|
+
// block is gone; reasoning content now flows to #symframe-substrate
|
|
760
|
+
// (see glass-ui/js/symframe-substrate.js).
|
|
564
761
|
const KNOWN_STICKY = [
|
|
565
762
|
{ id: "subagents", elementId: "subagents-panel", title: "SUBAGENTS", type: "panel-subagents" },
|
|
566
|
-
{ id: "reasoning", elementId: "reasoning-panel", title: "REASONING", type: "panel-reasoning" },
|
|
567
763
|
{
|
|
568
764
|
id: "scheduling",
|
|
569
765
|
elementId: "scheduling-panel",
|
|
@@ -584,7 +780,20 @@
|
|
|
584
780
|
}
|
|
585
781
|
}
|
|
586
782
|
|
|
587
|
-
window.symframe = {
|
|
783
|
+
window.symframe = {
|
|
784
|
+
add,
|
|
785
|
+
update,
|
|
786
|
+
remove,
|
|
787
|
+
list,
|
|
788
|
+
register,
|
|
789
|
+
// Stage C — attention verbs
|
|
790
|
+
dwell,
|
|
791
|
+
release,
|
|
792
|
+
recall,
|
|
793
|
+
pin,
|
|
794
|
+
unpin,
|
|
795
|
+
listRecentlyReleased,
|
|
796
|
+
};
|
|
588
797
|
|
|
589
798
|
// Phase 3: server-pushed cards. The gateway's `symframe` broadcast is
|
|
590
799
|
// re-emitted as a window-level CustomEvent by gateway.js — subscribe
|
|
@@ -592,6 +801,8 @@
|
|
|
592
801
|
// chat.symframe.push RPC: { action, id?, card?, force? }.
|
|
593
802
|
// Stage A: `force` flows through to update/remove so the agent (via
|
|
594
803
|
// display_artifact) and the CLI can override the sticky-card guard.
|
|
804
|
+
// Stage C: new verbs (dwell / release / recall / pin / unpin) route
|
|
805
|
+
// alongside the existing CRUD trio.
|
|
595
806
|
window.addEventListener("symi:symframe", (e) => {
|
|
596
807
|
const payload = e.detail;
|
|
597
808
|
if (!payload || typeof payload !== "object") {
|
|
@@ -604,6 +815,33 @@
|
|
|
604
815
|
update(payload.id, payload.card, force);
|
|
605
816
|
} else if (payload.action === "remove" && payload.id) {
|
|
606
817
|
remove(payload.id, force);
|
|
818
|
+
} else if (payload.action === "dwell" && payload.id) {
|
|
819
|
+
dwell(payload.id);
|
|
820
|
+
} else if (payload.action === "release" && payload.id) {
|
|
821
|
+
release(payload.id, force);
|
|
822
|
+
} else if (payload.action === "recall") {
|
|
823
|
+
recall(payload.id);
|
|
824
|
+
} else if (payload.action === "pin" && payload.id) {
|
|
825
|
+
pin(payload.id);
|
|
826
|
+
} else if (payload.action === "unpin" && payload.id) {
|
|
827
|
+
unpin(payload.id);
|
|
607
828
|
}
|
|
608
829
|
});
|
|
830
|
+
|
|
831
|
+
// Stage C: restore pinned cards from localStorage on boot. Pinned
|
|
832
|
+
// cards are user-curated state and survive reload, /new, and gateway
|
|
833
|
+
// reconnect. Each pin is a snapshot; the registry re-adds it as a
|
|
834
|
+
// dynamic card with pinned=true (no dismiss button).
|
|
835
|
+
if (typeof window.symframePinStore?.list === "function") {
|
|
836
|
+
try {
|
|
837
|
+
const pinned = window.symframePinStore.list();
|
|
838
|
+
for (const record of pinned) {
|
|
839
|
+
if (record?.card && !cards.has(record.id)) {
|
|
840
|
+
add({ ...record.card, pinned: true, dismissable: false });
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
} catch (err) {
|
|
844
|
+
console.warn("[symframe] failed to restore pinned cards:", err);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
609
847
|
})();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { f as defaultRuntime } from "./subsystem-CHbO_DkH.js";
|
|
2
|
-
import { n as resolveSymiPackageRootSync, t as resolveSymiPackageRoot } from "./symi-root-
|
|
2
|
+
import { n as resolveSymiPackageRootSync, t as resolveSymiPackageRoot } from "./symi-root-DeCVdZB4.js";
|
|
3
3
|
import { t as runCommandWithTimeout } from "./exec-DuYbft0z.js";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import path from "node:path";
|