tagword-codeagent 1.1.6__py3-none-any.whl
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.
- codeagent/__init__.py +10 -0
- codeagent/__main__.py +13 -0
- codeagent/cli/__init__.py +13 -0
- codeagent/cli/entrypoint.py +161 -0
- codeagent/cli/main.py +979 -0
- codeagent/core/__init__.py +2 -0
- codeagent/core/attachments.py +342 -0
- codeagent/core/audio_models.py +50 -0
- codeagent/core/bootstrap.py +178 -0
- codeagent/core/default_presets.py +159 -0
- codeagent/core/env.py +106 -0
- codeagent/core/folder_picker.py +151 -0
- codeagent/core/image_understanding.py +90 -0
- codeagent/core/models.py +6 -0
- codeagent/core/paths.py +238 -0
- codeagent/core/pricing.py +107 -0
- codeagent/core/process_ports.py +258 -0
- codeagent/core/seed_bridge.py +21 -0
- codeagent/core/settings.py +98 -0
- codeagent/core/speech_synth.py +330 -0
- codeagent/core/team_config.py +247 -0
- codeagent/core/team_manager.py +245 -0
- codeagent/core/token_counter.py +41 -0
- codeagent/core/tts_voices.py +103 -0
- codeagent/core/usage_billing.py +72 -0
- codeagent/core/vision_models.py +93 -0
- codeagent/memory/diary.py +144 -0
- codeagent/persona_defaults/README.md +12 -0
- codeagent/persona_defaults/agent.md +352 -0
- codeagent/persona_defaults/identity.md +29 -0
- codeagent/persona_defaults/memory.md +4 -0
- codeagent/persona_defaults/skills.md +325 -0
- codeagent/persona_defaults/soul.md +38 -0
- codeagent/persona_defaults/tools.md +41 -0
- codeagent/persona_defaults/user.md +18 -0
- codeagent/runtime/__init__.py +11 -0
- codeagent/runtime/agent_context.py +6 -0
- codeagent/runtime/agent_runtime.py +21 -0
- codeagent/runtime/compact_prompt.py +9 -0
- codeagent/runtime/compact_state.py +40 -0
- codeagent/runtime/llm_worker.py +132 -0
- codeagent/runtime/orchestrator.py +161 -0
- codeagent/runtime/prompt_enrichment.py +324 -0
- codeagent/runtime/session_manager.py +30 -0
- codeagent/runtime/task_split.py +38 -0
- codeagent/runtime/turn_loop.py +13 -0
- codeagent/runtime/worker.py +48 -0
- codeagent/server/__init__.py +505 -0
- codeagent/server/app_factory.py +1292 -0
- codeagent/server/attachment_api.py +261 -0
- codeagent/server/hub.py +175 -0
- codeagent/server/icon.png +0 -0
- codeagent/server/self_healing.py +143 -0
- codeagent/server/team_engine.py +243 -0
- codeagent/server/tts_api.py +51 -0
- codeagent/server/webui_api_app.py +3180 -0
- codeagent/skills/__init__.py +2 -0
- codeagent/skills/select.py +144 -0
- codeagent/tools/__init__.py +6 -0
- codeagent/tools/agent_tools.py +10 -0
- codeagent/web/__init__.py +1 -0
- codeagent/web/__pycache__/__init__.cpython-313.pyc +0 -0
- codeagent/web/__pycache__/app.cpython-313.pyc +0 -0
- codeagent/web/__pycache__/auth_impl.cpython-313.pyc +0 -0
- codeagent/web/auth_impl.py +326 -0
- codeagent/web/static/00-marked.min.js +6 -0
- codeagent/web/static/00-mermaid.min.js +2314 -0
- codeagent/web/static/00-purify.min.js +3 -0
- codeagent/web/static/00-storage.js +83 -0
- codeagent/web/static/00-utils.js +51 -0
- codeagent/web/static/01-theme.css +96 -0
- codeagent/web/static/01a-scroll.js +86 -0
- codeagent/web/static/01b-think.js +62 -0
- codeagent/web/static/01c-session-identity.js +81 -0
- codeagent/web/static/01c-session-thinking.js +61 -0
- codeagent/web/static/01c-session-tree-menus.js +349 -0
- codeagent/web/static/01c-session-tree.js +531 -0
- codeagent/web/static/01c-session-utilities.js +83 -0
- codeagent/web/static/01c-vision-model.js +132 -0
- codeagent/web/static/01d-image-gen-model.js +84 -0
- codeagent/web/static/01e-audio-model.js +97 -0
- codeagent/web/static/01f-compose-ui.js +88 -0
- codeagent/web/static/01g-tts-settings.js +128 -0
- codeagent/web/static/01h-music-model.js +85 -0
- codeagent/web/static/01i-model-stack.js +291 -0
- codeagent/web/static/01j-video-gen-model.js +85 -0
- codeagent/web/static/01k-model-stack-bootstrap.js +66 -0
- codeagent/web/static/01k-model-stack-state.js +209 -0
- codeagent/web/static/01q-inflight.js +195 -0
- codeagent/web/static/02-reset.css +22 -0
- codeagent/web/static/02-session-ui.js +201 -0
- codeagent/web/static/03-layout-p1.css +2 -0
- codeagent/web/static/03-layout-p2.css +2 -0
- codeagent/web/static/03a-links-stream.js +88 -0
- codeagent/web/static/03b-stream-text.js +119 -0
- codeagent/web/static/03c-render-bubble.js +520 -0
- codeagent/web/static/03d-agent-bubble.js +126 -0
- codeagent/web/static/03e-tool-trace.js +182 -0
- codeagent/web/static/03f-timeline.js +54 -0
- codeagent/web/static/03g-bubble-tts.js +292 -0
- codeagent/web/static/04-components-p1.css +1 -0
- codeagent/web/static/04-components-p2b.css +1 -0
- codeagent/web/static/04-components-p3.css +2 -0
- codeagent/web/static/04-components-p4.css +1 -0
- codeagent/web/static/04-components-p5.css +1 -0
- codeagent/web/static/04-components-p6.css +58 -0
- codeagent/web/static/04-components-p7.css +4 -0
- codeagent/web/static/04-components-p8.css +1 -0
- codeagent/web/static/04-components-p9.css +1 -0
- codeagent/web/static/04-ws-connect.js +351 -0
- codeagent/web/static/04-ws-helpers.js +116 -0
- codeagent/web/static/05-chat-p1.css +1058 -0
- codeagent/web/static/05-chat-p2.css +1 -0
- codeagent/web/static/05-chat-p3.css +295 -0
- codeagent/web/static/05a-session-history.js +176 -0
- codeagent/web/static/05b-session-list.js +114 -0
- codeagent/web/static/05c-dialog.js +123 -0
- codeagent/web/static/05d-project-create.js +172 -0
- codeagent/web/static/05e-project-remote.js +143 -0
- codeagent/web/static/06-chat.js +552 -0
- codeagent/web/static/06-utilities.css +181 -0
- codeagent/web/static/06b-attachments.js +304 -0
- codeagent/web/static/06c-camera.js +488 -0
- codeagent/web/static/07-activity-bar.css +127 -0
- codeagent/web/static/09-git-p1.css +1 -0
- codeagent/web/static/09-git-p2.css +1 -0
- codeagent/web/static/09a-init-bind.js +110 -0
- codeagent/web/static/09b-panel-toggle.js +80 -0
- codeagent/web/static/09c-api-refresh.js +100 -0
- codeagent/web/static/09d-status-log.js +80 -0
- codeagent/web/static/09e-commit.js +80 -0
- codeagent/web/static/09f-remote.js +93 -0
- codeagent/web/static/11a-cron-parse.js +117 -0
- codeagent/web/static/11b-cron-panel.js +100 -0
- codeagent/web/static/11c-cron-card.js +133 -0
- codeagent/web/static/11d-cron-form.js +105 -0
- codeagent/web/static/11e-env-config.js +168 -0
- codeagent/web/static/11f-env-llm-a-state.js +136 -0
- codeagent/web/static/11f-env-llm-b-form.js +409 -0
- codeagent/web/static/11f-env-llm-c-board.js +322 -0
- codeagent/web/static/11g-env-paths-git.js +973 -0
- codeagent/web/static/11h-env-mcp-a-state.js +161 -0
- codeagent/web/static/11h-env-mcp-b-form.js +229 -0
- codeagent/web/static/11h-env-mcp-c-board.js +565 -0
- codeagent/web/static/12-plugins.js +127 -0
- codeagent/web/static/13a-skills.js +156 -0
- codeagent/web/static/13a-todo-utils.js +140 -0
- codeagent/web/static/13b-todo-fetch.js +106 -0
- codeagent/web/static/13b-tools.js +127 -0
- codeagent/web/static/13c-todo-crud.js +92 -0
- codeagent/web/static/14-activity-bar.js +177 -0
- codeagent/web/static/15-plans.css +194 -0
- codeagent/web/static/15-plans.js +219 -0
- codeagent/web/static/16-mobile.css +612 -0
- codeagent/web/static/16-mobile.js +178 -0
- codeagent/web/static/17-preset-ux.css +287 -0
- codeagent/web/static/18-agent-mgr.css +616 -0
- codeagent/web/static/18-agent-mgr.js +204 -0
- codeagent/web/static/24-health-dashboard.js +68 -0
- codeagent/web/static/99-brand-polish.css +152 -0
- codeagent/web/static/body.html +824 -0
- codeagent/web/static/setup/setup_form.html +171 -0
- codeagent/web/static/setup/setup_head.html +100 -0
- codeagent/web/static/setup/setup_tail.html +264 -0
- codeagent/web/static/setup/setup_test.html +38 -0
- codeagent/web/web_login.html +265 -0
- codeagent/web/webui.html +35 -0
- tagword_codeagent-1.1.6.dist-info/METADATA +273 -0
- tagword_codeagent-1.1.6.dist-info/RECORD +173 -0
- tagword_codeagent-1.1.6.dist-info/WHEEL +5 -0
- tagword_codeagent-1.1.6.dist-info/entry_points.txt +3 -0
- tagword_codeagent-1.1.6.dist-info/licenses/LICENSE +21 -0
- tagword_codeagent-1.1.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/*! @license DOMPurify 3.1.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.1.6/LICENSE */
|
|
2
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).DOMPurify=t()}(this,(function(){"use strict";const{entries:e,setPrototypeOf:t,isFrozen:n,getPrototypeOf:o,getOwnPropertyDescriptor:r}=Object;let{freeze:i,seal:a,create:l}=Object,{apply:c,construct:s}="undefined"!=typeof Reflect&&Reflect;i||(i=function(e){return e}),a||(a=function(e){return e}),c||(c=function(e,t,n){return e.apply(t,n)}),s||(s=function(e,t){return new e(...t)});const u=b(Array.prototype.forEach),m=b(Array.prototype.pop),p=b(Array.prototype.push),f=b(String.prototype.toLowerCase),d=b(String.prototype.toString),h=b(String.prototype.match),g=b(String.prototype.replace),T=b(String.prototype.indexOf),y=b(String.prototype.trim),E=b(Object.prototype.hasOwnProperty),_=b(RegExp.prototype.test),A=(N=TypeError,function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return s(N,t)});var N;function b(e){return function(t){for(var n=arguments.length,o=new Array(n>1?n-1:0),r=1;r<n;r++)o[r-1]=arguments[r];return c(e,t,o)}}function S(e,o){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:f;t&&t(e,null);let i=o.length;for(;i--;){let t=o[i];if("string"==typeof t){const e=r(t);e!==t&&(n(o)||(o[i]=e),t=e)}e[t]=!0}return e}function R(e){for(let t=0;t<e.length;t++){E(e,t)||(e[t]=null)}return e}function w(t){const n=l(null);for(const[o,r]of e(t)){E(t,o)&&(Array.isArray(r)?n[o]=R(r):r&&"object"==typeof r&&r.constructor===Object?n[o]=w(r):n[o]=r)}return n}function C(e,t){for(;null!==e;){const n=r(e,t);if(n){if(n.get)return b(n.get);if("function"==typeof n.value)return b(n.value)}e=o(e)}return function(){return null}}const L=i(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),D=i(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),v=i(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),O=i(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),x=i(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),k=i(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),M=i(["#text"]),I=i(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),U=i(["accent-height","accumulate","additive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),P=i(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),F=i(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),H=a(/\{\{[\w\W]*|[\w\W]*\}\}/gm),z=a(/<%[\w\W]*|[\w\W]*%>/gm),B=a(/\${[\w\W]*}/gm),W=a(/^data-[\-\w.\u00B7-\uFFFF]/),G=a(/^aria-[\-\w]+$/),Y=a(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),j=a(/^(?:\w+script|data):/i),X=a(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),q=a(/^html$/i),$=a(/^[a-z][.\w]*(-[.\w]+)+$/i);var K=Object.freeze({__proto__:null,MUSTACHE_EXPR:H,ERB_EXPR:z,TMPLIT_EXPR:B,DATA_ATTR:W,ARIA_ATTR:G,IS_ALLOWED_URI:Y,IS_SCRIPT_OR_DATA:j,ATTR_WHITESPACE:X,DOCTYPE_NAME:q,CUSTOM_ELEMENT:$});const V=1,Z=3,J=7,Q=8,ee=9,te=function(){return"undefined"==typeof window?null:window};var ne=function t(){let n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:te();const o=e=>t(e);if(o.version="3.1.6",o.removed=[],!n||!n.document||n.document.nodeType!==ee)return o.isSupported=!1,o;let{document:r}=n;const a=r,c=a.currentScript,{DocumentFragment:s,HTMLTemplateElement:N,Node:b,Element:R,NodeFilter:H,NamedNodeMap:z=n.NamedNodeMap||n.MozNamedAttrMap,HTMLFormElement:B,DOMParser:W,trustedTypes:G}=n,j=R.prototype,X=C(j,"cloneNode"),$=C(j,"remove"),ne=C(j,"nextSibling"),oe=C(j,"childNodes"),re=C(j,"parentNode");if("function"==typeof N){const e=r.createElement("template");e.content&&e.content.ownerDocument&&(r=e.content.ownerDocument)}let ie,ae="";const{implementation:le,createNodeIterator:ce,createDocumentFragment:se,getElementsByTagName:ue}=r,{importNode:me}=a;let pe={};o.isSupported="function"==typeof e&&"function"==typeof re&&le&&void 0!==le.createHTMLDocument;const{MUSTACHE_EXPR:fe,ERB_EXPR:de,TMPLIT_EXPR:he,DATA_ATTR:ge,ARIA_ATTR:Te,IS_SCRIPT_OR_DATA:ye,ATTR_WHITESPACE:Ee,CUSTOM_ELEMENT:_e}=K;let{IS_ALLOWED_URI:Ae}=K,Ne=null;const be=S({},[...L,...D,...v,...x,...M]);let Se=null;const Re=S({},[...I,...U,...P,...F]);let we=Object.seal(l(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Ce=null,Le=null,De=!0,ve=!0,Oe=!1,xe=!0,ke=!1,Me=!0,Ie=!1,Ue=!1,Pe=!1,Fe=!1,He=!1,ze=!1,Be=!0,We=!1,Ge=!0,Ye=!1,je={},Xe=null;const qe=S({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let $e=null;const Ke=S({},["audio","video","img","source","image","track"]);let Ve=null;const Ze=S({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Je="http://www.w3.org/1998/Math/MathML",Qe="http://www.w3.org/2000/svg",et="http://www.w3.org/1999/xhtml";let tt=et,nt=!1,ot=null;const rt=S({},[Je,Qe,et],d);let it=null;const at=["application/xhtml+xml","text/html"];let lt=null,ct=null;const st=r.createElement("form"),ut=function(e){return e instanceof RegExp||e instanceof Function},mt=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!ct||ct!==e){if(e&&"object"==typeof e||(e={}),e=w(e),it=-1===at.indexOf(e.PARSER_MEDIA_TYPE)?"text/html":e.PARSER_MEDIA_TYPE,lt="application/xhtml+xml"===it?d:f,Ne=E(e,"ALLOWED_TAGS")?S({},e.ALLOWED_TAGS,lt):be,Se=E(e,"ALLOWED_ATTR")?S({},e.ALLOWED_ATTR,lt):Re,ot=E(e,"ALLOWED_NAMESPACES")?S({},e.ALLOWED_NAMESPACES,d):rt,Ve=E(e,"ADD_URI_SAFE_ATTR")?S(w(Ze),e.ADD_URI_SAFE_ATTR,lt):Ze,$e=E(e,"ADD_DATA_URI_TAGS")?S(w(Ke),e.ADD_DATA_URI_TAGS,lt):Ke,Xe=E(e,"FORBID_CONTENTS")?S({},e.FORBID_CONTENTS,lt):qe,Ce=E(e,"FORBID_TAGS")?S({},e.FORBID_TAGS,lt):{},Le=E(e,"FORBID_ATTR")?S({},e.FORBID_ATTR,lt):{},je=!!E(e,"USE_PROFILES")&&e.USE_PROFILES,De=!1!==e.ALLOW_ARIA_ATTR,ve=!1!==e.ALLOW_DATA_ATTR,Oe=e.ALLOW_UNKNOWN_PROTOCOLS||!1,xe=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,ke=e.SAFE_FOR_TEMPLATES||!1,Me=!1!==e.SAFE_FOR_XML,Ie=e.WHOLE_DOCUMENT||!1,Fe=e.RETURN_DOM||!1,He=e.RETURN_DOM_FRAGMENT||!1,ze=e.RETURN_TRUSTED_TYPE||!1,Pe=e.FORCE_BODY||!1,Be=!1!==e.SANITIZE_DOM,We=e.SANITIZE_NAMED_PROPS||!1,Ge=!1!==e.KEEP_CONTENT,Ye=e.IN_PLACE||!1,Ae=e.ALLOWED_URI_REGEXP||Y,tt=e.NAMESPACE||et,we=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&ut(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(we.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&ut(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(we.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(we.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),ke&&(ve=!1),He&&(Fe=!0),je&&(Ne=S({},M),Se=[],!0===je.html&&(S(Ne,L),S(Se,I)),!0===je.svg&&(S(Ne,D),S(Se,U),S(Se,F)),!0===je.svgFilters&&(S(Ne,v),S(Se,U),S(Se,F)),!0===je.mathMl&&(S(Ne,x),S(Se,P),S(Se,F))),e.ADD_TAGS&&(Ne===be&&(Ne=w(Ne)),S(Ne,e.ADD_TAGS,lt)),e.ADD_ATTR&&(Se===Re&&(Se=w(Se)),S(Se,e.ADD_ATTR,lt)),e.ADD_URI_SAFE_ATTR&&S(Ve,e.ADD_URI_SAFE_ATTR,lt),e.FORBID_CONTENTS&&(Xe===qe&&(Xe=w(Xe)),S(Xe,e.FORBID_CONTENTS,lt)),Ge&&(Ne["#text"]=!0),Ie&&S(Ne,["html","head","body"]),Ne.table&&(S(Ne,["tbody"]),delete Ce.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw A('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw A('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');ie=e.TRUSTED_TYPES_POLICY,ae=ie.createHTML("")}else void 0===ie&&(ie=function(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let n=null;const o="data-tt-policy-suffix";t&&t.hasAttribute(o)&&(n=t.getAttribute(o));const r="dompurify"+(n?"#"+n:"");try{return e.createPolicy(r,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+r+" could not be created."),null}}(G,c)),null!==ie&&"string"==typeof ae&&(ae=ie.createHTML(""));i&&i(e),ct=e}},pt=S({},["mi","mo","mn","ms","mtext"]),ft=S({},["foreignobject","annotation-xml"]),dt=S({},["title","style","font","a","script"]),ht=S({},[...D,...v,...O]),gt=S({},[...x,...k]),Tt=function(e){p(o.removed,{element:e});try{re(e).removeChild(e)}catch(t){$(e)}},yt=function(e,t){try{p(o.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){p(o.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e&&!Se[e])if(Fe||He)try{Tt(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},Et=function(e){let t=null,n=null;if(Pe)e="<remove></remove>"+e;else{const t=h(e,/^[\r\n\t ]+/);n=t&&t[0]}"application/xhtml+xml"===it&&tt===et&&(e='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+e+"</body></html>");const o=ie?ie.createHTML(e):e;if(tt===et)try{t=(new W).parseFromString(o,it)}catch(e){}if(!t||!t.documentElement){t=le.createDocument(tt,"template",null);try{t.documentElement.innerHTML=nt?ae:o}catch(e){}}const i=t.body||t.documentElement;return e&&n&&i.insertBefore(r.createTextNode(n),i.childNodes[0]||null),tt===et?ue.call(t,Ie?"html":"body")[0]:Ie?t.documentElement:i},_t=function(e){return ce.call(e.ownerDocument||e,e,H.SHOW_ELEMENT|H.SHOW_COMMENT|H.SHOW_TEXT|H.SHOW_PROCESSING_INSTRUCTION|H.SHOW_CDATA_SECTION,null)},At=function(e){return e instanceof B&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof z)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes)},Nt=function(e){return"function"==typeof b&&e instanceof b},bt=function(e,t,n){pe[e]&&u(pe[e],(e=>{e.call(o,t,n,ct)}))},St=function(e){let t=null;if(bt("beforeSanitizeElements",e,null),At(e))return Tt(e),!0;const n=lt(e.nodeName);if(bt("uponSanitizeElement",e,{tagName:n,allowedTags:Ne}),e.hasChildNodes()&&!Nt(e.firstElementChild)&&_(/<[/\w]/g,e.innerHTML)&&_(/<[/\w]/g,e.textContent))return Tt(e),!0;if(e.nodeType===J)return Tt(e),!0;if(Me&&e.nodeType===Q&&_(/<[/\w]/g,e.data))return Tt(e),!0;if(!Ne[n]||Ce[n]){if(!Ce[n]&&wt(n)){if(we.tagNameCheck instanceof RegExp&&_(we.tagNameCheck,n))return!1;if(we.tagNameCheck instanceof Function&&we.tagNameCheck(n))return!1}if(Ge&&!Xe[n]){const t=re(e)||e.parentNode,n=oe(e)||e.childNodes;if(n&&t){for(let o=n.length-1;o>=0;--o){const r=X(n[o],!0);r.__removalCount=(e.__removalCount||0)+1,t.insertBefore(r,ne(e))}}}return Tt(e),!0}return e instanceof R&&!function(e){let t=re(e);t&&t.tagName||(t={namespaceURI:tt,tagName:"template"});const n=f(e.tagName),o=f(t.tagName);return!!ot[e.namespaceURI]&&(e.namespaceURI===Qe?t.namespaceURI===et?"svg"===n:t.namespaceURI===Je?"svg"===n&&("annotation-xml"===o||pt[o]):Boolean(ht[n]):e.namespaceURI===Je?t.namespaceURI===et?"math"===n:t.namespaceURI===Qe?"math"===n&&ft[o]:Boolean(gt[n]):e.namespaceURI===et?!(t.namespaceURI===Qe&&!ft[o])&&!(t.namespaceURI===Je&&!pt[o])&&!gt[n]&&(dt[n]||!ht[n]):!("application/xhtml+xml"!==it||!ot[e.namespaceURI]))}(e)?(Tt(e),!0):"noscript"!==n&&"noembed"!==n&&"noframes"!==n||!_(/<\/no(script|embed|frames)/i,e.innerHTML)?(ke&&e.nodeType===Z&&(t=e.textContent,u([fe,de,he],(e=>{t=g(t,e," ")})),e.textContent!==t&&(p(o.removed,{element:e.cloneNode()}),e.textContent=t)),bt("afterSanitizeElements",e,null),!1):(Tt(e),!0)},Rt=function(e,t,n){if(Be&&("id"===t||"name"===t)&&(n in r||n in st))return!1;if(ve&&!Le[t]&&_(ge,t));else if(De&&_(Te,t));else if(!Se[t]||Le[t]){if(!(wt(e)&&(we.tagNameCheck instanceof RegExp&&_(we.tagNameCheck,e)||we.tagNameCheck instanceof Function&&we.tagNameCheck(e))&&(we.attributeNameCheck instanceof RegExp&&_(we.attributeNameCheck,t)||we.attributeNameCheck instanceof Function&&we.attributeNameCheck(t))||"is"===t&&we.allowCustomizedBuiltInElements&&(we.tagNameCheck instanceof RegExp&&_(we.tagNameCheck,n)||we.tagNameCheck instanceof Function&&we.tagNameCheck(n))))return!1}else if(Ve[t]);else if(_(Ae,g(n,Ee,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==T(n,"data:")||!$e[e]){if(Oe&&!_(ye,g(n,Ee,"")));else if(n)return!1}else;return!0},wt=function(e){return"annotation-xml"!==e&&h(e,_e)},Ct=function(e){bt("beforeSanitizeAttributes",e,null);const{attributes:t}=e;if(!t)return;const n={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Se};let r=t.length;for(;r--;){const i=t[r],{name:a,namespaceURI:l,value:c}=i,s=lt(a);let p="value"===a?c:y(c);if(n.attrName=s,n.attrValue=p,n.keepAttr=!0,n.forceKeepAttr=void 0,bt("uponSanitizeAttribute",e,n),p=n.attrValue,Me&&_(/((--!?|])>)|<\/(style|title)/i,p)){yt(a,e);continue}if(n.forceKeepAttr)continue;if(yt(a,e),!n.keepAttr)continue;if(!xe&&_(/\/>/i,p)){yt(a,e);continue}ke&&u([fe,de,he],(e=>{p=g(p,e," ")}));const f=lt(e.nodeName);if(Rt(f,s,p)){if(!We||"id"!==s&&"name"!==s||(yt(a,e),p="user-content-"+p),ie&&"object"==typeof G&&"function"==typeof G.getAttributeType)if(l);else switch(G.getAttributeType(f,s)){case"TrustedHTML":p=ie.createHTML(p);break;case"TrustedScriptURL":p=ie.createScriptURL(p)}try{l?e.setAttributeNS(l,a,p):e.setAttribute(a,p),At(e)?Tt(e):m(o.removed)}catch(e){}}}bt("afterSanitizeAttributes",e,null)},Lt=function e(t){let n=null;const o=_t(t);for(bt("beforeSanitizeShadowDOM",t,null);n=o.nextNode();)bt("uponSanitizeShadowNode",n,null),St(n)||(n.content instanceof s&&e(n.content),Ct(n));bt("afterSanitizeShadowDOM",t,null)};return o.sanitize=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=null,r=null,i=null,l=null;if(nt=!e,nt&&(e="\x3c!--\x3e"),"string"!=typeof e&&!Nt(e)){if("function"!=typeof e.toString)throw A("toString is not a function");if("string"!=typeof(e=e.toString()))throw A("dirty is not a string, aborting")}if(!o.isSupported)return e;if(Ue||mt(t),o.removed=[],"string"==typeof e&&(Ye=!1),Ye){if(e.nodeName){const t=lt(e.nodeName);if(!Ne[t]||Ce[t])throw A("root node is forbidden and cannot be sanitized in-place")}}else if(e instanceof b)n=Et("\x3c!----\x3e"),r=n.ownerDocument.importNode(e,!0),r.nodeType===V&&"BODY"===r.nodeName||"HTML"===r.nodeName?n=r:n.appendChild(r);else{if(!Fe&&!ke&&!Ie&&-1===e.indexOf("<"))return ie&&ze?ie.createHTML(e):e;if(n=Et(e),!n)return Fe?null:ze?ae:""}n&&Pe&&Tt(n.firstChild);const c=_t(Ye?e:n);for(;i=c.nextNode();)St(i)||(i.content instanceof s&&Lt(i.content),Ct(i));if(Ye)return e;if(Fe){if(He)for(l=se.call(n.ownerDocument);n.firstChild;)l.appendChild(n.firstChild);else l=n;return(Se.shadowroot||Se.shadowrootmode)&&(l=me.call(a,l,!0)),l}let m=Ie?n.outerHTML:n.innerHTML;return Ie&&Ne["!doctype"]&&n.ownerDocument&&n.ownerDocument.doctype&&n.ownerDocument.doctype.name&&_(q,n.ownerDocument.doctype.name)&&(m="<!DOCTYPE "+n.ownerDocument.doctype.name+">\n"+m),ke&&u([fe,de,he],(e=>{m=g(m,e," ")})),ie&&ze?ie.createHTML(m):m},o.setConfig=function(){mt(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),Ue=!0},o.clearConfig=function(){ct=null,Ue=!1},o.isValidAttribute=function(e,t,n){ct||mt({});const o=lt(e),r=lt(t);return Rt(o,r,n)},o.addHook=function(e,t){"function"==typeof t&&(pe[e]=pe[e]||[],p(pe[e],t))},o.removeHook=function(e){if(pe[e])return m(pe[e])},o.removeHooks=function(e){pe[e]&&(pe[e]=[])},o.removeAllHooks=function(){pe={}},o}();return ne}));
|
|
3
|
+
//# sourceMappingURL=purify.min.js.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/* ================================================================
|
|
2
|
+
* 00-storage.js
|
|
3
|
+
* localStorage / sessionStorage 集中封装。
|
|
4
|
+
*
|
|
5
|
+
* 历史:localStorage key 字符串散落在 8+ 个文件共 30+ 处,try/catch
|
|
6
|
+
* 防护重复 ~30 次。重命名风险高。
|
|
7
|
+
*
|
|
8
|
+
* 本文件:
|
|
9
|
+
* 1) STORAGE_KEYS — 唯一 key 来源(按用途分组)
|
|
10
|
+
* 2) getLS/setLS/removeLS/tryGetLS/trySetLS — 集中 try/catch
|
|
11
|
+
* (getLS 返回 null 表示 key 缺失或 quota 等异常,不再抛)
|
|
12
|
+
*
|
|
13
|
+
* 按字母序:00-storage.js 排在 00-utils.js 之前。
|
|
14
|
+
* ('00-storage' < '00-utils':'-' ASCII 45 < 'u' ASCII 117)
|
|
15
|
+
* ================================================================ */
|
|
16
|
+
|
|
17
|
+
/** 所有 storage key 的单一来源。 */
|
|
18
|
+
const STORAGE_KEYS = Object.freeze({
|
|
19
|
+
// ── 思考 / 推理 ──
|
|
20
|
+
ENABLE_THINKING: 'oa_enable_thinking',
|
|
21
|
+
REASONING_EFFORT: 'oa_reasoning_effort',
|
|
22
|
+
// ── 会话身份 ──
|
|
23
|
+
SESS_LAST_READ: 'oa_sess_last_read_v2',
|
|
24
|
+
SESS_COMPLETED: 'oaSessionCompletedMap',
|
|
25
|
+
SESS_CLEARED: 'oaSessionClearedMap',
|
|
26
|
+
SESS_ACTIVE_PAGE: 'oa_active_page',
|
|
27
|
+
SESS_ACTIVITY_MODE: 'oa_activity_mode',
|
|
28
|
+
// ── 模型选择(旧 fallback) ──
|
|
29
|
+
LLM_PRESET_ID: 'oa_llm_preset_id',
|
|
30
|
+
// ── 一次性 flag ──
|
|
31
|
+
SETUP_GREETED: 'oa_setup_greeted',
|
|
32
|
+
// ── 面板显隐 ──
|
|
33
|
+
TODO_PANEL_OPEN: 'oa_todo_panel_open',
|
|
34
|
+
PLAN_PANEL_OPEN: 'oa_plan_panel_open',
|
|
35
|
+
GIT_PANEL_OPEN: 'oa_git_panel_open',
|
|
36
|
+
// ── Todo 列表 scope ──
|
|
37
|
+
TODO_SCOPE: 'oa_todo_scope',
|
|
38
|
+
// ── WS 凭据(sessionStorage) ──
|
|
39
|
+
WS_TOKEN: 'oa_webui_ws_token',
|
|
40
|
+
// ── 输入草稿 ──
|
|
41
|
+
SESS_DRAFT_PREFIX: 'oa_sess_draft_',
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
/** 动态 key 构造器(agent/session 作用域)。 */
|
|
45
|
+
function sidStorageKey(aid, pid) {
|
|
46
|
+
// 历史:oa_sid_v5_<aid>_<pid>,_pid 部分做尾部归一化(空/null/legacy)
|
|
47
|
+
const a = String(aid || 'default');
|
|
48
|
+
const p = String(pid == null ? '' : pid).trim();
|
|
49
|
+
return 'oa_sid_v5_' + a + (p ? '_' + p : '');
|
|
50
|
+
}
|
|
51
|
+
function projectStorageKey(aid) {
|
|
52
|
+
return 'oa_proj_' + String(aid || 'default');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** 读取:异常或缺失 → fallback(默认 '')。 */
|
|
56
|
+
function tryGetLS(key, fallback) {
|
|
57
|
+
try { return localStorage.getItem(key) || fallback || ''; }
|
|
58
|
+
catch (_) { return fallback || ''; }
|
|
59
|
+
}
|
|
60
|
+
/** 写入:quota 满等异常静默吞掉。 */
|
|
61
|
+
function trySetLS(key, val) {
|
|
62
|
+
try { localStorage.setItem(key, String(val == null ? '' : val)); return true; }
|
|
63
|
+
catch (_) { return false; }
|
|
64
|
+
}
|
|
65
|
+
/** 删除:缺失也安全。 */
|
|
66
|
+
function tryRemoveLS(key) {
|
|
67
|
+
try { localStorage.removeItem(key); return true; }
|
|
68
|
+
catch (_) { return false; }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** 同上但走 sessionStorage(WS token 等短生命周期)。 */
|
|
72
|
+
function tryGetSS(key, fallback) {
|
|
73
|
+
try { return sessionStorage.getItem(key) || fallback || ''; }
|
|
74
|
+
catch (_) { return fallback || ''; }
|
|
75
|
+
}
|
|
76
|
+
function trySetSS(key, val) {
|
|
77
|
+
try { sessionStorage.setItem(key, String(val == null ? '' : val)); return true; }
|
|
78
|
+
catch (_) { return false; }
|
|
79
|
+
}
|
|
80
|
+
function tryRemoveSS(key) {
|
|
81
|
+
try { sessionStorage.removeItem(key); return true; }
|
|
82
|
+
catch (_) { return false; }
|
|
83
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* ================================================================
|
|
2
|
+
* 00-utils.js
|
|
3
|
+
* 共享工具函数(顶层声明,字母序下排在所有文件最前)。
|
|
4
|
+
*
|
|
5
|
+
* 本文件必须先于其他 JS 加载(按字母序自动满足:00-* 排第一位)。
|
|
6
|
+
* 各 *.js 文件直接调用 escapeHtml/escAttr,无需 import。
|
|
7
|
+
* (拼装式 SPA 的约定,不走 ES module。)
|
|
8
|
+
*
|
|
9
|
+
* 历史上散落在 5 个文件中的 6 个 escape 函数实现已统一:
|
|
10
|
+
* - 01c-session.js:802 escapeHtml → 4 字符 &<>"
|
|
11
|
+
* - 01c-session.js:805 escAttr → 4 字符 &"<>(与 body 顺序不同)
|
|
12
|
+
* - 08d-editor.js:73 escapeHtml → DOM textContent 反射(5 字符 &<>"')
|
|
13
|
+
* - 09f-remote.js:72 escapeHtml → DOM textContent 反射(5 字符 &<>"')
|
|
14
|
+
* - 09f-remote.js:76 escapeHtmlAttr→ 2 字符 "'(仅属性场景)
|
|
15
|
+
* - 11g-env-paths-git.js:3 escHtml → 4 字符 &<>"
|
|
16
|
+
*
|
|
17
|
+
* 不一致导致 11g 的路径含 ' 时不转义、escAttr 不处理 ' 是真 XSS 风险。
|
|
18
|
+
* 现统一为 2 个函数,均 5 字符 &<>"':
|
|
19
|
+
* - escapeHtml(s) HTML body 文本
|
|
20
|
+
* - escAttr(s) HTML 属性值(语义与 body 相同,但语义明确 + 5 字符)
|
|
21
|
+
* ================================================================ */
|
|
22
|
+
|
|
23
|
+
/** HTML 文本/属性通用转义。5 字符 &<>"' 全覆盖。 */
|
|
24
|
+
function escapeHtml(s) {
|
|
25
|
+
return String(s == null ? '' : s)
|
|
26
|
+
.replace(/&/g, '&')
|
|
27
|
+
.replace(/</g, '<')
|
|
28
|
+
.replace(/>/g, '>')
|
|
29
|
+
.replace(/"/g, '"')
|
|
30
|
+
.replace(/'/g, ''');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** HTML 属性值转义。与 escapeHtml 同语义,独立命名以强调使用场景。 */
|
|
34
|
+
function escAttr(s) {
|
|
35
|
+
return escapeHtml(s);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* API 路径包装。目前直接返回原路径,未来可在此追加 base URL 或前缀。
|
|
40
|
+
* 新模块统一用此函数而非裸 fetch(path),避免后续改 base URL 时到处改。
|
|
41
|
+
*/
|
|
42
|
+
function apiUrl(path) {
|
|
43
|
+
return path;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* escHtml — escapeHtml 的简短别名。多模块使用,与 escapeHtml 完全等价。
|
|
48
|
+
*/
|
|
49
|
+
function escHtml(s) {
|
|
50
|
+
return escapeHtml(s);
|
|
51
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/* ================================================================
|
|
2
|
+
* 01-theme.css — CSS custom properties, light/dark theme, resets
|
|
3
|
+
* ================================================================ */
|
|
4
|
+
|
|
5
|
+
:root {
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
|
|
8
|
+
/* Spacing scale (4px base) */
|
|
9
|
+
--sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
|
|
10
|
+
--sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px; --sp-12: 48px;
|
|
11
|
+
|
|
12
|
+
/* Radii */
|
|
13
|
+
--r-xs: 4px; --r-sm: 6px; --r-md: 8px; --r-lg: 10px;
|
|
14
|
+
--r-xl: 14px; --r-2xl: 18px; --r-full: 9999px;
|
|
15
|
+
|
|
16
|
+
/* Typography */
|
|
17
|
+
--font-sans: "Inter", "Segoe UI Variable", system-ui, -apple-system, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", "Helvetica Neue", sans-serif;
|
|
18
|
+
--font-mono: "JetBrains Mono", "SF Mono", ui-monospace, "Cascadia Code", Consolas, monospace;
|
|
19
|
+
|
|
20
|
+
/* Layout */
|
|
21
|
+
--activity-bar-w: 48px;
|
|
22
|
+
--sidebar-w: 272px;
|
|
23
|
+
--topbar-h: 56px;
|
|
24
|
+
|
|
25
|
+
/* Light theme */
|
|
26
|
+
--bg: #fbfbfc;
|
|
27
|
+
--bg-panel: #ffffff;
|
|
28
|
+
--bg-subtle: #f5f5f7;
|
|
29
|
+
--bg-hover: #eeeef1;
|
|
30
|
+
--bg-chat: #fafafb;
|
|
31
|
+
--border: #e6e6ea;
|
|
32
|
+
--border-strong: #d4d4d8;
|
|
33
|
+
--divider: #eeeef1;
|
|
34
|
+
--text: #18181b;
|
|
35
|
+
--text-secondary: #3f3f46;
|
|
36
|
+
--text-muted: #71717a;
|
|
37
|
+
--text-subtle: #a1a1aa;
|
|
38
|
+
--accent: #4f46e5;
|
|
39
|
+
--accent-hover: #4338ca;
|
|
40
|
+
--accent-soft: rgba(79, 70, 229, 0.09);
|
|
41
|
+
--accent-softer: rgba(79, 70, 229, 0.04);
|
|
42
|
+
--accent-ring: rgba(79, 70, 229, 0.22);
|
|
43
|
+
--danger: #dc2626;
|
|
44
|
+
--danger-soft: rgba(220, 38, 38, 0.10);
|
|
45
|
+
--success: #16a34a;
|
|
46
|
+
--shadow-xs: 0 1px 2px rgba(16, 24, 40, 0.04);
|
|
47
|
+
--shadow-sm: 0 1px 3px rgba(16, 24, 40, 0.06), 0 1px 2px rgba(16, 24, 40, 0.04);
|
|
48
|
+
--shadow-md: 0 6px 16px -4px rgba(16, 24, 40, 0.08), 0 2px 4px -2px rgba(16, 24, 40, 0.04);
|
|
49
|
+
--shadow-lg: 0 18px 36px -10px rgba(16, 24, 40, 0.12), 0 4px 10px -4px rgba(16, 24, 40, 0.05);
|
|
50
|
+
--shadow-focus: 0 0 0 3px var(--accent-ring);
|
|
51
|
+
|
|
52
|
+
--bubble-user-bg: linear-gradient(140deg, #4f46e5 0%, #4338ca 100%);
|
|
53
|
+
--bubble-user-text: #ffffff;
|
|
54
|
+
--bubble-agent-bg: #ffffff;
|
|
55
|
+
--bubble-agent-border: #e8e8ec;
|
|
56
|
+
--todo-in-progress-bg: #fef3c7;
|
|
57
|
+
--todo-in-progress-text: #d97706;
|
|
58
|
+
--todo-completed-bg: #d1fae5;
|
|
59
|
+
--todo-completed-text: #059669;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@media (prefers-color-scheme: dark) {
|
|
63
|
+
:root {
|
|
64
|
+
--bg: #0a0a0b;
|
|
65
|
+
--bg-panel: #111113;
|
|
66
|
+
--bg-subtle: #161618;
|
|
67
|
+
--bg-hover: rgba(255,255,255,0.05);
|
|
68
|
+
--bg-chat: #0c0c0e;
|
|
69
|
+
--border: rgba(255,255,255,0.08);
|
|
70
|
+
--border-strong: rgba(255,255,255,0.14);
|
|
71
|
+
--divider: rgba(255,255,255,0.06);
|
|
72
|
+
--text: #f4f4f5;
|
|
73
|
+
--text-secondary: #d4d4d8;
|
|
74
|
+
--text-muted: #a1a1aa;
|
|
75
|
+
--text-subtle: #71717a;
|
|
76
|
+
--accent: #a5b4fc;
|
|
77
|
+
--accent-hover: #c7d2fe;
|
|
78
|
+
--accent-soft: rgba(129, 140, 248, 0.16);
|
|
79
|
+
--accent-softer: rgba(129, 140, 248, 0.06);
|
|
80
|
+
--accent-ring: rgba(129, 140, 248, 0.35);
|
|
81
|
+
--danger: #f87171;
|
|
82
|
+
--danger-soft: rgba(248, 113, 113, 0.14);
|
|
83
|
+
--shadow-xs: 0 1px 2px rgba(0,0,0,0.35);
|
|
84
|
+
--shadow-sm: 0 1px 3px rgba(0,0,0,0.4);
|
|
85
|
+
--shadow-md: 0 8px 20px -6px rgba(0,0,0,0.5);
|
|
86
|
+
--shadow-lg: 0 24px 48px -14px rgba(0,0,0,0.6);
|
|
87
|
+
--bubble-user-bg: linear-gradient(140deg, #6366f1 0%, #4f46e5 100%);
|
|
88
|
+
--bubble-user-text: #ffffff;
|
|
89
|
+
--bubble-agent-bg: #17171a;
|
|
90
|
+
--bubble-agent-border: rgba(255,255,255,0.08);
|
|
91
|
+
--todo-in-progress-bg: rgba(217, 119, 6, 0.2);
|
|
92
|
+
--todo-in-progress-text: #fbbf24;
|
|
93
|
+
--todo-completed-bg: rgba(5, 150, 105, 0.2);
|
|
94
|
+
--todo-completed-text: #34d399;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/* ================================================================
|
|
2
|
+
* 01-core.js
|
|
3
|
+
* - DOM refs (log, msg, send, stop, thinkToggle, modelSelect)
|
|
4
|
+
* - Model selection persistence (localStorage)
|
|
5
|
+
* - Thinking toggle persistence
|
|
6
|
+
* - Session/agent identity (sessionId, projectId, agentId)
|
|
7
|
+
* - Core utility functions (escapeHtml, normReply, scrollLog, ...)
|
|
8
|
+
* - Chat inflight tracking (chatInflightBySid)
|
|
9
|
+
* - Refresh projects list
|
|
10
|
+
* ================================================================ */
|
|
11
|
+
|
|
12
|
+
const log = document.getElementById('log');
|
|
13
|
+
const msg = document.getElementById('msg');
|
|
14
|
+
const sendBtn = document.getElementById('send');
|
|
15
|
+
const stopBtn = document.getElementById('stop');
|
|
16
|
+
const thinkToggle = document.getElementById('thinkToggle');
|
|
17
|
+
const reasoningEffortSelect = document.getElementById('reasoningEffortSelect');
|
|
18
|
+
const modelSelect = document.getElementById('modelSelect');
|
|
19
|
+
|
|
20
|
+
// ── Smart auto-scroll (don't pull user away from history) ──────────────
|
|
21
|
+
let _userNearBottom = true;
|
|
22
|
+
const _SCROLL_THRESHOLD = 120; // px from bottom → "near bottom"
|
|
23
|
+
|
|
24
|
+
function scrollLog() {
|
|
25
|
+
if (_userNearBottom && log) {
|
|
26
|
+
log.scrollTop = log.scrollHeight;
|
|
27
|
+
} else if (log) {
|
|
28
|
+
// User scrolled away from bottom → show "new messages" hint
|
|
29
|
+
_showNewMsgBtn();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Force scroll to bottom regardless of user position (e.g. new message sent). */
|
|
33
|
+
function scrollLogForce() {
|
|
34
|
+
if (!log) return;
|
|
35
|
+
_userNearBottom = true;
|
|
36
|
+
log.scrollTop = log.scrollHeight;
|
|
37
|
+
_hideNewMsgBtn();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ── New message floating button ───────────────────────────────────────
|
|
41
|
+
let _newContentPending = false;
|
|
42
|
+
const _newMsgBtn = document.getElementById('btnNewMessages');
|
|
43
|
+
|
|
44
|
+
function _updateNewMsgBtn() {
|
|
45
|
+
if (!_newMsgBtn) return;
|
|
46
|
+
if (!_userNearBottom && _newContentPending) {
|
|
47
|
+
_newMsgBtn.style.display = 'inline-flex';
|
|
48
|
+
} else {
|
|
49
|
+
_newMsgBtn.style.display = 'none';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function _showNewMsgBtn() {
|
|
53
|
+
_newContentPending = true;
|
|
54
|
+
_updateNewMsgBtn();
|
|
55
|
+
}
|
|
56
|
+
function _hideNewMsgBtn() {
|
|
57
|
+
_newContentPending = false;
|
|
58
|
+
_updateNewMsgBtn();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Wire scroll detection to update button
|
|
62
|
+
let _scrollDetectTimer = null;
|
|
63
|
+
function _initScrollDetection() {
|
|
64
|
+
if (!log || log.dataset.scrollDetect === '1') return;
|
|
65
|
+
log.dataset.scrollDetect = '1';
|
|
66
|
+
log.addEventListener('scroll', () => {
|
|
67
|
+
// 节流到 ~80ms:scroll 事件可能每帧多次触发,没必要每次都重算
|
|
68
|
+
if (_scrollDetectTimer) return;
|
|
69
|
+
_scrollDetectTimer = setTimeout(() => {
|
|
70
|
+
_scrollDetectTimer = null;
|
|
71
|
+
const dist = log.scrollHeight - log.scrollTop - log.clientHeight;
|
|
72
|
+
_userNearBottom = dist <= _SCROLL_THRESHOLD;
|
|
73
|
+
_updateNewMsgBtn();
|
|
74
|
+
}, 80);
|
|
75
|
+
}, { passive: true });
|
|
76
|
+
}
|
|
77
|
+
_initScrollDetection();
|
|
78
|
+
|
|
79
|
+
// Click handler: scroll to bottom on button click
|
|
80
|
+
if (_newMsgBtn) {
|
|
81
|
+
_newMsgBtn.addEventListener('click', () => {
|
|
82
|
+
scrollLogForce();
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ---------------- Model selection persistence ----------------
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
|
|
2
|
+
/* Chat main LLM selector — now per-session (delegates to ModelStackState) */
|
|
3
|
+
|
|
4
|
+
function getSelectedModel() {
|
|
5
|
+
// 1) session override, 2) global default, 3) empty
|
|
6
|
+
if (window.ModelStackState) return window.ModelStackState.getEffectiveModel('llm');
|
|
7
|
+
return tryGetLS(STORAGE_KEYS.LLM_PRESET_ID, '');
|
|
8
|
+
}
|
|
9
|
+
function setSelectedModel(val) {
|
|
10
|
+
if (window.ModelStackState) {
|
|
11
|
+
if (val && val !== '__default__') {
|
|
12
|
+
window.ModelStackState.setSessionOverride('llm', val);
|
|
13
|
+
window.ModelStackState.schedulePersistToBackend();
|
|
14
|
+
} else {
|
|
15
|
+
window.ModelStackState.clearSessionOverride('llm');
|
|
16
|
+
window.ModelStackState.schedulePersistToBackend();
|
|
17
|
+
}
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
trySetLS(STORAGE_KEYS.LLM_PRESET_ID, String(val || '').trim());
|
|
21
|
+
}
|
|
22
|
+
async function refreshModelSelect() {
|
|
23
|
+
if (!modelSelect) return;
|
|
24
|
+
// Effective value (session override → global default → empty)
|
|
25
|
+
const cur = getSelectedModel();
|
|
26
|
+
try {
|
|
27
|
+
const r = await fetch('/api/ui/llm/presets');
|
|
28
|
+
if (!r.ok) return;
|
|
29
|
+
const j = await r.json();
|
|
30
|
+
const presets = (j.presets || []).filter(function(p) {
|
|
31
|
+
return inferPresetUseType(p) === 'chat';
|
|
32
|
+
});
|
|
33
|
+
const defaultId = j.default_id || '';
|
|
34
|
+
modelSelect.innerHTML = '<option value="__default__">默认模型</option>';
|
|
35
|
+
presets.forEach(function(p) {
|
|
36
|
+
const o = document.createElement('option');
|
|
37
|
+
o.value = p.id || '';
|
|
38
|
+
const isDef = p.id === defaultId;
|
|
39
|
+
const shortLabel = (typeof presetComposeLabel === 'function')
|
|
40
|
+
? presetComposeLabel(p, { isDefault: isDef })
|
|
41
|
+
: (p.model || p.name || p.id);
|
|
42
|
+
o.textContent = shortLabel;
|
|
43
|
+
o.title = (typeof presetOptionDetail === 'function') ? presetOptionDetail(p) : shortLabel;
|
|
44
|
+
modelSelect.appendChild(o);
|
|
45
|
+
});
|
|
46
|
+
if (cur && cur !== '__default__' && presets.some(function(p) { return p.id === cur; })) {
|
|
47
|
+
modelSelect.value = cur;
|
|
48
|
+
} else if (defaultId && presets.some(function(p) { return p.id === defaultId; })) {
|
|
49
|
+
modelSelect.value = defaultId;
|
|
50
|
+
} else {
|
|
51
|
+
modelSelect.value = '__default__';
|
|
52
|
+
}
|
|
53
|
+
if (typeof updateComposeModelPill === 'function') updateComposeModelPill();
|
|
54
|
+
} catch (_) {}
|
|
55
|
+
}
|
|
56
|
+
const refreshChatModelSelect = refreshModelSelect;
|
|
57
|
+
modelSelect && modelSelect.addEventListener('change', function() {
|
|
58
|
+
setSelectedModel(modelSelect.value);
|
|
59
|
+
if (typeof updateComposeModelPill === 'function') updateComposeModelPill();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// ---------------- Thinking toggle persistence ----------------
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/* ================================================================
|
|
2
|
+
* 01c-session-identity.js
|
|
3
|
+
* Session/agent identity:当前 agentId / projectId / sessionId 三元组
|
|
4
|
+
* 的状态、localStorage 持久化、URL/project 查询参数构造。
|
|
5
|
+
*
|
|
6
|
+
* 依赖 00-storage.js (STORAGE_KEYS)。
|
|
7
|
+
* 顶层声明顺序:先 helper function(被 loadXxx 引用),再状态变量。
|
|
8
|
+
* 实际加载靠 var/function hoisting 跨文件安全。
|
|
9
|
+
* ================================================================ */
|
|
10
|
+
|
|
11
|
+
const READ_KEY = STORAGE_KEYS.SESS_LAST_READ;
|
|
12
|
+
let lastSessionsCache = [];
|
|
13
|
+
let webuiSessionsEnabled = false;
|
|
14
|
+
var agentId = 'default';
|
|
15
|
+
|
|
16
|
+
/** RFC4122 v4;在 HTTP 或非 Chromium 旧版等环境下 crypto.randomUUID 可能不存在。 */
|
|
17
|
+
function oaRandomUUID() {
|
|
18
|
+
try {
|
|
19
|
+
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
|
20
|
+
return crypto.randomUUID();
|
|
21
|
+
}
|
|
22
|
+
} catch (_) {}
|
|
23
|
+
// Math.random fallback:拼 v4 格式(4/-/位标志位)
|
|
24
|
+
var bytes = new Array(16);
|
|
25
|
+
for (var i = 0; i < 16; i++) bytes[i] = (Math.random() * 256) | 0;
|
|
26
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4
|
|
27
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 10
|
|
28
|
+
var hex = '';
|
|
29
|
+
for (var j = 0; j < 16; j++) hex += (bytes[j] + 0x100).toString(16).slice(1);
|
|
30
|
+
return (
|
|
31
|
+
hex.slice(0, 8) + '-' +
|
|
32
|
+
hex.slice(8, 12) + '-' +
|
|
33
|
+
hex.slice(12, 16) + '-' +
|
|
34
|
+
hex.slice(16, 20) + '-' +
|
|
35
|
+
hex.slice(20)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function projectStorageKey(aid) {
|
|
40
|
+
return 'oa_proj_' + String(aid || 'default');
|
|
41
|
+
}
|
|
42
|
+
function loadProjectIdForAgent(aid) {
|
|
43
|
+
try { return localStorage.getItem(projectStorageKey(aid)) || ''; } catch (_) { return ''; }
|
|
44
|
+
}
|
|
45
|
+
function saveProjectIdForAgent(aid, pid) {
|
|
46
|
+
try { localStorage.setItem(projectStorageKey(aid), String(pid || '').trim()); } catch (_) {}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let projectId = loadProjectIdForAgent(agentId);
|
|
50
|
+
|
|
51
|
+
let historyFirstBlockIndex = null;
|
|
52
|
+
let historyHasMoreOlder = false;
|
|
53
|
+
let historyLoadingOlder = false;
|
|
54
|
+
let historyScrollTimer = null;
|
|
55
|
+
let historyPagingBound = false;
|
|
56
|
+
|
|
57
|
+
function _sidStorageKey(aid, pid) {
|
|
58
|
+
const a = String(aid || 'default');
|
|
59
|
+
const p = String(pid == null ? '' : pid).trim();
|
|
60
|
+
return 'oa_sid_v5_' + a + (p ? '_' + p : '');
|
|
61
|
+
}
|
|
62
|
+
function loadSessionIdForAgent(aid, pid) {
|
|
63
|
+
const p = String(pid || '').trim();
|
|
64
|
+
const key = _sidStorageKey(aid, p);
|
|
65
|
+
let sid = localStorage.getItem(key) || '';
|
|
66
|
+
if (!sid && !p) {
|
|
67
|
+
const legacy = localStorage.getItem('oa_sid_' + String(aid || 'default')) || '';
|
|
68
|
+
if (legacy) { sid = legacy; localStorage.setItem(key, sid); }
|
|
69
|
+
}
|
|
70
|
+
if (!sid) { sid = oaRandomUUID(); localStorage.setItem(key, sid); }
|
|
71
|
+
return sid;
|
|
72
|
+
}
|
|
73
|
+
function saveSessionIdForAgent(aid, pid, sid) {
|
|
74
|
+
try {
|
|
75
|
+
localStorage.setItem(_sidStorageKey(aid, pid), String(sid || '').trim());
|
|
76
|
+
} catch (_) {}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function projectQuerySuffix() {
|
|
80
|
+
return '&project_id=' + encodeURIComponent(projectId || '');
|
|
81
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* ================================================================
|
|
2
|
+
* 01c-session-thinking.js
|
|
3
|
+
* 思考模式 + 推理强度(DeepSeek 思考模式等)的持久化与 UI 同步。
|
|
4
|
+
* 依赖:00-storage.js (STORAGE_KEYS)。
|
|
5
|
+
* 依赖全局 DOM 元素:thinkToggle, reasoningEffortSelect(在 body.html 顶部)。
|
|
6
|
+
* ================================================================ */
|
|
7
|
+
|
|
8
|
+
const THINK_KEY = STORAGE_KEYS.ENABLE_THINKING;
|
|
9
|
+
const REASONING_EFFORT_KEY = STORAGE_KEYS.REASONING_EFFORT;
|
|
10
|
+
|
|
11
|
+
function getThinkState() {
|
|
12
|
+
try {
|
|
13
|
+
const v = localStorage.getItem(THINK_KEY);
|
|
14
|
+
if (v === null) return true;
|
|
15
|
+
return v === '1';
|
|
16
|
+
} catch (_) { return true; }
|
|
17
|
+
}
|
|
18
|
+
function getReasoningEffort() {
|
|
19
|
+
try {
|
|
20
|
+
const v = localStorage.getItem(REASONING_EFFORT_KEY);
|
|
21
|
+
return v === 'max' ? 'max' : 'high';
|
|
22
|
+
} catch (_) { return 'high'; }
|
|
23
|
+
}
|
|
24
|
+
function syncReasoningEffortUi() {
|
|
25
|
+
const on = getThinkState();
|
|
26
|
+
if (reasoningEffortSelect) {
|
|
27
|
+
reasoningEffortSelect.disabled = !on;
|
|
28
|
+
reasoningEffortSelect.value = getReasoningEffort();
|
|
29
|
+
reasoningEffortSelect.title = on
|
|
30
|
+
? '推理强度(DeepSeek 思考模式):高 = reasoning_effort high,最高 = max'
|
|
31
|
+
: '开启「思考」后可选择推理强度';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function setThinkState(on) {
|
|
35
|
+
try { localStorage.setItem(THINK_KEY, on ? '1' : '0'); } catch (_) {}
|
|
36
|
+
if (thinkToggle) {
|
|
37
|
+
thinkToggle.setAttribute('aria-pressed', on ? 'true' : 'false');
|
|
38
|
+
thinkToggle.title = on
|
|
39
|
+
? '思考:已开启。模型会先思考再回答(慢但更准)。点击关闭。'
|
|
40
|
+
: '思考:已关闭。模型直接回答(更快)。点击开启。';
|
|
41
|
+
}
|
|
42
|
+
syncReasoningEffortUi();
|
|
43
|
+
}
|
|
44
|
+
function setReasoningEffort(val) {
|
|
45
|
+
const effort = val === 'max' ? 'max' : 'high';
|
|
46
|
+
try { localStorage.setItem(REASONING_EFFORT_KEY, effort); } catch (_) {}
|
|
47
|
+
syncReasoningEffortUi();
|
|
48
|
+
}
|
|
49
|
+
if (thinkToggle) {
|
|
50
|
+
setThinkState(getThinkState());
|
|
51
|
+
thinkToggle.addEventListener('click', function(e) {
|
|
52
|
+
e.stopPropagation();
|
|
53
|
+
setThinkState(!getThinkState());
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (reasoningEffortSelect) {
|
|
57
|
+
syncReasoningEffortUi();
|
|
58
|
+
reasoningEffortSelect.addEventListener('change', () => {
|
|
59
|
+
setReasoningEffort(reasoningEffortSelect.value);
|
|
60
|
+
});
|
|
61
|
+
}
|