sliccy 6.154.5 → 6.154.7
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/README.md +1 -1
- package/dist/ui/.vite/manifest.json +174 -174
- package/dist/ui/assets/{CLAUDE-CWMPcWVI.js → CLAUDE-C4hj5z8T.js} +1 -1
- package/dist/ui/assets/GELATIERE-CRe0rWjK.js +1 -0
- package/dist/ui/assets/{MEMORY-1jIGxLn4.js → MEMORY-BJp9Ffsq.js} +1 -1
- package/dist/ui/assets/{SKILL-Cc0Ep86w.js → SKILL-C3909YTo.js} +1 -1
- package/dist/ui/assets/SKILL-CLKK9YsR.js +1 -0
- package/dist/ui/assets/{account-store-QrRg1uSN.js → account-store-Bv7LV6_A.js} +1 -1
- package/dist/ui/assets/{account-store-DqTfhn2_.js → account-store-CuTDBQ6V.js} +1 -1
- package/dist/ui/assets/{adobe-Bea7fu-T.js → adobe-Bld04yf4.js} +1 -1
- package/dist/ui/assets/{adobe-B6cbOIZR.js → adobe-yrm9KfZU.js} +1 -1
- package/dist/ui/assets/{agent-bridge-CLbiuQFp.js → agent-bridge-BOK0bK1-.js} +1 -1
- package/dist/ui/assets/{agent-panels-CrHaxcfP.js → agent-panels-JSKGPWny.js} +1 -1
- package/dist/ui/assets/{apply-layout-CUdgM9hY.js → apply-layout-Dol4QpYX.js} +1 -1
- package/dist/ui/assets/{approver-agent-BA3dC9Lg.js → approver-agent-CCkU0PVa.js} +1 -1
- package/dist/ui/assets/{apps-CmhTAbmY.js → apps-DdAoo50J.js} +1 -1
- package/dist/ui/assets/{azure-openai-DQvD4JfK.js → azure-openai-CROWb3eo.js} +1 -1
- package/dist/ui/assets/{azure-openai-oNkAJEH9.js → azure-openai-D16OgVVX.js} +1 -1
- package/dist/ui/assets/{budget-usage-source-DMq3fdAk.js → budget-usage-source-CiFTPdLG.js} +1 -1
- package/dist/ui/assets/{cdp-CyYrl-r3.js → cdp-ChTjN36Y.js} +1 -1
- package/dist/ui/assets/{cerebras-i6LmJBOw.js → cerebras-BGd53Y6O.js} +1 -1
- package/dist/ui/assets/{cerebras-CLMg0uuV.js → cerebras-DEjugWgo.js} +1 -1
- package/dist/ui/assets/{composer-speech-9Zo81K0N.js → composer-speech-BvDGMHRN.js} +1 -1
- package/dist/ui/assets/{connect-surface-BfXSOspJ.js → connect-surface-BxeM6wzG.js} +1 -1
- package/dist/ui/assets/{directed-approval-Df9ytmfk.js → directed-approval-DAIXE0nO.js} +1 -1
- package/dist/ui/assets/{fs-CtNDvIlo.js → fs-BEbWmRDq.js} +2 -2
- package/dist/ui/assets/{fs-BiGByget.js → fs-CjgMvwqK.js} +1 -1
- package/dist/ui/assets/gelatiere-store-DA2wk9nw.js +1 -0
- package/dist/ui/assets/{gelatiere-unit-Dem3bPJm.js → gelatiere-unit-DnbLwJqw.js} +1 -1
- package/dist/ui/assets/{github-BNNfDsCz.js → github-Bc1z9Z3b.js} +1 -1
- package/dist/ui/assets/{github-D753Gf5v.js → github-D6e0X_mv.js} +2 -2
- package/dist/ui/assets/{github-auth-Dah4Bvbq.js → github-auth-BPlvszS_.js} +1 -1
- package/dist/ui/assets/{github-copilot-BFeyn-UC.js → github-copilot-BQU9xIRH.js} +1 -1
- package/dist/ui/assets/{github-copilot-B1Ax8Lk3.js → github-copilot-CtFddSBT.js} +1 -1
- package/dist/ui/assets/{github-install-NhZ0wUHD.js → github-install-BUmd5jOm.js} +1 -1
- package/dist/ui/assets/{github-zip-Dl9WuPaB.js → github-zip-BbIUjzA4.js} +1 -1
- package/dist/ui/assets/{hear-Ctqu4qhx.js → hear-CYy8tVN1.js} +1 -1
- package/dist/ui/assets/{help-Bw8UwEZ2.js → help-C1vcRsvu.js} +1 -1
- package/dist/ui/assets/icons-Ce7Vz89o.js +1 -0
- package/dist/ui/assets/{js-realm-worker-w_3ye_7l.js → js-realm-worker-JtICkZ9q.js} +1 -1
- package/dist/ui/assets/{kernel-worker-Bort6gFm.js → kernel-worker-JOBY7Wxs.js} +587 -584
- package/dist/ui/assets/{local-llm-BB5kQEa2.js → local-llm-CJWLILc_.js} +1 -1
- package/dist/ui/assets/{local-llm-InWZD5_6.js → local-llm-_OhXJtNu.js} +1 -1
- package/dist/ui/assets/{main-CpFTnqJu.js → main-CpKPiVl7.js} +3 -3
- package/dist/ui/assets/{main-cherry-C00FP5cd.js → main-cherry-D8WCpwBV.js} +1 -1
- package/dist/ui/assets/{memory-curation-seam-UdyrM1Mx.js → memory-curation-seam-BxXS_BMa.js} +1 -1
- package/dist/ui/assets/migrate-scoop-sudoers-PBnz9AA3.js +1 -0
- package/dist/ui/assets/{mount-CNl3JQQP.js → mount-B-qjx7RD.js} +1 -1
- package/dist/ui/assets/{mount-omsLg2iT.js → mount-CIGA8r4q.js} +3 -3
- package/dist/ui/assets/{mount-recovery-B9S80wQd.js → mount-recovery-DNUbi0Ni.js} +1 -1
- package/dist/ui/assets/{new-session-DzHUS_-O.js → new-session-Bat4OTXx.js} +2 -2
- package/dist/ui/assets/{oauth-bootstrap-EjnDaNLY.js → oauth-bootstrap-D2j6OHaC.js} +2 -2
- package/dist/ui/assets/{onboarding-orchestrator-CasEZ5Ti.js → onboarding-orchestrator-Za4dEXZ8.js} +1 -1
- package/dist/ui/assets/{openai-codex-MngNy3OL.js → openai-codex-CcJ89ggy.js} +1 -1
- package/dist/ui/assets/{openai-codex-c9FzyJSx.js → openai-codex-f1f3Poo1.js} +1 -1
- package/dist/ui/assets/{openrouter-CTU-VUZU.js → openrouter-B52C9XuH.js} +1 -1
- package/dist/ui/assets/{openrouter-58brdWIl.js → openrouter-DN9cM8UA.js} +1 -1
- package/dist/ui/assets/{openrouter-free-B1pQjdc9.js → openrouter-free--eNgGfax.js} +1 -1
- package/dist/ui/assets/{openrouter-free-Cw45OIqu.js → openrouter-free-CiLvReDo.js} +1 -1
- package/dist/ui/assets/{openrouter-oauth-S-co-_BE.js → openrouter-oauth-DOQfi9TX.js} +1 -1
- package/dist/ui/assets/{openrouter-oauth-BVyZ9RG4.js → openrouter-oauth-Iv8iz92e.js} +1 -1
- package/dist/ui/assets/{panel-rpc-handlers-D_G7IsL-.js → panel-rpc-handlers-DtxsALXP.js} +2 -2
- package/dist/ui/assets/{panelize-shell-dRR-gQQ4.js → panelize-shell-Dk8A0fzt.js} +1 -1
- package/dist/ui/assets/{pi-edit-execution-DzlJRvzD.js → pi-edit-execution-BVNON_7G.js} +1 -1
- package/dist/ui/assets/{provider-D-5WiTrV.js → provider-BEV4Nyb0.js} +2 -2
- package/dist/ui/assets/{provider-CeNevkik.js → provider-jRSVQQyi.js} +1 -1
- package/dist/ui/assets/provider-settings-Dc0Uksht.js +1 -0
- package/dist/ui/assets/provider-store-access-BYCBOZrX.js +1 -0
- package/dist/ui/assets/provider-store-access-CcCQNG5q.js +1 -0
- package/dist/ui/assets/{providers-JVYHxTrW.js → providers-CkE3X7zj.js} +2 -2
- package/dist/ui/assets/{providers-CZoy8wMj.js → providers-DsDlOFZz.js} +1 -1
- package/dist/ui/assets/{quick-llm-BrhzKZyf.js → quick-llm-hedJ8LEL.js} +1 -1
- package/dist/ui/assets/{recovery-screen-Dm_Ys4T5.js → recovery-screen-DU8WFnpT.js} +1 -1
- package/dist/ui/assets/{run-D-ptdMRR.js → run-C-InHvWx.js} +2 -2
- package/dist/ui/assets/run-CuXkU2qx.js +3 -0
- package/dist/ui/assets/{run-CfuM1xwa.js → run-DTXbRzQ6.js} +1 -1
- package/dist/ui/assets/run-FqXwpBiQ.js +54 -0
- package/dist/ui/assets/{run-Da4WIBP4.js → run-dk5KyxT2.js} +1 -1
- package/dist/ui/assets/{session-jsonl-Be97cQdP.js → session-jsonl-CpQqgq2a.js} +1 -1
- package/dist/ui/assets/{setup-feature-flags-remote-D47pV_MM.js → setup-feature-flags-remote-DJTSDAP-.js} +1 -1
- package/dist/ui/assets/sidecar-repair-CPDaW6WS.js +1 -0
- package/dist/ui/assets/{silent-renew-backoff-Cynzp3bE.js → silent-renew-backoff-pEjTpf6Y.js} +1 -1
- package/dist/ui/assets/skills-D1r_dXXN.js +5 -0
- package/dist/ui/assets/slicc-version-Do_Qzxe9.js +1 -0
- package/dist/ui/assets/{snapshot-features-DVyd7MCD.js → snapshot-features-Bn7BtW7K.js} +1 -1
- package/dist/ui/assets/{snapshot-DZQ1apX-.js → snapshot-jBfySyLF.js} +1 -1
- package/dist/ui/assets/{soundscape-BMwJ3NUw.js → soundscape-gtJZ30qF.js} +1 -1
- package/dist/ui/assets/{speak-1sadgIHv.js → speak-D6N7JGfl.js} +1 -1
- package/dist/ui/assets/{sprinkle-manager-D6Qrwdww.js → sprinkle-manager-Bgirnz_O.js} +1 -1
- package/dist/ui/assets/{sprinkle-renderer-Pg2SqEAJ.js → sprinkle-renderer-CpbS9Pze.js} +1 -1
- package/dist/ui/assets/{state-DA5Ppyx-.js → state-gI8eLPCJ.js} +1 -1
- package/dist/ui/assets/{store-JtuNg-ld.js → store-CJoMqbUo.js} +1 -1
- package/dist/ui/assets/{store-BIDY4hVD.js → store-CoFkhkC_.js} +1 -1
- package/dist/ui/assets/{sudo-BAvTUS5b.js → sudo-CdUi7Bt1.js} +1 -1
- package/dist/ui/assets/sudoers-BdBYQPUn.js +3 -0
- package/dist/ui/assets/{suggestions-CFQTt8oo.js → suggestions-B34zKgsF.js} +151 -33
- package/dist/ui/assets/{sync-dialog-B22MjR-Y.js → sync-dialog-uCJmhtr8.js} +1 -1
- package/dist/ui/assets/{transformers-env-Dbzm2zOd.js → transformers-env-GrfzOgRv.js} +1 -1
- package/dist/ui/assets/{tray-sidecar-DfQxtpAU.js → tray-sidecar-B_1w3n4t.js} +1 -1
- package/dist/ui/assets/{upgrade-detection-B0CnEfsD.js → upgrade-detection-L60JNTNb.js} +1 -1
- package/dist/ui/assets/{upskill-lick-skip-Dkrc8SQj.js → upskill-lick-skip-Jcllnh6l.js} +1 -1
- package/dist/ui/assets/{voice-reply-hxJpzo4Z.js → voice-reply-DqNiHN6M.js} +1 -1
- package/dist/ui/assets/{wc-attach-B-RwMKh4.js → wc-attach-8_xsR0qy.js} +2 -2
- package/dist/ui/assets/{wc-extension-BzgY7Ay5.js → wc-extension-oYf2HrE6.js} +2 -2
- package/dist/ui/assets/{wc-follower-RmDJj3vx.js → wc-follower-BYsj_5x0.js} +3 -3
- package/dist/ui/assets/{wc-follower-oauth-CzL_YM3W.js → wc-follower-oauth-CljtR185.js} +1 -1
- package/dist/ui/assets/{wc-gelatiere-DMO16qkW.js → wc-gelatiere-CP4serB8.js} +1 -1
- package/dist/ui/assets/{wc-live-C1fkW0oh.js → wc-live-CkxSC9Ez.js} +6 -6
- package/dist/ui/assets/{wc-nav-EBobpmc0.js → wc-nav-XvRTYo98.js} +2 -2
- package/dist/ui/assets/{wc-onboarding-sry3pJ3v.js → wc-onboarding-iCoaOIma.js} +2 -2
- package/dist/ui/assets/{wc-placeholder-yiwnKVQh.js → wc-placeholder-em6OiHpb.js} +3 -3
- package/dist/ui/assets/{wc-secret-request-DR5a7SVR.js → wc-secret-request-BjM8NPKG.js} +1 -1
- package/dist/ui/assets/{wc-settings-BB5MYHf5.js → wc-settings-BtBwNeN8.js} +3 -3
- package/dist/ui/assets/{wc-shell-DMzpB1X4.js → wc-shell-DC9WMYcH.js} +3 -3
- package/dist/ui/assets/{wc-shortcut-config-CutoJlLo.js → wc-shortcut-config-BEsAGNLx.js} +1 -1
- package/dist/ui/assets/{wc-shortcuts-Db5RFxfY.js → wc-shortcuts-CETptwt9.js} +172 -172
- package/dist/ui/assets/{wc-sprinkles-CyZsTtq7.js → wc-sprinkles-DLNH0Ist.js} +2 -2
- package/dist/ui/assets/{wc-transcript-export-Bkn8aEFu.js → wc-transcript-export-CidB32Dc.js} +2 -2
- package/dist/ui/assets/{wc-tray-6uck1DGP.js → wc-tray-BbFFd7U-.js} +4 -4
- package/dist/ui/assets/welcome-detection-DW2ROqam.js +1 -0
- package/dist/ui/assets/{whisper-session-BNYJek9P.js → whisper-session-BvALr1gE.js} +2 -2
- package/dist/ui/assets/{xai-grok-DcM2TX44.js → xai-grok-DWDEwZSo.js} +1 -1
- package/dist/ui/assets/{xai-grok-CaMqKb8o.js → xai-grok-Ht4qQwUs.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/ui/lucide-icons.js +182 -179
- package/dist/ui/packages/webapp/index.html +3 -3
- package/package.json +1 -1
- package/dist/ui/assets/GELATIERE-CDj3aVTD.js +0 -1
- package/dist/ui/assets/SKILL-DvHAkJSI.js +0 -117
- package/dist/ui/assets/gelatiere-store-CcLPnD5F.js +0 -1
- package/dist/ui/assets/icons-D5_bMrnB.js +0 -1
- package/dist/ui/assets/provider-settings-CseKsTkN.js +0 -1
- package/dist/ui/assets/provider-store-access-B8K7spUZ.js +0 -1
- package/dist/ui/assets/provider-store-access-Cr4NjO-D.js +0 -1
- package/dist/ui/assets/run-CHF9lHjk.js +0 -46
- package/dist/ui/assets/sidecar-repair-9M_U9-Iy.js +0 -1
- package/dist/ui/assets/skills-DoZg-ojy.js +0 -5
- package/dist/ui/assets/slicc-version-7PkoDMIu.js +0 -1
- package/dist/ui/assets/sudoers-KgJRnN4b.js +0 -3
- package/dist/ui/assets/welcome-detection-DsUV5zMq.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as e}from"./snapshot-
|
|
1
|
+
import{a as e}from"./snapshot-jBfySyLF.js";import{g as t,v as n}from"./state-gI8eLPCJ.js";function r(e,t){let n=0,r=e.split(`
|
|
2
2
|
`).filter(e=>{let r=/^( *)- /.exec(e);return!r||r[1].length/2<t||(n++,!1)});return n>0&&r.push(`(${n} node(s) below depth ${t} elided — re-run without --depth for the full tree)`),r.join(`
|
|
3
3
|
`)}async function i(e,t,n){await e.send(`DOM.enable`),await e.send(`Runtime.enable`);let r={};for(let[n,i]of t)if(!n.startsWith(`f`))try{let t=(await e.send(`DOM.resolveNode`,{backendNodeId:i})).object?.objectId;if(!t)continue;let a=(await e.send(`Runtime.callFunctionOn`,{objectId:t,functionDeclaration:`function() {
|
|
4
4
|
const r = this.getBoundingClientRect();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e}from"./panel-rpc-BPwAqRch.js";import{m as t}from"./state-
|
|
1
|
+
import{n as e}from"./panel-rpc-BPwAqRch.js";import{m as t}from"./state-gI8eLPCJ.js";function n(e,t=``){if(e==null)return t;if(typeof e==`string`)return e;if(typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`)return String(e);try{return JSON.stringify(e)??t}catch{return String(e)}}function r(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/\n/g,`\\n`)}function i(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}const a=[`none`,`presentation`,`generic`,`rootwebarea`],o=[`textbox`,`button`,`link`,`checkbox`,`radio`];function s(e,t){return a.includes(e)?!1:!!t||o.includes(e)}function c(e,t){let n=i(t);return e===`button`&&t?[`button[aria-label="${n}"]`,`button[title="${n}"]`,`[role="button"][aria-label="${n}"]`,`[role="button"][title="${n}"]`,`input[type="button"][value="${n}"]`,`input[type="submit"][value="${n}"]`,`input[type="reset"][value="${n}"]`].join(`, `):e===`link`&&t?`a[aria-label="${n}"], a[title="${n}"], [role="link"][aria-label="${n}"], [role="link"][title="${n}"]`:e===`textbox`?t?`input[aria-label="${n}"], textarea[aria-label="${n}"], [contenteditable][aria-label="${n}"], input[placeholder="${n}"], textarea[placeholder="${n}"], [contenteditable][placeholder="${n}"], input[title="${n}"], textarea[title="${n}"], [contenteditable][title="${n}"]`:`input, textarea, [contenteditable]`:e===`checkbox`?`input[type="checkbox"]`:e===`radio`?`input[type="radio"]`:t?`[aria-label="${n}"], [title="${n}"]`:`[role="${e}"]`}function l(e,t,i,a,o=``,u=``){let d=[],f=n(e.role,`unknown`).toLowerCase(),p=n(e.name),m=n(e.value),h=``;s(f,p)&&(h=u+`e${++a.value}`,e.backendNodeId&&i.set(h,e.backendNodeId),t.set(h,c(f,p)));let g=`${o}- ${f}`;if(p&&(g+=` "${r(p)}"`),h&&(g+=` [ref=${h}]`),m&&(g+=`: "${r(m)}"`),d.push(g),e.children)for(let n of e.children)d.push(...l(n,t,i,a,o+` `,u));return d}async function u(e,t){if(t.appTabId)return;let n=await e.listPages(),r=await d(),i=n.find(e=>e.url.startsWith(r)&&!e.url.includes(`/preview/`));i&&(t.appTabId=i.targetId)}async function d(){if(typeof window<`u`)return window.location.origin;let t=e();if(t)try{let e=await t.call(`page-info`,void 0,{timeoutMs:2e3});if(e.origin)return e.origin}catch{}return`http://localhost:5710`}function f(e,t){return t===e.appTabId}function p(e){let t=e.url.trim(),n=e.title.trim();return n===`Omnibox Popup`||t.startsWith(`chrome://`)||t.startsWith(`chrome-search://`)||t.startsWith(`chrome-untrusted://`)||t.startsWith(`devtools://`)||t.length===0&&/popup$/i.test(n)}function m(e,t){return!f(e,t.targetId)&&!p(t)}async function h(e,n){return await u(e,n),(await t(e)).filter(e=>m(n,e))}function g(e,t){try{let n=new URL(e,t);return n.origin+n.pathname.replace(/\/$/,``)+n.search}catch{return null}}function _(e,t,n,r){let i=g(t,n);return e.find(e=>{if(r.has(e.frameId))return!1;let n=g(e.url);return n!==null&&i!==null?n===i:e.url===t})}async function v(e,t,n,r,i,a,o){try{let s=await e.getAccessibilityTreeForFrame(t),c=new Map,u=new Map,d=l(s,c,u,{value:0},n,r);for(let[e,n]of c)i.set(e,n),o.set(e,t);for(let[e,n]of u)a.set(e,n),o.set(e,t);return d}catch{return[]}}async function y(e,t,n,r,i,a){if(typeof e.getFrameTree!=`function`)return t;try{let o=(await e.getFrameTree()).filter(e=>e.parentFrameId);if(o.length===0)return t;let s=0,c=[],l=new Set;for(let u of t.split(`
|
|
2
2
|
`)){c.push(u);let t=u.match(/^(\s*)- iframe(?=\s|:)/);if(!t)continue;let d=u.match(/:\s*"([^"]+)"\s*$/);if(!d)continue;let f=_(o,d[1],n,l);f&&(l.add(f.frameId),s++,c.push(...await v(e,f.frameId,t[1]+` `,`f${s}`,r,i,a)))}return c.join(`
|
|
3
3
|
`)}catch{return t}}async function b(e,t){let n=await e.evaluate(`JSON.stringify({ url: location.href, title: document.title })`),{url:r,title:i}=JSON.parse(n),a=await e.getAccessibilityTree(),o=new Map,s=new Map,c=new Map,u=l(a,o,s,{value:0}).join(`
|
|
4
4
|
`);return t?.noIframes||(u=await y(e,u,r,o,s,c)),{url:r,title:i,text:u,refToSelector:o,refToBackendNodeId:s,refToFrameId:c}}async function x(e,t,n,r){let{url:i,title:a,text:o,refToSelector:s,refToBackendNodeId:c,refToFrameId:l}=await b(e,r),u={url:i,title:a,refToSelector:s,refToBackendNodeId:c,refToFrameId:l,content:o,timestamp:Date.now()};return t.snapshots.set(n,u),{snapshot:u,output:[`Page URL: ${i}`,`Page Title: ${a}`,``,o].join(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./logger-DDBAeTLF.js";import{B as t}from"./wc-shortcuts-
|
|
1
|
+
import{t as e}from"./logger-DDBAeTLF.js";import{B as t}from"./wc-shortcuts-CETptwt9.js";var n=e(`speech:soundscape`),r=`soundscape-enabled`;function i(){try{return localStorage.getItem(r)!==`false`}catch{return!0}}var a=0,o=!1;function s(){a++}function c(){a>0&&a--}function l(){return a>0}function u(e){o=e}function d(){return o}var f=null;function p(){return typeof AudioContext>`u`?null:((!f||f.state===`closed`)&&(f=new AudioContext),f)}function m(e){if(!i()||!l()||d())return;let r=p();if(r)try{r.state===`suspended`&&r.resume(),t(r,e)}catch(e){n.debug(`soundscape cue failed`,e)}}export{s as beginVoiceTurn,c as endVoiceTurn,m as playCue,u as setTtsActive};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/transformers.web-B0gi9Hor.js","assets/rolldown-runtime-Dd_uD5pT.js","assets/preload-helper-Czpn1I53.js","assets/kokoro-BkJ3NLgd.js","assets/__vite-browser-external-5eBdwsFd.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{t as e}from"./preload-helper-Czpn1I53.js";import{t}from"./logger-DDBAeTLF.js";import{n}from"./runtime-env-Dlaokqg1.js";import{t as r}from"./speech-assets-bridge-CFYafE89.js";import{i,n as a,o,r as s,t as c}from"./transformers-env-
|
|
2
|
+
import{t as e}from"./preload-helper-Czpn1I53.js";import{t}from"./logger-DDBAeTLF.js";import{n}from"./runtime-env-Dlaokqg1.js";import{t as r}from"./speech-assets-bridge-CFYafE89.js";import{i,n as a,o,r as s,t as c}from"./transformers-env-GrfzOgRv.js";var l=t(`speech:espeak`),u=`/workspace/node_modules/espeak-ng/dist/`,d=`espeak-ng.js`,f=`espeak-ng.wasm`;async function p(e,t,n,r){let i=`phonemes.txt`;return(await e({arguments:[`-q`,`-b=1`,`--ipa`,`-v`,n,`--phonout`,i,t],...r?{locateFile:r}:{}})).FS.readFile(i,{encoding:`utf8`}).split(`
|
|
3
3
|
`).map(e=>e.trim()).filter(e=>e.length>0)}function ee(e,t){return async n=>{let r=URL.createObjectURL(new Blob([new Uint8Array(t)],{type:`application/wasm`}));try{let t=e=>e.endsWith(`.wasm`)?r:n.locateFile?.(e)??e;return await e({...n,locateFile:t})}finally{URL.revokeObjectURL(r)}}}function m(e){if(typeof BroadcastChannel>`u`)return Promise.reject(Error(`Cannot read VFS path ${e}: BroadcastChannel unavailable`));let t=new BroadcastChannel(`preview-vfs`),n=`espeak-${Date.now()}-${Math.random().toString(36).slice(2)}`;return new Promise((r,i)=>{let a=e=>{t.removeEventListener(`message`,c),t.close(),e()},o,s=()=>{clearTimeout(o),o=setTimeout(()=>a(()=>i(Error(`ENOENT: ${e} (timed out)`))),3e4)};s();let c=t=>{let c=t.data;if(!(!c||c.id!==n)){if(c.type===`preview-vfs-start`){s();return}if(c.type===`preview-vfs-response`){if(clearTimeout(o),typeof c.error==`string`)a(()=>i(Error(c.error)));else if(c.content instanceof Uint8Array){let e=c.content;a(()=>r(e))}else if(typeof c.content==`string`){let e=c.content;a(()=>r(new TextEncoder().encode(e)))}else a(()=>i(Error(`Empty preview-vfs response for ${e}`)))}}};t.addEventListener(`message`,c),t.postMessage({type:`preview-vfs-read`,id:n,path:e,asText:!1})})}async function te(){let[t,n]=await Promise.all([m(`${u}${d}`),m(`${u}${f}`)]),r=URL.createObjectURL(new Blob([new Uint8Array(t)],{type:`text/javascript`}));try{return{factory:ee((await e(()=>import(r),[])).default,n)}}finally{URL.revokeObjectURL(r)}}var ne=te,h=null;function g(){return h||=ne().then(({factory:e,locateFile:t})=>(l.info(`espeak-ng multilingual phonemizer loaded`),(n,r)=>p(e,n,r,t)),e=>{throw h=null,l.error(`espeak-ng load failed`,e),e}),h}var re=Object.freeze({e:`es`,f:`fr-fr`,i:`it`,h:`hi`,p:`pt-br`});function _(e){return re[e[0]]??null}var ie=Object.freeze({a:`en-us`,b:`en-gb`});function ae(e){return ie[e[0]]??null}function oe(e){let t=e instanceof Error?e.message:String(e);return/Invalid language identifier/i.test(t)&&/Should be one of:\s*\.?\s*$/i.test(t)}var se=RegExp(`(\\s*[${`;:,.!?¡¿—…"«»“”(){}[]`.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}]+\\s*)+`,`g`);function ce(e){let t=[],n=0;for(let r of e.matchAll(se)){let i=r[0],a=r.index??0;n<a&&t.push({punct:!1,text:e.slice(n,a)}),i.length>0&&t.push({punct:!0,text:i}),n=a+i.length}return n<e.length&&t.push({punct:!1,text:e.slice(n)}),t}function le(e){return e.replace(/kəkˈoːɹoʊ/g,`kˈoʊkəɹoʊ`).replace(/kəkˈɔːɹəʊ/g,`kˈəʊkəɹəʊ`).replace(/(?<=[a-zɹrː])(?=hˈʌndɹɪd)/g,` `).replace(/ z(?=[;:,.!?¡¿—…"«»“” ]|$)/g,`z`).trim()}async function ue(e,t,n){let r=ce(e);return le((await Promise.all(r.map(async e=>e.punct?e.text:(await n(e.text,t)).join(` `)))).join(``))}var v=t(`speech:kokoro`),y={a:`en-US`,b:`en-GB`,e:`es-ES`,f:`fr-FR`,i:`it-IT`,h:`hi-IN`,p:`pt-BR`,j:`ja-JP`,z:`zh-CN`},b=new Set([`en-US`,`en-GB`,`es-ES`,`fr-FR`,`it-IT`,`hi-IN`,`pt-BR`]);function x(e){let[t,n]=e.split(`-`);return n?`${t.toLowerCase()}-${n.toUpperCase()}`:t.toLowerCase()}function S(e,t){if(!t)return!1;if(b.has(t))return!0;if(t.includes(`-`))return!1;let n=y[e[0]];return n!==void 0&&b.has(n)&&n.split(`-`)[0].toLowerCase()===t}function de(e){return Object.entries(e).map(([e,t])=>{let n=t.language?x(t.language):y[e[0]];return{id:e,name:t.name||e,lang:n??`en-US`,onDevice:S(e,n),...t.gender?{gender:t.gender}:{}}})}var fe=Object.freeze({ef_dora:{name:`Dora`,gender:`Female`},em_alex:{name:`Alex`,gender:`Male`},em_santa:{name:`Santa`,gender:`Male`},ff_siwis:{name:`Siwis`,gender:`Female`},hf_alpha:{name:`Alpha`,gender:`Female`},hf_beta:{name:`Beta`,gender:`Female`},hm_omega:{name:`Omega`,gender:`Male`},hm_psi:{name:`Psi`,gender:`Male`},if_sara:{name:`Sara`,gender:`Female`},im_nicola:{name:`Nicola`,gender:`Male`},pf_dora:{name:`Dora`,gender:`Female`},pm_alex:{name:`Alex`,gender:`Male`},pm_santa:{name:`Santa`,gender:`Male`},jf_alpha:{name:`Alpha`,gender:`Female`},jf_gongitsune:{name:`Gongitsune`,gender:`Female`},jf_nezumi:{name:`Nezumi`,gender:`Female`},jf_tebukuro:{name:`Tebukuro`,gender:`Female`},jm_kumo:{name:`Kumo`,gender:`Male`},zf_xiaobei:{name:`Xiaobei`,gender:`Female`},zf_xiaoni:{name:`Xiaoni`,gender:`Female`},zf_xiaoxiao:{name:`Xiaoxiao`,gender:`Female`},zf_xiaoyi:{name:`Xiaoyi`,gender:`Female`},zm_yunjian:{name:`Yunjian`,gender:`Male`},zm_yunxi:{name:`Yunxi`,gender:`Male`},zm_yunxia:{name:`Yunxia`,gender:`Male`},zm_yunyang:{name:`Yunyang`,gender:`Male`}});function C(e){let t={...e};for(let[e,n]of Object.entries(fe))e in t||(t[e]=n);return de(t)}var w=`style_text_to_speech_2`,T=`StyleTextToSpeech2Model`;function pe(e){return e?.model_type===w&&(!Array.isArray(e.architectures)||e.architectures.length===0)&&(e.architectures=[T]),e}var E=Symbol.for(`slicc.kokoro.style-tts2-arch-shim`);function me(e){let t=e?.AutoConfig,n=t?.from_pretrained;if(!t||typeof n!=`function`){v.debug(`style_text_to_speech_2 shim skipped: AutoConfig.from_pretrained unavailable`);return}if(n[E])return;let r=async(...e)=>{let r=await n.apply(t,e),i=r?.model_type===w&&(!Array.isArray(r.architectures)||r.architectures.length===0);return pe(r),i&&v.debug(`style_text_to_speech_2 architectures injected for "${String(e[0])}": [${T}]`),r};r[E]=!0,t.from_pretrained=r,v.debug(`style_text_to_speech_2 architecture shim installed on AutoConfig.from_pretrained`)}async function D(e,t,n,r,i,a){let o=await ue(t,n,a),s=e.tokenizer,{input_ids:c}=s(o,{truncation:!0}),l=await e.generate_from_ids(c,{voice:r,...i?{speed:i}:{}});return{audio:l.audio,sampleRate:l.sampling_rate}}var he=/(?<=[.!?。!?…])\s+|\n{2,}/u;function O(e,t){let n=t??he,r=e.split(n).map(e=>e.trim()).filter(e=>e.length>0),i=e.trim();return r.length>0?r:i?[i]:[]}var k=null,A=`idle`,j=null,M=null;function N(){return A}function P(){return j}function F(){return M}function I(e){return k||=(A=`loading`,L(e).then(e=>(A=`ready`,M=e,e),e=>{throw A=`failed`,k=null,v.error(`kokoro load failed`,e),e})),k}async function L(t){let n=await e(()=>import(`./transformers.web-B0gi9Hor.js`),__vite__mapDeps([0,1,2]));a(n.env),me(n),await c(i),await s();let{KokoroTTS:r,TextSplitterStream:l}=await e(async()=>{let{KokoroTTS:e,TextSplitterStream:t}=await import(`./kokoro-BkJ3NLgd.js`);return{KokoroTTS:e,TextSplitterStream:t}},__vite__mapDeps([3,1,4,0,2])),u=o(),d=typeof navigator<`u`&&`gpu`in navigator,f=await r.from_pretrained(i,{device:d?`webgpu`:`wasm`,dtype:d?`fp32`:`q8`,progress_callback:e=>{if(e?.file){if(e.status===`progress`)u.update(e.file,e.loaded??0,e.total??0);else if(e.status===`done`)u.complete(e.file);else return;j=u.snapshot(),t?.(j)}}});v.info(`kokoro ready`,{model:i,device:d?`webgpu`:`wasm`});let p=C(f.voices);return{async synthesize(e,t){let r=t?.voice??`af_heart`,i=_(r);if(i){let n=await g();return D(f,e,i,r,t?.speed,n)}try{let r=performance.now(),i=await f.generate(e,{...t?.voice?{voice:t.voice}:{},...t?.speed?{speed:t.speed}:{}}),a=i.audio;return v.info(`kokoro synthesize`,{elapsedMs:Math.round(performance.now()-r),chars:e.length,audioSeconds:Math.round(a.length/i.sampling_rate*100)/100,numThreads:n.env.backends?.onnx?.wasm?.numThreads}),{audio:a,sampleRate:i.sampling_rate}}catch(n){let i=await R(n,r);if(!i)throw n;return D(f,e,i.lang,r,t?.speed,i.phonemize)}},async*synthesizeStream(e,t){let r=t?.voice??`af_heart`,i=_(r);if(i){let n=await g();for(let a of O(e,t?.splitPattern))yield await D(f,a,i,r,t?.speed,n);return}let a={...t?.voice?{voice:t.voice}:{},...t?.speed?{speed:t.speed}:{}},o=new l;if(t?.splitPattern){let n=e.split(t.splitPattern).map(e=>e.trim()).filter(e=>e.length>0);o.push(...n)}else o.push(e);o.close();try{let t=performance.now(),r=0,i=0,s=0;for await(let e of f.stream(o,a)){let t=e.audio.audio;r+=1,i+=t.length,s=e.audio.sampling_rate,yield{audio:t,sampleRate:s}}v.info(`kokoro synthesizeStream`,{elapsedMs:Math.round(performance.now()-t),chunks:r,chars:e.length,audioSeconds:s?Math.round(i/s*100)/100:0,numThreads:n.env.backends?.onnx?.wasm?.numThreads})}catch(n){let i=await R(n,r);if(!i)throw n;for(let n of O(e,t?.splitPattern))yield await D(f,n,i.lang,r,t?.speed,i.phonemize)}},voices:()=>p}}async function R(e,t){if(!oe(e))return null;let n=ae(t);if(!n)return null;try{let e=await g();return v.warn(`kokoro bundled phonemizer reported no languages; phonemizing English with the staged espeak-ng`,{voiceId:t,lang:n}),{lang:n,phonemize:e}}catch(e){return v.warn(`staged espeak-ng unavailable, cannot recover English synthesis`,{error:String(e)}),null}}var z=44,B=16,V=1,H=B/8;function U(e,t,n){for(let r=0;r<n.length;r++)e.setUint8(t+r,n.charCodeAt(r))}function ge(e){let t=Math.max(-1,Math.min(1,e));return Math.round(t<0?t*32768:t*32767)}function _e(e){if(e.length===0)throw Error(`wav-encode: at least one PCM chunk is required`);let t=e[0].sampleRate;if(!Number.isFinite(t)||t<=0)throw Error(`wav-encode: invalid sample rate ${t}`);let n=0;for(let r of e){if(r.sampleRate!==t)throw Error(`wav-encode: mixed sample rates (${r.sampleRate} vs ${t}) — resample upstream`);n+=r.audio.length}let r=n*V*H,i=new ArrayBuffer(z+r),a=new DataView(i);U(a,0,`RIFF`),a.setUint32(4,36+r,!0),U(a,8,`WAVE`),U(a,12,`fmt `),a.setUint32(16,16,!0),a.setUint16(20,1,!0),a.setUint16(22,V,!0),a.setUint32(24,t,!0),a.setUint32(28,t*V*H,!0),a.setUint16(32,2,!0),a.setUint16(34,B,!0),U(a,36,`data`),a.setUint32(40,r,!0);let o=z;for(let t of e)for(let e=0;e<t.audio.length;e++)a.setInt16(o,ge(t.audio[e]),!0),o+=H;return new Uint8Array(i)}var W=t(`speech:speak`),G=2e4;function K(e){return e.toLowerCase().startsWith(`en`)}function ve(e,t){if(!t.ready)return`webspeech`;let n=e=>e.onDevice&&(K(e.lang)||t.nonEnglishOnDevice);if(e.voice){let r=t.voices.find(t=>t.id===e.voice);return r&&n(r)?`kokoro`:`webspeech`}let r=(e.lang?e.lang.split(`-`)[0]:`en`).toLowerCase();return t.voices.some(e=>e.lang.split(`-`)[0].toLowerCase()===r&&n(e))?`kokoro`:`webspeech`}function ye(e,t){if(!e||K(e))return;let n=e.split(`-`)[0].toLowerCase();return t.find(e=>e.onDevice&&e.lang.split(`-`)[0].toLowerCase()===n)?.id}var be=48;function xe(e){let t=e;return t=t.replace(/```[\s\S]*?```/g,` `),t=t.replace(/~~~[\s\S]*?~~~/g,` `),t=t.replace(/(?:```|~~~)[\s\S]*$/,` `),t=t.replace(/!\[([^\]]*)\]\([^)]*\)/g,`$1`),t=t.replace(/\[([^\]]+)\]\([^)]*\)/g,`$1`),t=t.replace(/`([^`]*)`/g,(e,t)=>t.length>be?` `:t),t=t.replace(/<[^>\n]+>/g,` `),t=t.replace(/^[ \t]{0,3}#{1,6}[ \t]+/gm,``),t=t.replace(/^[ \t]*>[ \t]?/gm,``),t=t.replace(/^[ \t]*(?:[-*+]|\d+[.)])[ \t]+/gm,``),t=t.replace(/[*_~]{1,3}([^*_~]+)[*_~]{1,3}/g,`$1`),t=t.replace(/\s+/g,` `).trim(),t.length>G&&(t=`${t.slice(0,G).replace(/\s+\S*$/,``)}…`),t}var q=n;function Se(e){return e.onDevice&&(K(e.lang)||!q())}function J(){return F()?.voices().map(e=>({...e,onDevice:Se(e)}))??[]}async function Y(){if(typeof speechSynthesis>`u`)return[];let e=speechSynthesis.getVoices();return e.length>0||typeof speechSynthesis.addEventListener!=`function`?e:new Promise(e=>{let t=()=>{clearTimeout(r),speechSynthesis.removeEventListener(`voiceschanged`,n),e(speechSynthesis.getVoices())},n=()=>t(),r=setTimeout(t,2e3);speechSynthesis.addEventListener(`voiceschanged`,n)})}async function Ce(e){let t=e.split(`-`)[0]?.toLowerCase();return t?J().some(e=>e.onDevice&&e.lang.split(`-`)[0].toLowerCase()===t)?!0:(await Y()).some(e=>e.lang.split(`-`)[0].toLowerCase()===t):!1}var X;function we(e){X=e}function Z(){let e=P();return{state:N(),...e?{loaded:e.loaded,total:e.total,etaSeconds:e.etaSeconds}:{}}}async function Te(){try{q()||await r({instanceId:X})}catch(e){W.warn(`kokoro asset staging failed; trying already-present weights`,e)}try{await I()}catch(e){W.warn(`kokoro warmup load failed`,e)}}function Q(){return Te(),Z()}var $=null;function Ee(){return(!$||$.state===`closed`)&&($=new AudioContext),$}async function De(e,t,n=1){let r=Ee();r.state===`suspended`&&await r.resume();let i=r.createBuffer(1,e.length,t);i.copyToChannel(new Float32Array(e),0);let a=r.createBufferSource();a.buffer=i;let o=r.createGain();o.gain.value=n,a.connect(o),o.connect(r.destination),await new Promise(e=>{a.onended=()=>e(),a.start()})}async function Oe(e){if(typeof speechSynthesis>`u`)throw Error(`speechSynthesis is unavailable in this realm`);let t=await Y();return new Promise((n,r)=>{let i=new SpeechSynthesisUtterance(e.text);if(e.lang!==void 0&&(i.lang=e.lang),e.rate!==void 0&&(i.rate=e.rate),e.pitch!==void 0&&(i.pitch=e.pitch),e.volume!==void 0&&(i.volume=e.volume),e.voice){let n=t.find(t=>t.name===e.voice);n&&(i.voice=n)}else if(e.lang){let n=e.lang.split(`-`)[0].toLowerCase(),r=t.find(e=>e.lang.split(`-`)[0].toLowerCase()===n);r&&(i.voice=r)}i.onend=()=>n(),i.onerror=e=>r(Error(`speak: ${e.error||`utterance failed`}`)),speechSynthesis.speak(i)})}async function ke(e){let t=F(),n=t?.voices()??[];if(ve(e,{ready:t!==null,voices:n,nonEnglishOnDevice:!q()})===`kokoro`&&t){let r=e.voice??ye(e.lang,n),i=0;try{let n=t.synthesizeStream(e.text,{...r?{voice:r}:{},...e.rate?{speed:e.rate}:{}});for await(let t of n)await De(t.audio,t.sampleRate,e.volume),i++;return{engine:`kokoro`}}catch(e){if(i>0)return W.warn(`kokoro stream failed mid-playback; stopping`,e),{engine:`kokoro`};W.warn(`kokoro synthesis failed; falling back to webspeech`,e)}}return await Oe(e),{engine:`webspeech`}}async function Ae(e){let t=F();if(!t)throw Error(`on-device voice not ready — run say --warmup and retry once it reports ready`);if(e.lang&&!e.lang.toLowerCase().startsWith(`en`))throw Error(`-o writes WAV via the on-device voice, which is English-only (got ${e.lang})`);if(e.voice&&!t.voices().map(e=>e.id).includes(e.voice))throw Error(`-o writes WAV via the on-device voice; "${e.voice}" is a Web Speech voice. Pick a kokoro voice (e.g. af_heart) or omit -v.`);let n=[],r=t.synthesizeStream(e.text,{...e.voice?{voice:e.voice}:{},...e.rate?{speed:e.rate}:{}});for await(let e of r)n.push({audio:e.audio,sampleRate:e.sampleRate});if(n.length===0)throw Error(`kokoro produced no audio (text is empty after sentence split?)`);return _e(n)}export{Ce as hasVoiceForLang,Z as kokoroStatus,J as kokoroVoicesIfReady,Q as kokoroWarmup,we as setSpeakAssetsInstanceId,ke as speak,xe as speechTextFromMarkdown,Ae as synthesizeToWav};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./logger-DDBAeTLF.js";import{r as t,t as n}from"./sprinkle-renderer-Pg2SqEAJ.js";import{s as r}from"./telemetry-DJyRzh6X.js";import{i}from"./feature-flags-O-TLmy2G.js";import{n as a,t as o}from"./panel-rpc-B3MSVImO.js";import{n as s,t as c}from"./bounded-walk-BjxKWNqp.js";import"./sprinkle-instances-B8n7h-oP.js";var l=[`/workspace`,`/shared`,`/scoops`,`/home`],u=[`/shared/sprinkles`],d=6,f=500,p=new Set([`connect-llm`,`welcome`]);function m(e){return p.has(e)?!0:e===`suggestions`&&!i(`memory-v2`)}async function h(e){let t=new Map;for(let n of[...u,...l])await e.exists(n)&&await g(e,n,t);return t}async function g(e,t,n){let r=s(e,t,{maxDepth:d,maxDirs:f,skip:c});for await(let t of r){if(!t.endsWith(`.shtml`))continue;let r=_(t);if(!m(r)&&!n.has(r)){let i;try{i=await e.readFile(t,{encoding:`utf-8`})??``}catch{i=``}n.set(r,{name:r,path:t,title:v(i,r),autoOpen:y(i),icon:b(i)})}}}function _(e){let t=e.split(`/`).pop()??e;return t.endsWith(`.shtml`)?t.slice(0,-6):t}function v(e,t){let n=e.match(/data-sprinkle-title=["']([^"']+)["']/);if(n)return n[1];let r=e.match(/<title>([^<]+)<\/title>/i);return r?r[1].trim():t}function y(e){return/data-sprinkle-autoopen\b/.test(e)}function b(e){let t=/<link\b/gi,n;for(;(n=t.exec(e))!==null;){let t=n.index+n[0].length,r=x(e,t);if(r<0)continue;let i=e.slice(t,r);if(!/\brel\s*=\s*("|')\s*(?:shortcut\s+)?icon\s*\1/i.test(i))continue;let a=S(i,`href`);if(a!==void 0)return a.trim()}let r=S(e,`data-sprinkle-icon`);if(r!==void 0)return r.trim()}function x(e,t){let n=!1,r=!1;for(let i=t;i<e.length;i++){let t=e.charCodeAt(i);if(n)t===34&&(n=!1);else if(r)t===39&&(r=!1);else if(t===34)n=!0;else if(t===39)r=!0;else if(t===62)return i}return-1}function S(e,t){let n=RegExp(`\\b${t}\\s*=\\s*(?:"([^"]*)"|'([^']*)')`,`i`),r=e.match(n);if(r)return r[1]??r[2]??void 0}var C=e(`sprinkle-manager`),w=`slicc-open-sprinkles`,T=`sprinkles`;function E(){try{if(typeof window>`u`||!window.location)return null;let e=new URLSearchParams(window.location.search).get(T);return e===null?null:e===``?[]:e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0)}catch{return null}}function D(e){try{if(typeof window>`u`||!window.location||typeof history>`u`||typeof history.replaceState!=`function`)return;let t=new URL(window.location.href);e.length===0?t.searchParams.delete(T):t.searchParams.set(T,e.join(`,`));let n=t.pathname+t.search+t.hash;history.replaceState(history.state??null,``,n)}catch{}}var O=`slicc-known-sprinkles`;function k(e){try{let t=new Set(e),n=A().filter(e=>t.has(e));localStorage.setItem(O,JSON.stringify(n))}catch{}}function A(){try{let e=localStorage.getItem(O);if(!e)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>typeof e==`string`):[]}catch{return[]}}var j=`slicc-autoopened-once`,M=l,N=250,P=class{fs;bridge;callbacks;availableSprinkles=new Map;watcherUnsub;openSprinkles=new Map;attentionOnly=new Set;rendererOperationTails=new Map;inflightRefresh=null;lastRefreshAt=0;autoOpenBehavior;onSendToSprinkle;onSprinkleReloaded;resolveLickOriginUnitId;registeredSprinkles=new Set;inlineSprinkles;changeListeners=new Set;changeNotifyScheduled=!1;urlWriteScheduled=!1;constructor(e,n,r,i,s={}){this.fs=e;let c=async()=>{let e=`image/png`,t=a(),n=o();if(!t&&!n)throw Error(`Screen capture unavailable in this environment`);if(t&&!navigator.mediaDevices?.getDisplayMedia)throw Error(`Screen capture not supported in this browser`);let r,i,s;if(t){let t=await navigator.mediaDevices.getDisplayMedia({video:!0,audio:!1});try{let n=document.createElement(`video`);n.srcObject=t,n.muted=!0,n.playsInline=!0,await new Promise((e,t)=>{n.onloadedmetadata=()=>n.play().then(()=>e()).catch(t),n.onerror=()=>t(Error(`Failed to load video stream`))}),await new Promise(e=>setTimeout(e,100)),i=n.videoWidth,s=n.videoHeight;let a=document.createElement(`canvas`);a.width=i,a.height=s;let o=a.getContext(`2d`);if(!o)throw Error(`Failed to get canvas context`);o.drawImage(n,0,0,i,s),r=await(await new Promise((t,n)=>{a.toBlob(e=>e?t(e):n(Error(`Failed to create image blob`)),e,1)})).arrayBuffer()}finally{for(let e of t.getTracks())e.stop()}}else{let t=await n.call(`screencapture`,{mimeType:e,quality:1},{timeoutMs:3e5});r=t.bytes,i=t.width,s=t.height}let c=new Uint8Array(r),l=[],u=8192;for(let e=0;e<c.length;e+=u)l.push(String.fromCharCode(...c.subarray(e,e+u)));return{base64:btoa(l.join(``)),width:i,height:s,mimeType:e}};this.bridge=new t(e,n,e=>this.close(e),e=>this.minimize(e),i,s.onAttachImage??(()=>{}),c,s.execHandler,(e,t,n)=>{this.openSprinkles.get(e)?.renderer.pushDeviceEvent(t,n)}),this.callbacks=r,this.autoOpenBehavior=s.autoOpenBehavior??`activate`,this.onSendToSprinkle=s.onSendToSprinkle,this.onSprinkleReloaded=s.onSprinkleReloaded,this.resolveLickOriginUnitId=s.resolveLickOriginUnitId,this.inlineSprinkles=s.inlineSprinkles??new Set}setSendToSprinkleHook(e){this.onSendToSprinkle&&!e&&C.error(`SprinkleManager broadcast hook detached`),this.onSendToSprinkle=e}setReloadHook(e){this.onSprinkleReloaded=e}enqueueRendererOperation(e,t){let n=(this.rendererOperationTails.get(e)??Promise.resolve()).then(t,t);return this.rendererOperationTails.set(e,n),n.finally(()=>{this.rendererOperationTails.get(e)===n&&this.rendererOperationTails.delete(e)})}reload(e){return this.enqueueRendererOperation(e,()=>this.reloadNow(e))}async reloadNow(e){let t=this.openSprinkles.get(e);if(!t){C.info(`Cannot reload closed sprinkle`,{name:e});return}let r=this.availableSprinkles.get(e);if(r||=(await this.refresh(),this.availableSprinkles.get(e)),!r){C.warn(`Sprinkle not found during reload`,{name:e});return}let i=await this.fs.readFile(r.path,{encoding:`utf-8`});if(i==null){C.warn(`Failed to read sprinkle content during reload`,{name:e});return}let a=typeof i==`string`?i:new TextDecoder(`utf-8`).decode(i);t.renderer?.dispose(),this.bridge.removeSprinkle(e);let o=this.bridge.createAPI(e,()=>t.lickOriginUnitId),s=new n(t.container,o);if(await s.render(a,e),!this.openSprinkles.has(e)){s.dispose();return}if(t.renderer=s,s.activateBridgeLifecycle(),this.openSprinkles.has(e)&&(C.info(`Sprinkle reloaded`,{name:e}),this.notifyChange(),this.onSprinkleReloaded))try{this.onSprinkleReloaded(e)}catch(t){C.error(`onSprinkleReloaded hook threw`,{name:e,error:t instanceof Error?t.message:String(t)})}}async restoreOpenSprinkles(){try{let e=E();if(e!==null){await this.reopenInBackground(e);return}let t=localStorage.getItem(w);t?await this.restoreFromLegacyStorage(t):await this.autoOpenFirstRun()}catch{}await this.surfaceUnseenSprinkles()}async reopenInBackground(e){for(let t of e)try{await this.open(t,void 0,{background:!0})}catch{C.warn(`Failed to restore sprinkle`,{name:t})}}async restoreFromLegacyStorage(e){try{await this.reopenInBackground(JSON.parse(e))}finally{try{localStorage.removeItem(w)}catch{}}}async autoOpenFirstRun(){let e=this.autoOpenBehavior===`attention`,t=this.loadAutoOpenedOnce(),n=new Set;for(let r of this.availableSprinkles.values())if(!(!r.autoOpen||t.has(r.name)))try{await this.open(r.name,void 0,{attention:e}),n.add(r.name)}catch{C.warn(`Failed to auto-open sprinkle`,{name:r.name})}n.size>0&&this.persistAutoOpenedOnce(n)}async surfaceUnseenSprinkles(){let e=this.loadKnownSprinkles(),t=this.loadAutoOpenedOnce(),n=this.autoOpenBehavior===`attention`,r=new Set;for(let i of this.availableSprinkles.values())if(!e.has(i.name)&&!this.openSprinkles.has(i.name)&&!(i.autoOpen&&t.has(i.name)))try{await this.open(i.name,void 0,{attention:!i.autoOpen||n}),i.autoOpen&&r.add(i.name),C.info(`Surfaced previously-unseen sprinkle`,{name:i.name})}catch{C.warn(`Failed to surface unseen sprinkle`,{name:i.name})}this.persistKnownSprinkles(new Set(this.availableSprinkles.keys())),r.size>0&&this.persistAutoOpenedOnce(r)}loadKnownSprinkles(){return new Set(A())}persistKnownSprinkles(e){try{let t=new Set([...this.loadKnownSprinkles(),...e]);localStorage.setItem(O,JSON.stringify([...t]))}catch{}}loadAutoOpenedOnce(){try{let e=localStorage.getItem(j);if(!e)return new Set;let t=JSON.parse(e);return Array.isArray(t)?new Set(t.filter(e=>typeof e==`string`)):new Set}catch{return new Set}}persistAutoOpenedOnce(e){try{let t=new Set([...this.loadAutoOpenedOnce(),...e]);localStorage.setItem(j,JSON.stringify([...t]))}catch{}}persistOpenSprinkles(){try{let e=[...this.openSprinkles.keys()].filter(e=>!this.attentionOnly.has(e));localStorage.setItem(w,JSON.stringify(e))}catch{}this.schedulePersistOpenSprinklesToUrl()}schedulePersistOpenSprinklesToUrl(){this.urlWriteScheduled||(this.urlWriteScheduled=!0,queueMicrotask(()=>{this.urlWriteScheduled=!1,D([...this.openSprinkles.keys()].filter(e=>!this.attentionOnly.has(e)))}))}async openNewAutoOpenSprinkles(){if(this.inflightRefresh!==null)return this.inflightRefresh;if(!(Date.now()-this.lastRefreshAt<N))return this.inflightRefresh=this.runOpenNewAutoOpenSprinkles().finally(()=>{this.lastRefreshAt=Date.now(),this.inflightRefresh=null}),this.inflightRefresh}async runOpenNewAutoOpenSprinkles(){let e=new Set(this.availableSprinkles.keys());await this.refresh();let t=this.autoOpenBehavior===`attention`,n=this.loadAutoOpenedOnce(),r=new Set,i=!1;for(let a of this.availableSprinkles.values())if(!this.openSprinkles.has(a.name)&&!e.has(a.name)){if(i=!0,a.autoOpen){if(n.has(a.name)){C.info(`Skipped one-shot auto-open for previously-consumed sprinkle`,{name:a.name});continue}try{await this.open(a.name,void 0,{attention:t}),r.add(a.name),C.info(`Auto-opened new sprinkle after install`,{name:a.name,attention:t})}catch{C.warn(`Failed to auto-open new sprinkle`,{name:a.name})}}else try{await this.open(a.name,void 0,{attention:!0}),C.info(`Surfaced newly-installed sprinkle in rail`,{name:a.name})}catch{C.warn(`Failed to surface newly-installed sprinkle`,{name:a.name})}}i&&this.persistKnownSprinkles(new Set(this.availableSprinkles.keys())),r.size>0&&this.persistAutoOpenedOnce(r)}async refresh(){this.availableSprinkles=await h(this.fs),C.info(`Discovered sprinkles`,{count:this.availableSprinkles.size}),this.syncRegisteredIcons(),this.notifyChange()}syncRegisteredIcons(){if(!this.callbacks.registerSprinkle)return;let e=new Set;for(let t of this.availableSprinkles.values())this.inlineSprinkles.has(t.name)||e.add(t.name);for(let t of this.availableSprinkles.values())if(e.has(t.name)&&!this.registeredSprinkles.has(t.name))try{this.callbacks.registerSprinkle(t.name,t.title,{icon:t.icon}),this.registeredSprinkles.add(t.name)}catch(e){C.warn(`registerSprinkle callback threw`,{name:t.name,error:e instanceof Error?e.message:String(e)})}for(let t of[...this.registeredSprinkles])if(!e.has(t)){this.openSprinkles.has(t)&&this.close(t);try{this.callbacks.unregisterSprinkle?.(t)}catch(e){C.warn(`unregisterSprinkle callback threw`,{name:t,error:e instanceof Error?e.message:String(e)})}this.registeredSprinkles.delete(t)}}onChange(e){return this.changeListeners.add(e),()=>{this.changeListeners.delete(e)}}notifyChange(){this.changeNotifyScheduled||(this.changeNotifyScheduled=!0,queueMicrotask(()=>{this.changeNotifyScheduled=!1;for(let e of this.changeListeners)try{e()}catch(e){C.error(`SprinkleManager.onChange handler threw`,{error:e instanceof Error?e.message:String(e)})}}))}open(e,t,n={}){return this.enqueueRendererOperation(e,()=>this.openNow(e,t,n))}async openNow(e,t,i={}){if(this.openSprinkles.has(e)){C.info(`Sprinkle already open`,{name:e});return}let a=this.availableSprinkles.get(e);if(a||=(await this.refresh(),this.availableSprinkles.get(e)),!a)throw Error(`Sprinkle not found: ${e}`);let o=await this.fs.readFile(a.path,{encoding:`utf-8`});if(o==null)throw Error(`Failed to read sprinkle content: ${a.path} (file may be corrupted or missing)`);let s=typeof o==`string`?o:new TextDecoder(`utf-8`).decode(o),c=document.createElement(`div`);c.className=`sprinkle-panel`,c.style.cssText=`width: 100%; height: 100%; display: flex; flex-direction: column; overflow-y: auto;`,c.dataset.sprinkle=e;let l={renderer:null,container:c,lickOriginUnitId:i.lickOriginTarget?this.resolveLickOriginUnitId?.(i.lickOriginTarget):void 0};this.openSprinkles.set(e,l),i.attention?this.attentionOnly.add(e):this.attentionOnly.delete(e),this.callbacks.addSprinkle(e,a.title,c,t,{attention:i.attention,background:i.background,icon:a.icon});let u=this.bridge.createAPI(e,()=>l.lickOriginUnitId),d=new n(c,u);await d.render(s,e);let f=this.openSprinkles.get(e);if(!f){d.dispose();return}f.renderer=d,d.activateBridgeLifecycle(),this.openSprinkles.has(e)&&(this.persistOpenSprinkles(),r(e),C.info(`Sprinkle opened`,{name:e,title:a.title}),this.notifyChange())}markActivated(e){this.attentionOnly.has(e)&&(this.attentionOnly.delete(e),this.persistOpenSprinkles(),C.info(`Sprinkle promoted from attention to user-opened`,{name:e}),this.notifyChange())}async activate(e,t,n={}){let r=this.attentionOnly.has(e),i=this.openSprinkles.get(e);if(r&&i&&n.lickOriginTarget&&(i.lickOriginUnitId=this.resolveLickOriginUnitId?.(n.lickOriginTarget)),r&&this.markActivated(e),!i){try{await this.open(e,t,n)}catch(t){C.warn(`Failed to open sprinkle from rail-icon click`,{name:e,error:t instanceof Error?t.message:String(t)})}return}let a=this.availableSprinkles.get(e);this.callbacks.addSprinkle(e,a?.title??e,i.container,t,{icon:a?.icon})}close(e){let t=this.openSprinkles.get(e);t&&(t.renderer?.dispose(),t.container.remove(),this.bridge.removeSprinkle(e),this.openSprinkles.delete(e),this.attentionOnly.delete(e),this.callbacks.closeSprinkleContent?this.callbacks.closeSprinkleContent(e):this.callbacks.removeSprinkle(e),this.persistOpenSprinkles(),C.info(`Sprinkle closed`,{name:e}),this.notifyChange())}minimize(e){this.openSprinkles.has(e)&&(this.callbacks.minimizeSprinkle(e),C.info(`Sprinkle minimized`,{name:e}))}available(){return Array.from(this.availableSprinkles.values())}opened(){return Array.from(this.openSprinkles.keys())}setupWatcher(e){let t=null,n=new Map,r=e=>{let r=!1;for(let t of e){let e=this.findOpenSprinkleByPath(t.path);if(e){let t=n.get(e);t&&clearTimeout(t),n.set(e,setTimeout(()=>{n.delete(e),this.reload(e).catch(t=>{C.warn(`Sprinkle reload on watcher event failed`,{name:e,error:t instanceof Error?t.message:String(t)})})},300))}else r=!0}r&&!t&&(t=setTimeout(()=>{t=null,this.openNewAutoOpenSprinkles().catch(e=>{C.warn(`Sprinkle refresh on watcher event failed`,{error:e instanceof Error?e.message:String(e)})})},150))},i=M.map(t=>e.watch(t,e=>e.endsWith(`.shtml`),r));this.watcherUnsub=()=>{for(let e of i)e();t&&=(clearTimeout(t),null);for(let e of n.values())clearTimeout(e);n.clear()}}findOpenSprinkleByPath(e){for(let[t]of this.openSprinkles){let n=this.availableSprinkles.get(t);if(n&&n.path===e)return t}return null}dispose(){this.watcherUnsub?.()}sendToSprinkle(e,t,n){let r=!n?.runtime||n.runtime===`leader`,i=!n?.runtime||n.runtime!==`leader`,a={leader:!1,followers:[]};if(r){let n=this.openSprinkles.get(e);n?(this.bridge.pushUpdate(e,t),n.renderer.pushUpdate(t),a.leader=!0):C.warn(`Cannot send to closed sprinkle`,{name:e})}if(i&&this.onSendToSprinkle)try{let r=this.onSendToSprinkle(e,t,n);r&&(a.followers=r.followers,r.unknownRuntime&&(a.unknownRuntime=r.unknownRuntime))}catch(t){C.error(`onSendToSprinkle hook threw`,{name:e,error:t instanceof Error?t.message:String(t)})}return a}};export{P as SprinkleManager,k as pruneKnownSprinkleNames,A as readKnownSprinkleNames};
|
|
1
|
+
import{t as e}from"./logger-DDBAeTLF.js";import{r as t,t as n}from"./sprinkle-renderer-CpbS9Pze.js";import{s as r}from"./telemetry-DJyRzh6X.js";import{i}from"./feature-flags-O-TLmy2G.js";import{n as a,t as o}from"./panel-rpc-B3MSVImO.js";import{n as s,t as c}from"./bounded-walk-BjxKWNqp.js";import"./sprinkle-instances-B8n7h-oP.js";var l=[`/workspace`,`/shared`,`/scoops`,`/home`],u=[`/shared/sprinkles`],d=6,f=500,p=new Set([`connect-llm`,`welcome`]);function m(e){return p.has(e)?!0:e===`suggestions`&&!i(`memory-v2`)}async function h(e){let t=new Map;for(let n of[...u,...l])await e.exists(n)&&await g(e,n,t);return t}async function g(e,t,n){let r=s(e,t,{maxDepth:d,maxDirs:f,skip:c});for await(let t of r){if(!t.endsWith(`.shtml`))continue;let r=_(t);if(!m(r)&&!n.has(r)){let i;try{i=await e.readFile(t,{encoding:`utf-8`})??``}catch{i=``}n.set(r,{name:r,path:t,title:v(i,r),autoOpen:y(i),icon:b(i)})}}}function _(e){let t=e.split(`/`).pop()??e;return t.endsWith(`.shtml`)?t.slice(0,-6):t}function v(e,t){let n=e.match(/data-sprinkle-title=["']([^"']+)["']/);if(n)return n[1];let r=e.match(/<title>([^<]+)<\/title>/i);return r?r[1].trim():t}function y(e){return/data-sprinkle-autoopen\b/.test(e)}function b(e){let t=/<link\b/gi,n;for(;(n=t.exec(e))!==null;){let t=n.index+n[0].length,r=x(e,t);if(r<0)continue;let i=e.slice(t,r);if(!/\brel\s*=\s*("|')\s*(?:shortcut\s+)?icon\s*\1/i.test(i))continue;let a=S(i,`href`);if(a!==void 0)return a.trim()}let r=S(e,`data-sprinkle-icon`);if(r!==void 0)return r.trim()}function x(e,t){let n=!1,r=!1;for(let i=t;i<e.length;i++){let t=e.charCodeAt(i);if(n)t===34&&(n=!1);else if(r)t===39&&(r=!1);else if(t===34)n=!0;else if(t===39)r=!0;else if(t===62)return i}return-1}function S(e,t){let n=RegExp(`\\b${t}\\s*=\\s*(?:"([^"]*)"|'([^']*)')`,`i`),r=e.match(n);if(r)return r[1]??r[2]??void 0}var C=e(`sprinkle-manager`),w=`slicc-open-sprinkles`,T=`sprinkles`;function E(){try{if(typeof window>`u`||!window.location)return null;let e=new URLSearchParams(window.location.search).get(T);return e===null?null:e===``?[]:e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0)}catch{return null}}function D(e){try{if(typeof window>`u`||!window.location||typeof history>`u`||typeof history.replaceState!=`function`)return;let t=new URL(window.location.href);e.length===0?t.searchParams.delete(T):t.searchParams.set(T,e.join(`,`));let n=t.pathname+t.search+t.hash;history.replaceState(history.state??null,``,n)}catch{}}var O=`slicc-known-sprinkles`;function k(e){try{let t=new Set(e),n=A().filter(e=>t.has(e));localStorage.setItem(O,JSON.stringify(n))}catch{}}function A(){try{let e=localStorage.getItem(O);if(!e)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>typeof e==`string`):[]}catch{return[]}}var j=`slicc-autoopened-once`,M=l,N=250,P=class{fs;bridge;callbacks;availableSprinkles=new Map;watcherUnsub;openSprinkles=new Map;attentionOnly=new Set;rendererOperationTails=new Map;inflightRefresh=null;lastRefreshAt=0;autoOpenBehavior;onSendToSprinkle;onSprinkleReloaded;resolveLickOriginUnitId;registeredSprinkles=new Set;inlineSprinkles;changeListeners=new Set;changeNotifyScheduled=!1;urlWriteScheduled=!1;constructor(e,n,r,i,s={}){this.fs=e;let c=async()=>{let e=`image/png`,t=a(),n=o();if(!t&&!n)throw Error(`Screen capture unavailable in this environment`);if(t&&!navigator.mediaDevices?.getDisplayMedia)throw Error(`Screen capture not supported in this browser`);let r,i,s;if(t){let t=await navigator.mediaDevices.getDisplayMedia({video:!0,audio:!1});try{let n=document.createElement(`video`);n.srcObject=t,n.muted=!0,n.playsInline=!0,await new Promise((e,t)=>{n.onloadedmetadata=()=>n.play().then(()=>e()).catch(t),n.onerror=()=>t(Error(`Failed to load video stream`))}),await new Promise(e=>setTimeout(e,100)),i=n.videoWidth,s=n.videoHeight;let a=document.createElement(`canvas`);a.width=i,a.height=s;let o=a.getContext(`2d`);if(!o)throw Error(`Failed to get canvas context`);o.drawImage(n,0,0,i,s),r=await(await new Promise((t,n)=>{a.toBlob(e=>e?t(e):n(Error(`Failed to create image blob`)),e,1)})).arrayBuffer()}finally{for(let e of t.getTracks())e.stop()}}else{let t=await n.call(`screencapture`,{mimeType:e,quality:1},{timeoutMs:3e5});r=t.bytes,i=t.width,s=t.height}let c=new Uint8Array(r),l=[],u=8192;for(let e=0;e<c.length;e+=u)l.push(String.fromCharCode(...c.subarray(e,e+u)));return{base64:btoa(l.join(``)),width:i,height:s,mimeType:e}};this.bridge=new t(e,n,e=>this.close(e),e=>this.minimize(e),i,s.onAttachImage??(()=>{}),c,s.execHandler,(e,t,n)=>{this.openSprinkles.get(e)?.renderer.pushDeviceEvent(t,n)}),this.callbacks=r,this.autoOpenBehavior=s.autoOpenBehavior??`activate`,this.onSendToSprinkle=s.onSendToSprinkle,this.onSprinkleReloaded=s.onSprinkleReloaded,this.resolveLickOriginUnitId=s.resolveLickOriginUnitId,this.inlineSprinkles=s.inlineSprinkles??new Set}setSendToSprinkleHook(e){this.onSendToSprinkle&&!e&&C.error(`SprinkleManager broadcast hook detached`),this.onSendToSprinkle=e}setReloadHook(e){this.onSprinkleReloaded=e}enqueueRendererOperation(e,t){let n=(this.rendererOperationTails.get(e)??Promise.resolve()).then(t,t);return this.rendererOperationTails.set(e,n),n.finally(()=>{this.rendererOperationTails.get(e)===n&&this.rendererOperationTails.delete(e)})}reload(e){return this.enqueueRendererOperation(e,()=>this.reloadNow(e))}async reloadNow(e){let t=this.openSprinkles.get(e);if(!t){C.info(`Cannot reload closed sprinkle`,{name:e});return}let r=this.availableSprinkles.get(e);if(r||=(await this.refresh(),this.availableSprinkles.get(e)),!r){C.warn(`Sprinkle not found during reload`,{name:e});return}let i=await this.fs.readFile(r.path,{encoding:`utf-8`});if(i==null){C.warn(`Failed to read sprinkle content during reload`,{name:e});return}let a=typeof i==`string`?i:new TextDecoder(`utf-8`).decode(i);t.renderer?.dispose(),this.bridge.removeSprinkle(e);let o=this.bridge.createAPI(e,()=>t.lickOriginUnitId),s=new n(t.container,o);if(await s.render(a,e),!this.openSprinkles.has(e)){s.dispose();return}if(t.renderer=s,s.activateBridgeLifecycle(),this.openSprinkles.has(e)&&(C.info(`Sprinkle reloaded`,{name:e}),this.notifyChange(),this.onSprinkleReloaded))try{this.onSprinkleReloaded(e)}catch(t){C.error(`onSprinkleReloaded hook threw`,{name:e,error:t instanceof Error?t.message:String(t)})}}async restoreOpenSprinkles(){try{let e=E();if(e!==null){await this.reopenInBackground(e);return}let t=localStorage.getItem(w);t?await this.restoreFromLegacyStorage(t):await this.autoOpenFirstRun()}catch{}await this.surfaceUnseenSprinkles()}async reopenInBackground(e){for(let t of e)try{await this.open(t,void 0,{background:!0})}catch{C.warn(`Failed to restore sprinkle`,{name:t})}}async restoreFromLegacyStorage(e){try{await this.reopenInBackground(JSON.parse(e))}finally{try{localStorage.removeItem(w)}catch{}}}async autoOpenFirstRun(){let e=this.autoOpenBehavior===`attention`,t=this.loadAutoOpenedOnce(),n=new Set;for(let r of this.availableSprinkles.values())if(!(!r.autoOpen||t.has(r.name)))try{await this.open(r.name,void 0,{attention:e}),n.add(r.name)}catch{C.warn(`Failed to auto-open sprinkle`,{name:r.name})}n.size>0&&this.persistAutoOpenedOnce(n)}async surfaceUnseenSprinkles(){let e=this.loadKnownSprinkles(),t=this.loadAutoOpenedOnce(),n=this.autoOpenBehavior===`attention`,r=new Set;for(let i of this.availableSprinkles.values())if(!e.has(i.name)&&!this.openSprinkles.has(i.name)&&!(i.autoOpen&&t.has(i.name)))try{await this.open(i.name,void 0,{attention:!i.autoOpen||n}),i.autoOpen&&r.add(i.name),C.info(`Surfaced previously-unseen sprinkle`,{name:i.name})}catch{C.warn(`Failed to surface unseen sprinkle`,{name:i.name})}this.persistKnownSprinkles(new Set(this.availableSprinkles.keys())),r.size>0&&this.persistAutoOpenedOnce(r)}loadKnownSprinkles(){return new Set(A())}persistKnownSprinkles(e){try{let t=new Set([...this.loadKnownSprinkles(),...e]);localStorage.setItem(O,JSON.stringify([...t]))}catch{}}loadAutoOpenedOnce(){try{let e=localStorage.getItem(j);if(!e)return new Set;let t=JSON.parse(e);return Array.isArray(t)?new Set(t.filter(e=>typeof e==`string`)):new Set}catch{return new Set}}persistAutoOpenedOnce(e){try{let t=new Set([...this.loadAutoOpenedOnce(),...e]);localStorage.setItem(j,JSON.stringify([...t]))}catch{}}persistOpenSprinkles(){try{let e=[...this.openSprinkles.keys()].filter(e=>!this.attentionOnly.has(e));localStorage.setItem(w,JSON.stringify(e))}catch{}this.schedulePersistOpenSprinklesToUrl()}schedulePersistOpenSprinklesToUrl(){this.urlWriteScheduled||(this.urlWriteScheduled=!0,queueMicrotask(()=>{this.urlWriteScheduled=!1,D([...this.openSprinkles.keys()].filter(e=>!this.attentionOnly.has(e)))}))}async openNewAutoOpenSprinkles(){if(this.inflightRefresh!==null)return this.inflightRefresh;if(!(Date.now()-this.lastRefreshAt<N))return this.inflightRefresh=this.runOpenNewAutoOpenSprinkles().finally(()=>{this.lastRefreshAt=Date.now(),this.inflightRefresh=null}),this.inflightRefresh}async runOpenNewAutoOpenSprinkles(){let e=new Set(this.availableSprinkles.keys());await this.refresh();let t=this.autoOpenBehavior===`attention`,n=this.loadAutoOpenedOnce(),r=new Set,i=!1;for(let a of this.availableSprinkles.values())if(!this.openSprinkles.has(a.name)&&!e.has(a.name)){if(i=!0,a.autoOpen){if(n.has(a.name)){C.info(`Skipped one-shot auto-open for previously-consumed sprinkle`,{name:a.name});continue}try{await this.open(a.name,void 0,{attention:t}),r.add(a.name),C.info(`Auto-opened new sprinkle after install`,{name:a.name,attention:t})}catch{C.warn(`Failed to auto-open new sprinkle`,{name:a.name})}}else try{await this.open(a.name,void 0,{attention:!0}),C.info(`Surfaced newly-installed sprinkle in rail`,{name:a.name})}catch{C.warn(`Failed to surface newly-installed sprinkle`,{name:a.name})}}i&&this.persistKnownSprinkles(new Set(this.availableSprinkles.keys())),r.size>0&&this.persistAutoOpenedOnce(r)}async refresh(){this.availableSprinkles=await h(this.fs),C.info(`Discovered sprinkles`,{count:this.availableSprinkles.size}),this.syncRegisteredIcons(),this.notifyChange()}syncRegisteredIcons(){if(!this.callbacks.registerSprinkle)return;let e=new Set;for(let t of this.availableSprinkles.values())this.inlineSprinkles.has(t.name)||e.add(t.name);for(let t of this.availableSprinkles.values())if(e.has(t.name)&&!this.registeredSprinkles.has(t.name))try{this.callbacks.registerSprinkle(t.name,t.title,{icon:t.icon}),this.registeredSprinkles.add(t.name)}catch(e){C.warn(`registerSprinkle callback threw`,{name:t.name,error:e instanceof Error?e.message:String(e)})}for(let t of[...this.registeredSprinkles])if(!e.has(t)){this.openSprinkles.has(t)&&this.close(t);try{this.callbacks.unregisterSprinkle?.(t)}catch(e){C.warn(`unregisterSprinkle callback threw`,{name:t,error:e instanceof Error?e.message:String(e)})}this.registeredSprinkles.delete(t)}}onChange(e){return this.changeListeners.add(e),()=>{this.changeListeners.delete(e)}}notifyChange(){this.changeNotifyScheduled||(this.changeNotifyScheduled=!0,queueMicrotask(()=>{this.changeNotifyScheduled=!1;for(let e of this.changeListeners)try{e()}catch(e){C.error(`SprinkleManager.onChange handler threw`,{error:e instanceof Error?e.message:String(e)})}}))}open(e,t,n={}){return this.enqueueRendererOperation(e,()=>this.openNow(e,t,n))}async openNow(e,t,i={}){if(this.openSprinkles.has(e)){C.info(`Sprinkle already open`,{name:e});return}let a=this.availableSprinkles.get(e);if(a||=(await this.refresh(),this.availableSprinkles.get(e)),!a)throw Error(`Sprinkle not found: ${e}`);let o=await this.fs.readFile(a.path,{encoding:`utf-8`});if(o==null)throw Error(`Failed to read sprinkle content: ${a.path} (file may be corrupted or missing)`);let s=typeof o==`string`?o:new TextDecoder(`utf-8`).decode(o),c=document.createElement(`div`);c.className=`sprinkle-panel`,c.style.cssText=`width: 100%; height: 100%; display: flex; flex-direction: column; overflow-y: auto;`,c.dataset.sprinkle=e;let l={renderer:null,container:c,lickOriginUnitId:i.lickOriginTarget?this.resolveLickOriginUnitId?.(i.lickOriginTarget):void 0};this.openSprinkles.set(e,l),i.attention?this.attentionOnly.add(e):this.attentionOnly.delete(e),this.callbacks.addSprinkle(e,a.title,c,t,{attention:i.attention,background:i.background,icon:a.icon});let u=this.bridge.createAPI(e,()=>l.lickOriginUnitId),d=new n(c,u);await d.render(s,e);let f=this.openSprinkles.get(e);if(!f){d.dispose();return}f.renderer=d,d.activateBridgeLifecycle(),this.openSprinkles.has(e)&&(this.persistOpenSprinkles(),r(e),C.info(`Sprinkle opened`,{name:e,title:a.title}),this.notifyChange())}markActivated(e){this.attentionOnly.has(e)&&(this.attentionOnly.delete(e),this.persistOpenSprinkles(),C.info(`Sprinkle promoted from attention to user-opened`,{name:e}),this.notifyChange())}async activate(e,t,n={}){let r=this.attentionOnly.has(e),i=this.openSprinkles.get(e);if(r&&i&&n.lickOriginTarget&&(i.lickOriginUnitId=this.resolveLickOriginUnitId?.(n.lickOriginTarget)),r&&this.markActivated(e),!i){try{await this.open(e,t,n)}catch(t){C.warn(`Failed to open sprinkle from rail-icon click`,{name:e,error:t instanceof Error?t.message:String(t)})}return}let a=this.availableSprinkles.get(e);this.callbacks.addSprinkle(e,a?.title??e,i.container,t,{icon:a?.icon})}close(e){let t=this.openSprinkles.get(e);t&&(t.renderer?.dispose(),t.container.remove(),this.bridge.removeSprinkle(e),this.openSprinkles.delete(e),this.attentionOnly.delete(e),this.callbacks.closeSprinkleContent?this.callbacks.closeSprinkleContent(e):this.callbacks.removeSprinkle(e),this.persistOpenSprinkles(),C.info(`Sprinkle closed`,{name:e}),this.notifyChange())}minimize(e){this.openSprinkles.has(e)&&(this.callbacks.minimizeSprinkle(e),C.info(`Sprinkle minimized`,{name:e}))}available(){return Array.from(this.availableSprinkles.values())}opened(){return Array.from(this.openSprinkles.keys())}setupWatcher(e){let t=null,n=new Map,r=e=>{let r=!1;for(let t of e){let e=this.findOpenSprinkleByPath(t.path);if(e){let t=n.get(e);t&&clearTimeout(t),n.set(e,setTimeout(()=>{n.delete(e),this.reload(e).catch(t=>{C.warn(`Sprinkle reload on watcher event failed`,{name:e,error:t instanceof Error?t.message:String(t)})})},300))}else r=!0}r&&!t&&(t=setTimeout(()=>{t=null,this.openNewAutoOpenSprinkles().catch(e=>{C.warn(`Sprinkle refresh on watcher event failed`,{error:e instanceof Error?e.message:String(e)})})},150))},i=M.map(t=>e.watch(t,e=>e.endsWith(`.shtml`),r));this.watcherUnsub=()=>{for(let e of i)e();t&&=(clearTimeout(t),null);for(let e of n.values())clearTimeout(e);n.clear()}}findOpenSprinkleByPath(e){for(let[t]of this.openSprinkles){let n=this.availableSprinkles.get(t);if(n&&n.path===e)return t}return null}dispose(){this.watcherUnsub?.()}sendToSprinkle(e,t,n){let r=!n?.runtime||n.runtime===`leader`,i=!n?.runtime||n.runtime!==`leader`,a={leader:!1,followers:[]};if(r){let n=this.openSprinkles.get(e);n?(this.bridge.pushUpdate(e,t),n.renderer.pushUpdate(t),a.leader=!0):C.warn(`Cannot send to closed sprinkle`,{name:e})}if(i&&this.onSendToSprinkle)try{let r=this.onSendToSprinkle(e,t,n);r&&(a.followers=r.followers,r.unknownRuntime&&(a.unknownRuntime=r.unknownRuntime))}catch(t){C.error(`onSendToSprinkle hook threw`,{name:e,error:t instanceof Error?t.message:String(t)})}return a}};export{P as SprinkleManager,k as pruneKnownSprinkleNames,A as readKnownSprinkleNames};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/usb-claim-broker-Dacw2Z3M.js","assets/usb-device-registry--JwKRTYp.js","assets/rolldown-runtime-Dd_uD5pT.js","assets/slicc-editor-BwV9b9S6.js","assets/preload-helper-Czpn1I53.js","assets/upgrade-own-properties-DI0JKxGt.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{t as e}from"./preload-helper-Czpn1I53.js";import{J as t}from"./wc-shortcuts-
|
|
2
|
+
import{t as e}from"./preload-helper-Czpn1I53.js";import{J as t}from"./wc-shortcuts-CETptwt9.js";import{n,r}from"./hid-device-registry-B2R-0rNt.js";import{a as i,i as a}from"./serial-port-registry-CCqklAEr.js";import{c as o,d as s,g as c,i as l,l as u,m as d,n as f,o as p,p as m,r as h,t as g,u as _}from"./hid-operations-C97SZtrY.js";import{a as v,i as y,o as ee,s as te}from"./usb-device-registry--JwKRTYp.js";import{a as ne,d as re,f as b,g as x,h as S,i as C,l as w,m as T,n as E,o as ie,p as ae,r as oe,s as se,u as ce}from"./usb-operations-v1mGAdRY.js";import"./shared-mBEktoxE.js";import{a as D,n as le,r as O}from"./theme-DFKCBK8N.js";function k(){try{let e=globalThis.window??globalThis;return e.self!==e.top}catch{return!0}}var A=new WeakSet;function j(e,t){if(A.has(e)){t?.();return}let n=!1;M(e,t,()=>{n=!0}),setTimeout(()=>{n||e.isConnected&&M(e)},500)}function M(e,t,n){if(A.has(e)){t?.();return}A.add(e);let r=e.style.display;e.style.display=`none`;let i=!1,a=a=>{i||(i=!0,e.style.display=r,A.delete(e),a&&n?.(),t?.())},o=globalThis.requestAnimationFrame;typeof o==`function`&&o(()=>{o(()=>a(!0))}),setTimeout(()=>a(!1),100)}var N=`
|
|
3
3
|
var _themeOverrideKeys = [];
|
|
4
4
|
var _themeCssStyle = null;
|
|
5
5
|
function applyIframeTheme(event) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{t as e}from"./logger-LESFN7Hj.js";import{n as t}from"./panel-rpc-BPwAqRch.js";import{t as n}from"./base64-DzRgusa4.js";import{t as r}from"./types-Dgm4REV3.js";import"./fs-
|
|
1
|
+
import{t as e}from"./logger-LESFN7Hj.js";import{n as t}from"./panel-rpc-BPwAqRch.js";import{t as n}from"./base64-DzRgusa4.js";import{t as r}from"./types-Dgm4REV3.js";import"./fs-CjgMvwqK.js";import"./tray-storage-keys-DbThbnIh.js";function i(e){return e==null?[]:Array.isArray(e)?e:[e]}function a(e,t,n,r){var i,a=e[t],o=~r.string.indexOf(t)?n==null||n===!0?``:String(n):typeof n==`boolean`?n:~r.boolean.indexOf(t)?n===`false`?!1:n===`true`||(e._.push((i=+n,i*0==0?i:n)),!!n):(i=+n,i*0==0?i:n);e[t]=a==null?o:Array.isArray(a)?a.concat(o):[a,o]}function o(e,t){e||=[],t||={};var n,r,o,s,c,l={_:[]},u=0,d=0,f=0,p=e.length;let m=t.alias!==void 0,h=t.unknown!==void 0,g=t.default!==void 0;if(t.alias=t.alias||{},t.string=i(t.string),t.boolean=i(t.boolean),m)for(n in t.alias)for(r=t.alias[n]=i(t.alias[n]),u=0;u<r.length;u++)(t.alias[r[u]]=r.concat(n)).splice(u,1);for(u=t.boolean.length;u-->0;)for(r=t.alias[t.boolean[u]]||[],d=r.length;d-->0;)t.boolean.push(r[d]);for(u=t.string.length;u-->0;)for(r=t.alias[t.string[u]]||[],d=r.length;d-->0;)t.string.push(r[d]);if(g){for(n in t.default)if(s=typeof t.default[n],r=t.alias[n]=t.alias[n]||[],t[s]!==void 0)for(t[s].push(n),u=0;u<r.length;u++)t[s].push(r[u])}let _=h?Object.keys(t.alias):[];for(u=0;u<p;u++){if(o=e[u],o===`--`){l._=l._.concat(e.slice(++u));break}for(d=0;d<o.length&&o.charCodeAt(d)===45;d++);if(d===0)l._.push(o);else if(o.substring(d,d+3)===`no-`){if(s=o.substring(d+3),h&&!~_.indexOf(s))return t.unknown(o);l[s]=!1}else{for(f=d+1;f<o.length&&o.charCodeAt(f)!==61;f++);for(s=o.substring(d,f),c=o.substring(++f)||u+1===p||(``+e[u+1]).charCodeAt(0)===45||e[++u],r=d===2?[s]:s,f=0;f<r.length;f++){if(s=r[f],h&&!~_.indexOf(s))return t.unknown(`-`.repeat(d)+s);a(l,s,f+1<r.length||c,t)}}}if(g)for(n in t.default)l[n]===void 0&&(l[n]=t.default[n]);if(m)for(n in l)for(r=t.alias[n]||[];r.length>0;)l[r.shift()]=l[n];return l}function s(e,t){let n=[],r=new Map,i=new Set;for(let a=0;a<e.length;a++){let o=e[a];o.startsWith(`-`)?t.has(o)?r.set(o,e[++a]??``):i.add(o):n.push(o)}return{positionals:n,flags:r,bools:i}}function c(e){let t=new Set(e.string??[]),n=e.alias??{};for(let[e,r]of Object.entries(n)){let n=[e,...Array.isArray(r)?r:[r]];if(n.some(e=>t.has(e)))for(let e of n)t.add(e)}return t}const l=/^(--?)([^=]+)(=.*)?$/;function u(e){let t=new Set(e.string??[]);for(let n of e.boolean??[])t.add(n),t.add(`no-${n}`);for(let[n,r]of Object.entries(e.alias??{})){t.add(n);for(let e of Array.isArray(r)?r:[r])t.add(e)}return t}function d(e,t,n){let r=0;for(;r<e.length;r++){let i=e[r];if(!i.startsWith(`-`)||i===`-`)break;let a=l.exec(i);if(!a||!n.has(a[2]))break;!a[3]&&t.has(a[2])&&r+1<e.length&&r++}return r}function f(e,t){let n=[];for(let r=0;r<e.length;r++){let i=e[r],a=l.exec(i);a&&!a[3]&&t.has(a[2])&&r+1<e.length?(n.push(`${i}=${e[r+1]}`),r++):n.push(i)}return n}function p(e,t={}){let n=e,r=[];if(t[`--`]){let t=e.indexOf(`--`);t!==-1&&(n=e.slice(0,t),r=e.slice(t+1))}let i=c(t),a=n,s=[];if(t.stopEarly){let e=d(n,i,u(t));a=n.slice(0,e),s=n.slice(e)}let{_:l,...p}=o(f(a,i),{string:t.string?[...t.string]:void 0,boolean:t.boolean?[...t.boolean]:void 0,alias:t.alias,default:t.default}),m=t.stopEarly?s:l;return{_:m,positionals:m,flags:p,doubleDashRest:r}}const m=[`playwright-cli`,`playwright`,`puppeteer`],h=new WeakMap,g=e(`playwright`);function _(e,t){let n=h.get(e);n||(n=new WeakMap,h.set(e,n));let r=n.get(t);return r||(r={snapshots:new Map,appTabId:null,harRecorder:null,sessionDirsCreated:!1,teleportWatchers:new Map,consoleMessages:new Map,consoleCleanup:new Map,networkRequests:new Map,networkRequestIndex:new Map,networkCleanup:new Map,routes:new Map,routeCleanup:new Map,lastMousePosition:new Map},n.set(t,r)),r}const v=/^(f[0-9]+)?e[0-9]+$/;function y(e){return v.test(e)}function b(e){let t=e.match(/^(f[0-9]+)(e[0-9]+)$/);return t?{framePrefix:t[1],isIframe:!0}:{framePrefix:``,isIframe:!1}}const x=n,S=new Set([`click`,`dblclick`,`fill`,`type`,`press`,`goto`,`navigate`,`select`,`check`,`uncheck`,`drag`,`dialog-accept`,`dialog-dismiss`,`drop`]);function C(e){return e.toISOString().replace(/:/g,`-`)}function w(e){return e instanceof r||typeof e==`object`&&e&&`code`in e?e.code===`EEXIST`:e instanceof Error&&e.message.includes(`EEXIST`)}const T=`function(text) {
|
|
2
2
|
const el = this;
|
|
3
3
|
const tag = el.tagName;
|
|
4
4
|
const proto = tag === 'TEXTAREA' ? window.HTMLTextAreaElement.prototype : window.HTMLInputElement.prototype;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./logger-LESFN7Hj.js";import{t as n}from"./types-Dgm4REV3.js";import{t as r}from"./global-db-DJXlpNui.js";var i=e({MCP_STORE_PATH:()=>o,deleteServer:()=>y,getServer:()=>_,listServers:()=>b,readMcpAuthEntries:()=>S,readMcpAuthEntry:()=>x,readServersFile:()=>h,setServer:()=>v,writeServersFile:()=>g});const a=t(`mcp-store`),o=`/workspace/.mcp/servers.json`;let s=null,c=null;async function l(){return s||=await import(`./fs-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./logger-LESFN7Hj.js";import{t as n}from"./types-Dgm4REV3.js";import{t as r}from"./global-db-DJXlpNui.js";var i=e({MCP_STORE_PATH:()=>o,deleteServer:()=>y,getServer:()=>_,listServers:()=>b,readMcpAuthEntries:()=>S,readMcpAuthEntry:()=>x,readServersFile:()=>h,setServer:()=>v,writeServersFile:()=>g});const a=t(`mcp-store`),o=`/workspace/.mcp/servers.json`;let s=null,c=null;async function l(){return s||=await import(`./fs-CjgMvwqK.js`).then(e=>e.t),s}async function u(e){if(e)return e;if(c&&c.dbName===`slicc-fs-global`)return c.instance;let{VirtualFS:t}=await l(),n=await t.create({dbName:r});return c={instance:n,dbName:r},n}function d(){return{version:1,servers:{}}}function f(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function p(e){if(!f(e))return null;let t={...e};return typeof t.url==`string`?(delete t.sessionId,t):null}function m(e){if(!f(e))return d();let t=e,n=typeof t.version==`number`?t.version:1,r={};if(f(t.servers))for(let[e,n]of Object.entries(t.servers)){let t=p(n);t&&(r[e]=t)}return{version:n,servers:r}}async function h(e){try{let t=await(await u(e)).readFile(o,{encoding:`utf-8`});try{return m(JSON.parse(t))}catch(e){return a.warn(`servers.json is not valid JSON; treating as empty`,{error:e instanceof Error?e.message:String(e)}),d()}}catch(e){if(e instanceof n&&e.code===`ENOENT`)return d();throw e}}async function g(e,t){let n=await u(t);await n.mkdir(`/workspace/.mcp`,{recursive:!0});let r=m({version:e.version||1,servers:e.servers??{}});await n.writeFile(o,JSON.stringify(r,null,2))}async function _(e,t){return(await h(t)).servers[e]??null}async function v(e,t,n){let r=await h(n),i=p({...r.servers[e],...t});if(!i)throw Error(`MCP server entry requires a URL`);return r.servers[e]=i,await g(r,n),i}async function y(e,t){let n=await h(t);return e in n.servers&&(delete n.servers[e],await g(n,t),!0)}async function b(e){return(await h(e)).servers}async function x(e){let t=await _(e);return!t?.url||!t.auth?.clientId?null:{name:e,serverUrl:t.url,auth:t.auth}}async function S(){let e=await b(),t=[];for(let[n,r]of Object.entries(e))!r?.url||!r.auth?.clientId||t.push({name:n,serverUrl:r.url,auth:r.auth});return t}export{x as n,i as r,S as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./types-Dgm4REV3.js";import{t}from"./global-db-DJXlpNui.js";const n=`/workspace/.plugins/plugins.json`;let r=null;async function i(e){if(e)return e;if(r&&r.dbName===`slicc-fs-global`)return r.instance;let{VirtualFS:n}=await import(`./fs-
|
|
1
|
+
import{t as e}from"./types-Dgm4REV3.js";import{t}from"./global-db-DJXlpNui.js";const n=`/workspace/.plugins/plugins.json`;let r=null;async function i(e){if(e)return e;if(r&&r.dbName===`slicc-fs-global`)return r.instance;let{VirtualFS:n}=await import(`./fs-CjgMvwqK.js`).then(e=>e.t),i=await n.create({dbName:t});return r={instance:i,dbName:t},i}function a(){return{version:1,plugins:{}}}function o(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function s(e){if(!o(e))return null;let t=e;return typeof t.root==`string`?t:null}function c(e){if(!o(e))return a();let t=e,n=typeof t.version==`number`?t.version:1,r={};if(o(t.plugins))for(let[e,n]of Object.entries(t.plugins)){let t=s(n);t&&(r[e]=t)}return{version:n,plugins:r}}async function l(t){try{let e=await(await i(t)).readFile(n,{encoding:`utf-8`});try{return c(JSON.parse(e))}catch{return a()}}catch(t){if(t instanceof e&&t.code===`ENOENT`)return a();throw t}}async function u(e,t){let r=await i(t);await r.mkdir(`/workspace/.plugins`,{recursive:!0});let a=c({version:e.version||1,plugins:e.plugins??{}});await r.writeFile(n,JSON.stringify(a,null,2))}async function d(e,t){return(await l(t)).plugins[e]??null}async function f(e,t,n){let r=await l(n);r.plugins[e]=t,await u(r,n)}async function p(e,t){let n=await l(t);return e in n.plugins&&(delete n.plugins[e],await u(n,t),!0)}async function m(e){return(await l(e)).plugins}export{p as deleteInstalledPlugin,d as getInstalledPlugin,m as listInstalledPlugins,f as setInstalledPlugin};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/panel-rpc-B3MSVImO.js","assets/rolldown-runtime-Dd_uD5pT.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{t as e}from"./preload-helper-Czpn1I53.js";import{t}from"./logger-DDBAeTLF.js";import{t as n}from"./quick-llm-
|
|
2
|
+
import{t as e}from"./preload-helper-Czpn1I53.js";import{t}from"./logger-DDBAeTLF.js";import{t as n}from"./quick-llm-hedJ8LEL.js";import{t as r}from"./approval-decision-CS9Wwm5B.js";import"./capability-DQ10DnFn.js";import{t as i}from"./page-approval-service-BXlCsull.js";var a=t(`sudo:timeout`);function o(e=`user-timeout`){return{decision:`deny`,reason:e}}function s(e,t={}){let n=t.timeoutMs??3e5;if(!Number.isFinite(n)||n<=0)return e;let r=t.setTimer??((e,t)=>setTimeout(e,t)),i=t.clearTimer??(e=>clearTimeout(e));return{requestApproval(t,s){return new Promise(c=>{let l=new AbortController,u=()=>l.abort();s?.signal?.addEventListener(`abort`,u,{once:!0});let d=!1,f=e=>{d=!0,s?.signal?.removeEventListener(`abort`,u),c(e)},p=r(()=>{d||(a.warn(`sudo approval timed out — failing closed`,{kind:t.kind,detail:t.detail,timeoutMs:n}),l.abort(),f(o(`user-timeout`)))},n),m=e=>{if(d){a.warn(`sudo decision arrived after timeout — discarded`,{kind:t.kind,detail:t.detail,decision:e.decision});return}i(p),f(e)};e.requestApproval(t,{signal:l.signal}).then(m,e=>{a.warn(`sudo broker threw — denying`,{error:e instanceof Error?e.message:String(e)}),m({decision:`deny`})})})}}}var c=t(`sudo-suggest`),l=[`You generalize a single shell command into a minimal glob pattern for an`,`allow-list rule. Output ONLY the pattern on one line — no prose, no quotes,`,`no backticks. Keep the leading command/sub-command verbatim and replace only`,`the volatile tail (args, paths, refs) with a single trailing "*".`,`Examples:`,` git push origin main -> git push*`,` rm -rf build/cache -> rm -rf*`,` npm install left-pad -> npm install*`].join(`
|
|
3
3
|
`),u=[`You generalize a single filesystem path into a minimal glob pattern for an`,`allow-list rule. Output ONLY the pattern on one line — no prose, no quotes,`,`no backticks. Keep the meaningful directory prefix and replace the volatile`,`leaf (and below) with "**". Examples:`,` /workspace/.git/config -> /workspace/.git/**`,` /shared/secrets/openai.key -> /shared/secrets/**`,` /workspace/src/app/main.ts -> /workspace/src/**`].join(`
|
|
4
4
|
`);async function d(e,t){if(e.suggestedPattern&&e.suggestedPattern.trim().length>0)return e.suggestedPattern.trim();let r=e.detail.trim(),i=e.kind===`command`?l:u,a=null;try{a=await n({prompt:r,system:i,maxTokens:40,temperature:0,signal:t})}catch(e){c.debug(`suggestPattern: quickLabel threw`,{error:e instanceof Error?e.message:String(e)}),a=null}return f(a)||r}function f(e){if(!e)return null;let t=(e.split(`
|
|
5
5
|
`,1)[0]?.trim()??``).replace(/^`+/,``).replace(/`+$/,``).replace(/^["']/,``).replace(/["']$/,``).trim();return t.length===0?null:t}var p=t(`sudo:capability-gesture`);function m(e,t={}){let n=t.suggest??d;return{async requestApproval(t,i){let a=i?.signal,o;if(t.suggestedPattern)o=t.suggestedPattern;else try{o=await n(t,a)}catch{o=t.detail}if(a?.aborted)return p.warn(`sudo approval aborted before prompting — denying`,{detail:t.detail}),{decision:`deny`};if(!e)return p.warn(`no CapabilityBroker injected for the sudo gesture hop — denying (composition bug, never a guessed transport)`,{detail:t.detail}),{decision:`deny`};let s=await e.approvals.request({kind:t.kind,detail:t.detail,suggestedPattern:o,...t.requester?{requester:t.requester}:{},...t.approver?{approver:t.approver}:{},...a?{signal:a}:{}});return s.ok?r(s.value,o):(p.warn(`capability broker approvals.request failed — denying`,{message:s.message}),{decision:`deny`})}}}var h=t(`sudo:tray-first`),g=6e5;function _(t,n={}){let r=n.suggest??d,i=n.timeoutMs??g,a=n.getClient??(async()=>{let{getPanelRpcClient:t}=await e(async()=>{let{getPanelRpcClient:e}=await import(`./panel-rpc-B3MSVImO.js`).then(e=>e.i);return{getPanelRpcClient:e}},__vite__mapDeps([0,1]));return t()});return{async requestApproval(e,n){if(n?.signal?.aborted)return{decision:`deny`};let o=e.suggestedPattern;if(!o)try{o=await r(e,n?.signal)}catch{o=e.detail}let s={...e,suggestedPattern:o},c=null;try{c=await a()}catch(e){h.debug?.(`panel-RPC client lookup threw — using native broker`,{error:e instanceof Error?e.message:String(e)})}if(c)try{let e=await c.call(`sudo-request`,{request:s,mode:`tray-first`},{timeoutMs:i});if(e?.handled!==!1)return v(e?.decision,o)}catch(e){h.warn(`tray-first sudo probe failed — using native broker`,{error:e instanceof Error?e.message:String(e)})}return t.requestApproval(s,n)}}}function v(e,t){if(!e||typeof e!=`object`)return{decision:`deny`};let n=e,r=n.attestation===`biometric`||n.attestation===`passcode`||n.attestation===`none`?n.attestation:void 0;return n.decision===`allow`?{decision:`allow`,...r?{attestation:r}:{}}:n.decision===`always`?{decision:`always`,pattern:typeof n.pattern==`string`&&n.pattern.trim().length>0?n.pattern.trim():t,...r?{attestation:r}:{}}:{decision:`deny`}}var y=t(`sudo`),b=`__slicc_sudo`;function x(e){return s(S(e))}function S(e){let t=m(e);return e?.adapter===`extension-direct`||e?.adapter===`extension-delegate`?t:_(t)}function C(e){let t={requestApproval:t=>e.requestApproval(t)};return globalThis[b]=t,y.info(`sudo broker test hook published on globalThis.__slicc_sudo`),t}export{x as createSudoBroker,i as installPanelSudoResponder,C as installSudoTestHook};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{t as e}from"./logger-LESFN7Hj.js";import{n as t,r as n}from"./path-utils-DNJG-zQf.js";import{n as r,r as i}from"./virtual-device-paths-CS5o4QVz.js";const a=e(`sudo:sudoers`),o=`/etc/sudoers`,s=`/etc/sudoers.d`,c=`/etc/APPROVALS.md`,l=/^\/scoops\/[^/]+\/etc\/sudoers(?:\.d(?:\/.*)?)?$/;function u(e){return l.test(t(e))}function d(e){return e.length>0&&e!==`.`&&e!==`..`&&!/[/\\]/.test(e)}function f(e){return d(e)?`${s}/scoop-${e}`:null}function p(e){return e.startsWith(`scoop-`)&&e.slice(6)||null}function m(e){return`/scoops/${e}/etc/sudoers`}function h(e,t){return e===`no-match`?t===`require-approval`?`require-approval`:`no-match`:e}function g(){return{cmnd:[],read:[],write:[],export:[]}}function _(e){return`.+^$()[]|\\{}`.includes(e)?`\\${e}`:e}function v(e){let t=``,n=0;for(;n<e.length;){let r=e[n];r===`*`?(t+=`.*`,n+=e[n+1]===`*`?2:1):r===`?`?(t+=`.`,n+=1):(t+=_(r),n+=1)}return RegExp(`^${t}$`,`s`)}function y(e){return e.split(/\r?\n/,1)[0]?.trim()??``}const b=new Set([`Cmnd`,`Read`,`Write`,`Export`]);function x(e){switch(e){case`read`:return`Read`;case`write`:return`Write`;case`export`:return`Export`;default:return`Cmnd`}}function S(e){let t=e.trim(),n=!1,r=t.search(/\s/);(r===-1?t:t.slice(0,r))===`NOPASSWD`&&(n=!0,t=r===-1?``:t.slice(r).trimStart());let i=t.search(/\s/),a=i===-1?t:t.slice(0,i);if(!b.has(a))return null;let o=i===-1?``:t.slice(i).trim();return o?{directive:a,nopasswd:n,pattern:o}:null}function C(e){let t=g();try{if(typeof e!=`string`)return t;for(let r of e.split(`
|
|
2
|
+
`)){let e=r.trim();if(!e||e.startsWith(`#`))continue;let i=S(e);if(!i){a.warn(`Skipping unrecognized sudoers line`,{line:e});continue}let o=i.directive===`Cmnd`||i.directive===`Export`?v:n,s={pattern:i.pattern,nopasswd:i.nopasswd,regex:o(i.pattern)};i.directive===`Cmnd`?t.cmnd.push(s):i.directive===`Read`?t.read.push(s):i.directive===`Export`?t.export.push(s):t.write.push(s)}return t}catch(e){return a.error(`Failed to parse sudoers; falling back to self-protection only`,{err:e}),g()}}const w=[`NOPASSWD Read /tmp`,`NOPASSWD Read /tmp/**`,`NOPASSWD Write /tmp`,`NOPASSWD Write /tmp/**`].join(`
|
|
3
|
+
`);let T=null;function E(){return T??=C(w),T}function D(...e){let t=g();for(let n of e)n&&(t.cmnd.push(...n.cmnd),t.read.push(...n.read),t.write.push(...n.write),t.export.push(...n.export??[]));return t}function O(e,t){let n=!1;for(let r of e)if(r.regex.test(t)){if(r.nopasswd)return`nopasswd-allow`;n=!0}return n?`require-approval`:`no-match`}function k(e,t){return O(e.export??[],t)===`nopasswd-allow`?`nopasswd-allow`:`require-approval`}function A(e,t){return O(e.cmnd,t.trim())}function j(e){return e===`/etc/sudoers`||e===`/etc/APPROVALS.md`||e===`/etc/sudoers.d`||e.startsWith(`/etc/sudoers.d/`)||e===`/etc/slicc/layouts`||e.startsWith(`/etc/slicc/layouts/`)}function M(e,n,a,o){let s=t(a);if(n===`write`){if(l.test(s))return`deny`;if(j(s))return`require-approval`;if(o?.isContentWrite&&i(s))return`nopasswd-allow`}return r(s)?`nopasswd-allow`:O(n===`read`?e.read:e.write,s)}export{p as _,E as a,g as c,A as d,k as f,y as g,C as h,h as i,u as l,D as m,s as n,v as o,M as p,o as r,x as s,c as t,m as u,f as v};
|
|
@@ -12,10 +12,15 @@ var e=`<!DOCTYPE html>
|
|
|
12
12
|
<style>
|
|
13
13
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
14
14
|
|
|
15
|
+
/* The stream fills a panel iframe edge to edge, so the GUTTER IS OURS:
|
|
16
|
+
with the \`*\` reset above and no host padding (neither \`.sprinkle-panel\`
|
|
17
|
+
nor \`.msg__dip\` adds any), content without this sits flush against the
|
|
18
|
+
panel's rounded corners. */
|
|
15
19
|
body {
|
|
16
20
|
font-family: var(--s2-font-family, 'Adobe Clean', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif);
|
|
17
21
|
background: transparent;
|
|
18
22
|
color: var(--s2-content-default, #e8e8e8);
|
|
23
|
+
padding: 14px 18px 20px;
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
/* ── Gelatiere stream ──
|
|
@@ -23,8 +28,10 @@ var e=`<!DOCTYPE html>
|
|
|
23
28
|
stream draws NO boxes of its own — flat entries separated by
|
|
24
29
|
hairlines, one pill button per entry, everything else plain text. */
|
|
25
30
|
#gelatiereStream[hidden] { display: none; }
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
/* No horizontal padding of their own — \`body\` owns the gutter, so the
|
|
32
|
+
hairline separators run the full width the way a list should. */
|
|
33
|
+
.gelatiere-entry { padding: 18px 0; }
|
|
34
|
+
.gelatiere-entry:first-child { padding-top: 2px; }
|
|
28
35
|
.gelatiere-entry + .gelatiere-entry,
|
|
29
36
|
.gelatiere-done {
|
|
30
37
|
border-top: 1px solid var(--s2-border-subtle, var(--s2-gray-200, #e8e8e8));
|
|
@@ -40,7 +47,11 @@ var e=`<!DOCTYPE html>
|
|
|
40
47
|
line-height: 1.35;
|
|
41
48
|
color: var(--s2-content-default, #e8e8e8);
|
|
42
49
|
}
|
|
43
|
-
|
|
50
|
+
/* \`:is(i, svg)\` because Lucide REPLACES the \`<i data-lucide>\` placeholder
|
|
51
|
+
with an \`<svg width="24" height="24">\` — an \`i\`-only rule stops
|
|
52
|
+
matching the moment the icons render, and every glyph in the panel
|
|
53
|
+
falls back to 24px. */
|
|
54
|
+
.gelatiere-entry__head :is(i, svg) { width: 15px; height: 15px; flex-shrink: 0; }
|
|
44
55
|
.gelatiere-entry__title { flex: 1; }
|
|
45
56
|
.gelatiere-kind {
|
|
46
57
|
font-size: 10px;
|
|
@@ -68,7 +79,7 @@ var e=`<!DOCTYPE html>
|
|
|
68
79
|
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
69
80
|
font-size: 11px;
|
|
70
81
|
}
|
|
71
|
-
/* Buttons sit on the right, dialog-style: quiet "
|
|
82
|
+
/* Buttons sit on the right, dialog-style: quiet "Dismiss" beside the
|
|
72
83
|
primary pill. The taken note pushes itself back to the left. */
|
|
73
84
|
.gelatiere-actions {
|
|
74
85
|
display: flex;
|
|
@@ -78,7 +89,7 @@ var e=`<!DOCTYPE html>
|
|
|
78
89
|
margin-top: 12px;
|
|
79
90
|
}
|
|
80
91
|
.gelatiere-actions .gelatiere-taken-note { margin-right: auto; }
|
|
81
|
-
/* "
|
|
92
|
+
/* "Dismiss" is a quiet text button — one pill per entry is plenty. */
|
|
82
93
|
.gelatiere-quiet-btn {
|
|
83
94
|
background: none;
|
|
84
95
|
border: none;
|
|
@@ -89,11 +100,28 @@ var e=`<!DOCTYPE html>
|
|
|
89
100
|
padding: 4px 0;
|
|
90
101
|
}
|
|
91
102
|
.gelatiere-quiet-btn:hover { color: var(--s2-content-secondary, #a1a1a1); }
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
103
|
+
/* ── Empty state + discovery ──
|
|
104
|
+
Before the first pass there is nothing to render, and "nothing yet"
|
|
105
|
+
alone reads like a broken panel: it says what will land here, then
|
|
106
|
+
links three use cases from www.sliccy.com. Both reuse the entry's own
|
|
107
|
+
head / why classes, so the panel keeps one type ramp and only the
|
|
108
|
+
link chrome is new. */
|
|
109
|
+
.gelatiere-empty { padding: 2px 0 4px; }
|
|
110
|
+
.gelatiere-explore {
|
|
111
|
+
margin-top: 18px;
|
|
112
|
+
padding-top: 14px;
|
|
113
|
+
border-top: 1px solid var(--s2-border-subtle, var(--s2-gray-200, #e8e8e8));
|
|
114
|
+
}
|
|
115
|
+
.gelatiere-explore__link {
|
|
116
|
+
display: block;
|
|
117
|
+
padding: 10px 0;
|
|
118
|
+
text-decoration: none;
|
|
119
|
+
color: inherit;
|
|
120
|
+
}
|
|
121
|
+
.gelatiere-explore__link + .gelatiere-explore__link {
|
|
122
|
+
border-top: 1px solid var(--s2-border-subtle, var(--s2-gray-200, #e8e8e8));
|
|
96
123
|
}
|
|
124
|
+
.gelatiere-explore__link:hover .gelatiere-entry__title { text-decoration: underline; }
|
|
97
125
|
/* An entry the user just acted on: buttons gone, a quiet confirmation
|
|
98
126
|
line in their place. The entry stays until the next render. */
|
|
99
127
|
.gelatiere-entry--taken .gelatiere-entry__head,
|
|
@@ -106,9 +134,9 @@ var e=`<!DOCTYPE html>
|
|
|
106
134
|
font-size: 12px;
|
|
107
135
|
color: var(--s2-content-positive, #2d9d78);
|
|
108
136
|
}
|
|
109
|
-
.gelatiere-taken-note i { width: 14px; height: 14px; flex-shrink: 0; }
|
|
137
|
+
.gelatiere-taken-note :is(i, svg) { width: 14px; height: 14px; flex-shrink: 0; }
|
|
110
138
|
/* The "Done" ledger under the open entries: one quiet line each. */
|
|
111
|
-
.gelatiere-done { margin-top:
|
|
139
|
+
.gelatiere-done { margin-top: 6px; padding-top: 14px; }
|
|
112
140
|
.gelatiere-done-title {
|
|
113
141
|
padding-bottom: 6px;
|
|
114
142
|
font-size: 10px;
|
|
@@ -125,7 +153,7 @@ var e=`<!DOCTYPE html>
|
|
|
125
153
|
font-size: 12px;
|
|
126
154
|
color: var(--s2-content-secondary, #a1a1a1);
|
|
127
155
|
}
|
|
128
|
-
.gelatiere-done-row i {
|
|
156
|
+
.gelatiere-done-row :is(i, svg) {
|
|
129
157
|
width: 13px;
|
|
130
158
|
height: 13px;
|
|
131
159
|
flex-shrink: 0;
|
|
@@ -159,11 +187,24 @@ var e=`<!DOCTYPE html>
|
|
|
159
187
|
// waking the agent; \`gelatiere-install\` / \`gelatiere-try\` go to the
|
|
160
188
|
// cone, which acts on them per the \`gelatiere\` skill.
|
|
161
189
|
var GELATIERE_SUGGESTIONS_PATH = '/shared/.gelatiere/suggestions.json';
|
|
190
|
+
// \`skill-idea\` and \`issue\` are prompt-carrying like \`use-case\` and ride
|
|
191
|
+
// the same \`gelatiere-try\` lick; only the label and the pill differ, so
|
|
192
|
+
// "report this to SLICC" does not render as "Try this".
|
|
162
193
|
var KIND_LABELS = {
|
|
163
|
-
'skill':
|
|
164
|
-
'use-case':
|
|
165
|
-
'tip':
|
|
194
|
+
'skill': { label: 'Skill', icon: 'package', action: 'Install', done: 'installed' },
|
|
195
|
+
'use-case': { label: 'Try this', icon: 'sparkles', action: 'Try it', done: 'tried' },
|
|
196
|
+
'tip': { label: 'Tip', icon: 'lightbulb', action: null, done: 'tried' },
|
|
197
|
+
'skill-idea': { label: 'New skill', icon: 'wand-sparkles', action: 'Draft it', done: 'drafted' },
|
|
198
|
+
'issue': { label: 'Report', icon: 'bug', action: 'Report it', done: 'reported' },
|
|
166
199
|
};
|
|
200
|
+
// Rotated daily by the command, so a second visit differs.
|
|
201
|
+
var USE_CASE_COMMAND = 'gelatiere use-cases --limit 3 --json';
|
|
202
|
+
var USE_CASE_CACHE_MS = 12 * 60 * 60 * 1000;
|
|
203
|
+
var EMPTY_HEADLINE = 'Nothing here yet';
|
|
204
|
+
var EMPTY_BODY =
|
|
205
|
+
'The gelatiere reads how you actually work — nightly, and after each chat ' +
|
|
206
|
+
'ends — and leaves what it finds here: a skill worth installing, a use ' +
|
|
207
|
+
'case worth trying, a habit worth changing. Check back after your next session.';
|
|
167
208
|
|
|
168
209
|
function el(tag, className, text) {
|
|
169
210
|
var node = document.createElement(tag);
|
|
@@ -185,15 +226,16 @@ var e=`<!DOCTYPE html>
|
|
|
185
226
|
return btn;
|
|
186
227
|
}
|
|
187
228
|
|
|
188
|
-
function gelatiereQuietButton(label, onClick) {
|
|
229
|
+
function gelatiereQuietButton(label, onClick, title) {
|
|
189
230
|
var btn = el('button', 'gelatiere-quiet-btn', label);
|
|
190
231
|
btn.type = 'button';
|
|
232
|
+
if (title) btn.title = title;
|
|
191
233
|
btn.onclick = onClick;
|
|
192
234
|
return btn;
|
|
193
235
|
}
|
|
194
236
|
|
|
195
237
|
// WHAT (icon + imperative title + quiet kind label), WHY (one
|
|
196
|
-
// paragraph), then one pill and a quiet "
|
|
238
|
+
// paragraph), then one pill and a quiet "Dismiss". Flat on purpose:
|
|
197
239
|
// the sidebar panel is the box, so the entries draw none of their own.
|
|
198
240
|
function buildSuggestionCard(s) {
|
|
199
241
|
var meta = KIND_LABELS[s.kind] || KIND_LABELS.tip;
|
|
@@ -217,7 +259,7 @@ var e=`<!DOCTYPE html>
|
|
|
217
259
|
var actions = el('div', 'gelatiere-actions');
|
|
218
260
|
// Taking an entry keeps it visible: the buttons swap for a quiet
|
|
219
261
|
// confirmation so the user sees what they set in motion. Dismissing
|
|
220
|
-
// removes it — "
|
|
262
|
+
// removes it — "Dismiss" means "stop showing me this".
|
|
221
263
|
function markTaken(note) {
|
|
222
264
|
card.classList.add('gelatiere-entry--taken');
|
|
223
265
|
var done = el('div', 'gelatiere-taken-note');
|
|
@@ -226,21 +268,21 @@ var e=`<!DOCTYPE html>
|
|
|
226
268
|
actions.replaceChildren(done);
|
|
227
269
|
if (window.LucideIcons) window.LucideIcons.render();
|
|
228
270
|
}
|
|
229
|
-
// "
|
|
271
|
+
// "Dismiss" first in the DOM: the row is right-aligned, so the quiet
|
|
230
272
|
// button sits left of the primary pill, which keeps the right edge.
|
|
231
|
-
actions.appendChild(gelatiereQuietButton('
|
|
273
|
+
actions.appendChild(gelatiereQuietButton('Dismiss', function () {
|
|
232
274
|
if (window.slicc) slicc.lick({ action: 'gelatiere-dismiss', data: { id: s.id } });
|
|
233
275
|
card.remove();
|
|
234
|
-
if (!document.querySelector('.gelatiere-entry'))
|
|
235
|
-
}));
|
|
276
|
+
if (!document.querySelector('.gelatiere-entry')) renderGelatiereCaughtUp();
|
|
277
|
+
}, "that's not for me"));
|
|
236
278
|
if (s.kind === 'skill') {
|
|
237
|
-
actions.appendChild(gelatierePrimaryButton(
|
|
279
|
+
actions.appendChild(gelatierePrimaryButton(meta.action, function () {
|
|
238
280
|
if (window.slicc) slicc.lick({ action: 'gelatiere-install',
|
|
239
281
|
data: { id: s.id, skill: s.skill || null, install: s.install || null, title: s.title } });
|
|
240
282
|
markTaken('Installing — the cone is on it.');
|
|
241
283
|
}));
|
|
242
|
-
} else if (
|
|
243
|
-
actions.appendChild(gelatierePrimaryButton(
|
|
284
|
+
} else if (meta.action && s.prompt) {
|
|
285
|
+
actions.appendChild(gelatierePrimaryButton(meta.action, function () {
|
|
244
286
|
if (window.slicc) slicc.lick({ action: 'gelatiere-try',
|
|
245
287
|
data: { id: s.id, prompt: s.prompt, title: s.title } });
|
|
246
288
|
markTaken('Sent to the cone — watch the chat.');
|
|
@@ -264,21 +306,89 @@ var e=`<!DOCTYPE html>
|
|
|
264
306
|
var wrap = el('div', 'gelatiere-done');
|
|
265
307
|
wrap.appendChild(el('div', 'gelatiere-done-title', 'Done'));
|
|
266
308
|
taken.slice(0, DONE_LEDGER_LIMIT).forEach(function (s) {
|
|
309
|
+
var meta = KIND_LABELS[s.kind] || KIND_LABELS.tip;
|
|
267
310
|
var row = el('div', 'gelatiere-done-row');
|
|
268
311
|
row.appendChild(lucide('check'));
|
|
269
312
|
row.appendChild(el('span', 'gelatiere-done-title-text', s.title));
|
|
270
|
-
row.appendChild(el('span', 'gelatiere-done-what',
|
|
271
|
-
s.kind === 'skill' ? 'installed' : 'tried'));
|
|
313
|
+
row.appendChild(el('span', 'gelatiere-done-what', meta.done));
|
|
272
314
|
wrap.appendChild(row);
|
|
273
315
|
});
|
|
274
316
|
return wrap;
|
|
275
317
|
}
|
|
276
318
|
|
|
277
|
-
|
|
319
|
+
// \`gelatiere use-cases\` owns the fetching (pinned host), so the sprinkle
|
|
320
|
+
// needs no egress of its own; the result is cached in sprinkle state
|
|
321
|
+
// because this runs on every panel open.
|
|
322
|
+
function readCachedUseCases() {
|
|
323
|
+
try {
|
|
324
|
+
var saved = window.slicc && slicc.getState && slicc.getState();
|
|
325
|
+
if (!saved || !saved.useCases || !saved.fetchedAt) return null;
|
|
326
|
+
if (Date.now() - saved.fetchedAt > USE_CASE_CACHE_MS) return null;
|
|
327
|
+
return saved.useCases;
|
|
328
|
+
} catch (e) { return null; }
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
function loadUseCases() {
|
|
332
|
+
var cached = readCachedUseCases();
|
|
333
|
+
if (cached) return Promise.resolve(cached);
|
|
334
|
+
if (!window.slicc || typeof slicc.exec !== 'function') return Promise.resolve([]);
|
|
335
|
+
return Promise.resolve(slicc.exec(USE_CASE_COMMAND)).then(function (result) {
|
|
336
|
+
if (!result || result.exitCode !== 0) return [];
|
|
337
|
+
var parsed = JSON.parse(result.stdout);
|
|
338
|
+
if (!Array.isArray(parsed)) return [];
|
|
339
|
+
var cases = parsed.filter(function (c) { return c && c.url && c.title; });
|
|
340
|
+
try { slicc.setState({ fetchedAt: Date.now(), useCases: cases }); } catch (e) {}
|
|
341
|
+
return cases;
|
|
342
|
+
}, function () { return []; });
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Appended after the empty text, never instead of it: the panel must
|
|
346
|
+
// read correctly whether or not the site answers.
|
|
347
|
+
function appendUseCases(stream) {
|
|
348
|
+
loadUseCases().then(function (cases) {
|
|
349
|
+
if (!cases.length || !stream.isConnected) return;
|
|
350
|
+
var wrap = el('div', 'gelatiere-explore');
|
|
351
|
+
wrap.appendChild(el('div', 'gelatiere-done-title', 'Meanwhile, from sliccy.com'));
|
|
352
|
+
cases.forEach(function (c) {
|
|
353
|
+
var link = el('a', 'gelatiere-explore__link');
|
|
354
|
+
link.href = c.url;
|
|
355
|
+
link.target = '_blank';
|
|
356
|
+
link.rel = 'noopener';
|
|
357
|
+
var head = el('div', 'gelatiere-entry__head');
|
|
358
|
+
head.appendChild(el('span', 'gelatiere-entry__title', c.title));
|
|
359
|
+
head.appendChild(lucide('arrow-up-right'));
|
|
360
|
+
link.appendChild(head);
|
|
361
|
+
if (c.description) link.appendChild(el('div', 'gelatiere-why', c.description));
|
|
362
|
+
wrap.appendChild(link);
|
|
363
|
+
});
|
|
364
|
+
stream.appendChild(wrap);
|
|
365
|
+
if (window.LucideIcons) window.LucideIcons.render();
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Nothing to act on: what will land here, then what to do until then.
|
|
370
|
+
function renderGelatiereEmpty(headline, body) {
|
|
278
371
|
var stream = document.getElementById('gelatiereStream');
|
|
279
372
|
stream.innerHTML = '';
|
|
280
|
-
|
|
373
|
+
var empty = el('div', 'gelatiere-empty');
|
|
374
|
+
var head = el('div', 'gelatiere-entry__head');
|
|
375
|
+
head.appendChild(lucide('ice-cream-cone'));
|
|
376
|
+
head.appendChild(el('span', 'gelatiere-entry__title', headline));
|
|
377
|
+
empty.appendChild(head);
|
|
378
|
+
empty.appendChild(el('div', 'gelatiere-why', body));
|
|
379
|
+
stream.appendChild(empty);
|
|
281
380
|
stream.hidden = false;
|
|
381
|
+
if (window.LucideIcons) window.LucideIcons.render();
|
|
382
|
+
appendUseCases(stream);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/** Every suggestion answered — the Done ledger, if any, follows. */
|
|
386
|
+
function renderGelatiereCaughtUp() {
|
|
387
|
+
renderGelatiereEmpty(
|
|
388
|
+
'All caught up',
|
|
389
|
+
'You have answered everything the gelatiere left here. The next pass runs ' +
|
|
390
|
+
'tonight, and again after your next chat ends.'
|
|
391
|
+
);
|
|
282
392
|
}
|
|
283
393
|
|
|
284
394
|
function renderGelatiereStream() {
|
|
@@ -288,7 +398,7 @@ var e=`<!DOCTYPE html>
|
|
|
288
398
|
// rendering the leader's rail): the quiet empty line, never an error
|
|
289
399
|
// box and never a wizard.
|
|
290
400
|
if (!window.slicc || typeof slicc.readFile !== 'function') {
|
|
291
|
-
renderGelatiereEmpty(
|
|
401
|
+
renderGelatiereEmpty(EMPTY_HEADLINE, EMPTY_BODY);
|
|
292
402
|
return;
|
|
293
403
|
}
|
|
294
404
|
// \`exists\` first: a missing store is the ordinary state before the
|
|
@@ -308,17 +418,25 @@ var e=`<!DOCTYPE html>
|
|
|
308
418
|
var open = readable.filter(function (s) { return !s.dismissedAt && !s.takenAt; });
|
|
309
419
|
var taken = readable.filter(function (s) { return s.takenAt; });
|
|
310
420
|
if (open.length === 0 && taken.length === 0) {
|
|
311
|
-
renderGelatiereEmpty(
|
|
421
|
+
renderGelatiereEmpty(EMPTY_HEADLINE, EMPTY_BODY);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
// Everything answered: the caught-up copy, then the ledger. The use
|
|
425
|
+
// cases land after both (they arrive a round trip later), so the
|
|
426
|
+
// panel still offers a next step instead of a closed book.
|
|
427
|
+
if (open.length === 0) {
|
|
428
|
+
renderGelatiereCaughtUp();
|
|
429
|
+
stream.appendChild(buildDoneLedger(taken));
|
|
430
|
+
if (window.LucideIcons) window.LucideIcons.render();
|
|
312
431
|
return;
|
|
313
432
|
}
|
|
314
433
|
stream.innerHTML = '';
|
|
315
|
-
if (open.length === 0) stream.appendChild(el('div', 'gelatiere-empty', 'All caught up.'));
|
|
316
434
|
open.forEach(function (s) { stream.appendChild(buildSuggestionCard(s)); });
|
|
317
435
|
if (taken.length > 0) stream.appendChild(buildDoneLedger(taken));
|
|
318
436
|
stream.hidden = false;
|
|
319
437
|
if (window.LucideIcons) window.LucideIcons.render();
|
|
320
438
|
}, function () {
|
|
321
|
-
renderGelatiereEmpty(
|
|
439
|
+
renderGelatiereEmpty(EMPTY_HEADLINE, EMPTY_BODY);
|
|
322
440
|
});
|
|
323
441
|
}
|
|
324
442
|
|