micro-models-agent 2.21.0 → 2.23.0
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/CHANGELOG.md +29 -0
- package/dist/assets/app.js +1 -1
- package/dist/assets/index.html +17 -0
- package/dist/assets/js/dom.js +1 -1
- package/dist/assets/js/feed/sidebar.js +1 -1
- package/dist/assets/js/session/composer.js +1 -1
- package/dist/assets/js/sidebar/core.js +1 -1
- package/dist/assets/js/sidebar/files.js +1 -0
- package/dist/assets/js/sidebar/state.js +1 -1
- package/dist/assets/js/sidebar.js +1 -1
- package/dist/assets/styles.css +1 -1
- package/dist/i18n/en.json +1 -1
- package/dist/i18n/ru.json +1 -1
- package/dist/main.js +368 -368
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,35 @@ All notable changes to Micro Models Agent (MMA) will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [2.23.0] - 2026-10-07
|
|
8
|
+
|
|
9
|
+
A new **Files** sidebar tab in `mma web`: browse the workspace as a lazy tree,
|
|
10
|
+
read files in-app (read-only) and attach a file to the message by inserting its
|
|
11
|
+
path. Live-refreshes on workspace changes.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **Files sidebar tab** (`src/modules/webui/assets/js/sidebar/files.ts`, `index.html`, `styles.css`): a fifth sidebar tab (`Alt+5`) renders a lazy file tree (fetch a directory only when it is expanded), master-detail read-only viewer (text with highlight.js, markdown, images/PDF/media) and an "attach path" action on file rows and in the viewer header. Attaching inserts the workspace-relative path (backticked) into the active composer draft — no new attachment channel; the agent reads it via `read_file`.
|
|
16
|
+
- **`GET /api/files?path=`** (`src/modules/webui/file/files-api.ts`): JSON listing of one directory (dirs first, then files; `MAX_DIR_ENTRIES` cap with `truncated`), jailed to the workspace and filtered with the indexer's ignore primitives (`IGNORE_DIRS`, `.gitignore`/`.mmaignore`) and protected paths.
|
|
17
|
+
- **Live tree updates** (`src/modules/indexer/module.ts`, `src/modules/webui/index-watcher.ts`, `module.ts`, `assets/app.ts`): the workspace watcher now invokes an `onSettled` callback after its debounced rebuild, which bumps `HostStateSnapshot.filesRevision` and broadcasts a `files` SSE event; the Files tab re-reads expanded directories.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- **Shared workspace path resolver** (`src/modules/webui/file/paths.ts`): `resolveWorkspacePath` centralizes the lexical + `realpath` + protected-path jail; `file-api.ts` and the new `files-api.ts` both use it.
|
|
22
|
+
|
|
23
|
+
## [2.22.0] - 2026-10-06
|
|
24
|
+
|
|
25
|
+
Web sidebar metrics are no longer frozen until a turn ends, and the cache cell no
|
|
26
|
+
longer shows a misleading `0%` on backends that do not report prompt caching.
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **Live context metrics** (`src/modules/webui/session/run-agent.ts`, `host-state.ts`, `assets/app.ts`): while a turn runs the runner reads the live `ContextManager` snapshot every ~800ms and broadcasts a new `usage` SSE event for the owning session. The sidebar context bar/legend, compaction count and quality now update in real time instead of only at `turn_end`; the client merges it into the tab without a full state re-fetch.
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- **Cache hit-rate on non-reporting backends** (`src/core/agent/cache-stats.ts`, `src/core/agent.ts`, `types.ts`, `src/cli/cache-line.ts`): `hitRate` is now emitted only when the provider actually returned cache tokens. Previously the prefix monitor always supplied `stableRatio`, so `buildCacheStats` fabricated `hitRate: 0` and the web sidebar showed `0%` (and JSON/CLI consumers saw a false miss) on providers without prompt caching; it now renders `—`.
|
|
35
|
+
|
|
7
36
|
## [2.21.0] - 2026-10-06
|
|
8
37
|
|
|
9
38
|
Additive hardening on top of 2.20.0: deterministic grounding for stated figures,
|
package/dist/assets/app.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{msgs as
|
|
1
|
+
import{msgs as W,inp as m,connStatus as x,setIcon as T,icon as C}from"./js/dom.js";import{api as j,token as k}from"./js/api.js";import{I18N as D,t as a,loadI18n as z}from"./js/i18n.js";import{tabs as u,session as o,settings as f,hooks as h}from"./js/store.js";import{onText as J,onReasoning as Q,onMeta as X,onPhase as G,onToolStart as K,onToolEnd as V,onTurnEnd as Y,onErrorEvent as Z,onCommandOutput as $,onLog as ee,onPlan as te,onQuestion as ne,onRetract as se,showEmptyFeed as S,renderPlan as oe,renderUsage as w,renderEnvironment as ie,renderWorkspace as ae,feedHasContent as re,loadHistory as de}from"./js/feed.js";import{openTab as A,updateTabName as ce,renderSessionsDropdown as R,reflectBusy as q,loadSessions as _,loadCommands as le,setTabStatus as p,reconcileTabStatuses as P}from"./js/session/tabs.js";import{renderSelectors as I,renderSettings as ue,loadConfig as fe,loadModels as be,loadProviders as pe,loadMemory as ge,loadSkills as me,loadPlugins as he,applyTheme as Se,currentTheme as we,applyFontSize as Ie,setConnStatus as v,setStaleBar as B}from"./js/settings.js";import{initRail as ve,setPlan as N,railEvent as ye,applyRailI18n as Ee}from"./js/rail.js";import{initSidebar as Le,sidebarSessionChanged as xe,sidebarMapState as Te,sidebarTraceEvent as y,sidebarTurnEnd as Ce,sidebarBusy as M,sidebarMapIndicator as ke,sidebarPullLog as Ae,sidebarSessionId as Re,setSessionLoading as qe,sidebarLspState as _e,sidebarLspEvent as Pe,applySidebarI18n as H,initFiles as Be,sidebarFilesState as Ne,sidebarFilesChanged as O}from"./js/sidebar.js";import{insertIntoDraft as Me}from"./js/session/composer.js";document.querySelectorAll("[data-collapse]").forEach(n=>{const s=n.querySelector(".arrow");s&&(s.textContent="",s.appendChild(C("chevron-down"))),n.addEventListener("click",()=>{const d=n.nextElementSibling;if(!d)return;const i=d.classList.toggle("collapsed");n.setAttribute("aria-expanded",i?"false":"true");const r=n.querySelector(".arrow");r&&(r.textContent="",r.appendChild(C(i?"chevron-right":"chevron-down")))})});const g=document.getElementById("toggleSidebar");g&&(g.addEventListener("click",()=>{const n=document.body.classList.toggle("sb-open");g.setAttribute("aria-expanded",n?"true":"false")}),document.addEventListener("keydown",n=>{if(n.key!=="Escape"||!document.body.classList.contains("sb-open"))return;const s=document.activeElement?String(document.activeElement.tagName):"";s==="TEXTAREA"||s==="INPUT"||(document.body.classList.remove("sb-open"),g.setAttribute("aria-expanded","false"))}));let E=-1;function F(n,s,d){o.host=n||{},o.busy=!!s,o.runningSessionId=d&&d.runningSessionId||null,o.runningSessionIds=d&&d.runningSessionIds||(o.runningSessionId?[o.runningSessionId]:[]),o.queued=d&&d.queued||{},q(),P();const i=o.host.sessionId||null;o.activeSessionId=i,i&&!u.tabs.some(c=>c.id===i)&&A(i,o.host.sessionName||String(i),"session",!1),i&&ce(i,o.host.sessionName),u.tabs.length||S(),oe(o.host.plan),N(s&&n?n.plan:null),w(o.host),n&&typeof n.contextWindow=="number"&&f.config&&f.config.contextWindow!==n.contextWindow&&(f.config.contextWindow=n.contextWindow,I()),ie(o.host),Te(o.host),ke(o.host),_e(),Ne(o.host);const r=n&&typeof n.filesRevision=="number"?n.filesRevision:void 0;if(r!==void 0&&r!==E){const c=E===-1;E=r,!c&&r>0&&O()}xe(i),ae(o.host),R(),qe(!1),B(!!(n&&n.i18nStale))}async function b(){const n=u.activeTabId,s=n?"/api/state?session="+encodeURIComponent(n):"/api/state",d=await j(s);!d.ok||!d.data||u.activeTabId===n&&F(d.data.state||{},d.data.busy,d.data)}h.applyState=F,h.refreshState=b;function He(){b();const n=u.tabs.find(s=>s.id===u.activeTabId);n&&n.kind==="session"&&!re(n.feed)&&(n.historyLoaded=!1,de(n))}function Oe(){const n="/events"+(k?"?token="+encodeURIComponent(k):""),s=new EventSource(n);let d=!1;s.onopen=()=>{d&&(d=!1,v(!1),He())},s.onerror=e=>{e&&typeof e.data=="string"||(d=!0,v(!0))};const i=e=>{try{return JSON.parse(e.data)}catch{return null}},r=e=>!e.sessionId||e.sessionId===Re(),c=[["text",e=>J(e.chunk||"",e.sessionId)],["meta",e=>X(e.chunk||"",e.sessionId,e.kind)],["reasoning",e=>Q(e.chunk||"",e.sessionId)],["phase",e=>G(e.phase,e.sessionId)],["tool_start",K],["tool_end",V],["plan",te],["question",ne],["turn_end",e=>{Y(e),r(e)&&(Ce(e.turnSeq),M(!1),Ae())}],["log",ee],["retract",e=>se(e.reason||"",e.sessionId)]];for(const[e,t]of c)s.addEventListener(e,l=>{const L=i(l);L&&t(L)});for(const e of["tool_start","tool_end","text","plan"])s.addEventListener(e,t=>{const l=i(t);l&&(e==="plan"?N(l):ye(e,l.name))});for(const e of["text","reasoning","phase","tool_start","plan"])s.addEventListener(e,t=>{const l=i(t);l&&l.sessionId&&p(l.sessionId,"working")});s.addEventListener("question",e=>{const t=i(e);t&&t.sessionId&&p(t.sessionId,"waiting")}),s.addEventListener("turn_end",e=>{const t=i(e);t&&t.sessionId&&p(t.sessionId,t.success===!1?"failed":"idle")});for(const e of["tool_start","tool_end","phase","plan","question","meta","log","retract","index"])s.addEventListener(e,t=>{const l=i(t);l&&r(l)&&y(e,l)});s.addEventListener("text",e=>{const t=i(e);t&&r(t)&&y("text",t)}),s.addEventListener("lsp",e=>{const t=i(e);t&&Pe(t)}),s.addEventListener("files",()=>O()),s.addEventListener("command",e=>{const t=i(e);t&&typeof t.text=="string"&&$(t.text,t.sessionId)}),s.addEventListener("state",e=>{const t=i(e);t&&(o.busy=!!t.busy,o.runningSessionId=t.runningSessionId||null,o.runningSessionIds=t.runningSessionIds||(o.runningSessionId?[o.runningSessionId]:[]),o.queued=t.queued||{},q(),P(),M(!!t.busy),b(),t.usage&&typeof t.usage=="object"&&(t.usageSessionId==null||t.usageSessionId===o.activeSessionId)&&(o.host=Object.assign({},o.host,t.usage),w(o.host)))}),s.addEventListener("usage",e=>{const t=i(e);t&&t.usage&&typeof t.usage=="object"&&(t.usageSessionId==null||t.usageSessionId===o.activeSessionId)&&(o.host=Object.assign({},o.host,t.usage),w(o.host))}),s.addEventListener("error",e=>{if(!e.data)return;const t=i(e);t&&(t.sessionId&&p(t.sessionId,"failed"),Z(t),y("error",t))})}function U(){document.documentElement.lang=D.locale;const n=(r,c)=>{const e=document.getElementById(r);e&&(e.textContent=c)};n("planHeaderLabel",a("web.sidebar.plan")),n("usageHeaderLabel",a("web.sidebar.session")+" · "+a("web.sidebar.usage")),n("envHeaderLabel",a("web.sidebar.env")),n("settingsTitle",a("web.settings.title")),n("sessActiveHeader",a("web.sessions.active")),n("sessRecentHeader",a("web.sessions.recent")),n("hintEnter",a("web.input.enter")),n("hintShift",a("web.input.shift_enter")),n("hintEsc",a("web.input.esc")),n("hintAttach",a("web.input.attach"));const s={newChat:["plus",a("web.topbar.new_chat")],sessBtn:["menu",a("web.topbar.all_sessions")],toggleSidebar:["panel",a("web.topbar.sidebar")],openSettings:["settings",a("web.topbar.settings")],attachBtn:["image",a("web.attach.title")],closeSettings:["x",a("web.topbar.close")],sessNew:["plus",a("web.sessions.new")],sessRefresh:["refresh",a("web.sessions.refresh")],sessPrev:["chevron-left",a("web.sessbar.prev")],sessNext:["chevron-right",a("web.sessbar.next")],sessClose:["x",a("web.topbar.close")]};Object.keys(s).forEach(r=>{const c=document.getElementById(r);if(!c)return;const[e,t]=s[r];T(c,e,r==="closeSettings"||r==="sessNew"||r==="sessRefresh"?t:null),c.title=t,c.setAttribute("aria-label",t)});const d=document.getElementById("settingsIcon");d&&T(d,"settings",null),m&&(m.placeholder=a("web.input.placeholder"),m.setAttribute("aria-label",a("web.input.placeholder"))),document.querySelectorAll("#setMenu .mi").forEach(r=>{const c=r.dataset.p;c&&(r.textContent=a("web.settings."+c))});const i=document.getElementById("setSearch");i&&(i.setAttribute("placeholder",a("web.settings.search_placeholder")),i.setAttribute("aria-label",a("web.settings.search_placeholder"))),document.querySelectorAll(".content-col .panel").forEach(r=>{const c=r.querySelector("h3"),e=r.id.replace(/^p-/,"");c&&e&&(c.textContent=a("web.settings."+e))}),I(),R(),Ee(),H(),W.querySelector(".empty")&&S(),x&&!x.hidden&&v(!0),B(void 0,!0)}async function Fe(){const n=new URLSearchParams(location.search).get("session");if(window.MmaSetup)try{if(await window.MmaSetup.maybeOpen())return}catch{}await z(),await le(),Se(we()),Ie(),U(),S(),I(),ue(),await fe(),ve(f.config&&f.config.ui?f.config.ui.activityRail:void 0),Le(),H(),Be({insertPath:s=>Me("`"+s+"` ")}),await be(),await pe(),await _(),await ge(),await me(),await he();try{await b()}catch(s){console.error("initial refresh failed",s)}if(n){const s=o.sessions.find(d=>d.id===n);s&&A(n,s.name||String(n),"session",!0)}Oe(),setInterval(()=>{b().catch(s=>console.error("refresh failed",s))},2e3),setInterval(()=>{_()},15e3)}h.applyStaticI18n=U,Fe();
|
package/dist/assets/index.html
CHANGED
|
@@ -116,6 +116,10 @@
|
|
|
116
116
|
<span class="sb-ico" data-icon="lsp" aria-hidden="true"></span>
|
|
117
117
|
<span class="sb-dot" aria-hidden="true"></span>
|
|
118
118
|
</button>
|
|
119
|
+
<button class="sb-tab" type="button" role="tab" data-tab="files" aria-selected="false" aria-controls="pane-files" title="Files">
|
|
120
|
+
<span class="sb-ico" data-icon="files" aria-hidden="true"></span>
|
|
121
|
+
<span class="sb-dot" aria-hidden="true"></span>
|
|
122
|
+
</button>
|
|
119
123
|
</div>
|
|
120
124
|
<div class="sb-name" id="sbName"><span class="sb-ico" data-icon="session" aria-hidden="true"></span><span id="sbNameText">Session</span></div>
|
|
121
125
|
|
|
@@ -153,6 +157,19 @@
|
|
|
153
157
|
<div class="sec-body" id="lspBody"></div>
|
|
154
158
|
</div>
|
|
155
159
|
</div>
|
|
160
|
+
|
|
161
|
+
<div class="sb-pane" id="pane-files" role="tabpanel" data-pane="files" hidden>
|
|
162
|
+
<div class="files-tree" id="filesTree"></div>
|
|
163
|
+
<div class="files-detail" id="filesDetail" hidden>
|
|
164
|
+
<div class="detail-h">
|
|
165
|
+
<span class="g" id="filesGlyph" aria-hidden="true">◆</span>
|
|
166
|
+
<span id="filesTitle"></span>
|
|
167
|
+
<button class="x linkbtn" type="button" id="filesAttach" title="attach path">◧</button>
|
|
168
|
+
<button class="x linkbtn" type="button" id="filesClose" title="close">✕</button>
|
|
169
|
+
</div>
|
|
170
|
+
<div class="detail-b" id="filesBody"></div>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
156
173
|
</div>
|
|
157
174
|
</div>
|
|
158
175
|
|
package/dist/assets/js/dom.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const msgs=document.getElementById("msgs"),inp=document.getElementById("inp"),tabstripEl=document.getElementById("tabstrip"),planEl=document.getElementById("plan"),planCountEl=document.getElementById("planCount"),usageEl=document.getElementById("usage"),envEl=document.getElementById("env"),wsLine=document.getElementById("wsLine"),saveIndicator=document.getElementById("saveIndicator"),attachStrip=document.getElementById("attachStrip"),attachErr=document.getElementById("attachErr"),imgPicker=document.getElementById("imgPicker"),connStatus=document.getElementById("connStatus"),staleBar=document.getElementById("staleBar"),liveEl=document.getElementById("live"),sendBtn=document.getElementById("sendBtn");export function announce(e){!liveEl||!e||(liveEl.textContent="",setTimeout(()=>{liveEl.textContent=e},30))}export function el(e,a,t){const n=document.createElement(e);return a&&(n.className=a),t!=null&&(n.textContent=String(t)),n}let i=null,s=!1;function p(){return i||(i=el("div","ctip"),i.setAttribute("role","tooltip"),document.body.appendChild(i)),i}function
|
|
1
|
+
export const msgs=document.getElementById("msgs"),inp=document.getElementById("inp"),tabstripEl=document.getElementById("tabstrip"),planEl=document.getElementById("plan"),planCountEl=document.getElementById("planCount"),usageEl=document.getElementById("usage"),envEl=document.getElementById("env"),wsLine=document.getElementById("wsLine"),saveIndicator=document.getElementById("saveIndicator"),attachStrip=document.getElementById("attachStrip"),attachErr=document.getElementById("attachErr"),imgPicker=document.getElementById("imgPicker"),connStatus=document.getElementById("connStatus"),staleBar=document.getElementById("staleBar"),liveEl=document.getElementById("live"),sendBtn=document.getElementById("sendBtn");export function announce(e){!liveEl||!e||(liveEl.textContent="",setTimeout(()=>{liveEl.textContent=e},30))}export function el(e,a,t){const n=document.createElement(e);return a&&(n.className=a),t!=null&&(n.textContent=String(t)),n}let i=null,s=!1;function p(){return i||(i=el("div","ctip"),i.setAttribute("role","tooltip"),document.body.appendChild(i)),i}function c(){i&&i.classList.remove("show")}function h(){s||(s=!0,window.addEventListener("scroll",c,!0),window.addEventListener("resize",c))}export function attachTooltip(e,a){const t=()=>{const n=p();n.replaceChildren(a()),n.classList.add("show");const o=e.getBoundingClientRect(),r=n.getBoundingClientRect();let d=o.left+o.width/2-r.width/2;d=Math.max(6,Math.min(d,window.innerWidth-r.width-6));let l=o.top-r.height-7;l<6&&(l=o.bottom+7),n.style.left=d+"px",n.style.top=l+"px"};e.addEventListener("mouseenter",t),e.addEventListener("mouseleave",c),e.addEventListener("focus",t),e.addEventListener("blur",c),h()}export const SVG_NS="http://www.w3.org/2000/svg",ICONS={plus:[["path",{d:"M5 12h14"}],["path",{d:"M12 5v14"}]],menu:[["line",{x1:4,y1:6,x2:20,y2:6}],["line",{x1:4,y1:12,x2:20,y2:12}],["line",{x1:4,y1:18,x2:20,y2:18}]],settings:[["path",{d:"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"}],["circle",{cx:12,cy:12,r:3}]],image:[["rect",{width:18,height:18,x:3,y:3,rx:2,ry:2}],["circle",{cx:9,cy:9,r:2}],["path",{d:"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"}]],x:[["path",{d:"M18 6 6 18"}],["path",{d:"m6 6 12 12"}]],trash:[["path",{d:"M3 6h18"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"}],["line",{x1:10,y1:11,x2:10,y2:17}],["line",{x1:14,y1:11,x2:14,y2:17}]],refresh:[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"}],["path",{d:"M21 3v5h-5"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"}],["path",{d:"M8 21H3v-5"}]],"chevron-down":[["path",{d:"m6 9 6 6 6-6"}]],"chevron-left":[["path",{d:"m15 18-6-6 6-6"}]],"chevron-right":[["path",{d:"m9 18 6-6-6-6"}]],search:[["circle",{cx:11,cy:11,r:8}],["path",{d:"m21 21-4.3-4.3"}]],"list-checks":[["path",{d:"m3 17 2 2 4-4"}],["path",{d:"m3 7 2 2 4-4"}],["path",{d:"M13 6h8"}],["path",{d:"M13 12h8"}],["path",{d:"M13 18h8"}]],map:[["path",{d:"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z"}],["path",{d:"M15 5.764v15"}],["path",{d:"M9 3.236v15"}]],activity:[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"}]],"arrow-up":[["path",{d:"M12 19V5"}],["path",{d:"m5 12 7-7 7 7"}]],panel:[["rect",{width:18,height:18,x:3,y:3,rx:2,ry:2}],["line",{x1:15,y1:3,x2:15,y2:21}]],square:[["rect",{width:14,height:14,x:5,y:5,rx:2}]],copy:[["rect",{width:14,height:14,x:8,y:8,rx:2,ry:2}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"}]],check:[["path",{d:"M20 6 9 17l-5-5"}]],info:[["circle",{cx:12,cy:12,r:10}],["path",{d:"M12 16v-4"}],["path",{d:"M12 8h.01"}]],stethoscope:[["path",{d:"M11 2v2"}],["path",{d:"M5 2v2"}],["path",{d:"M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1"}],["path",{d:"M8 15a6 6 0 0 0 12 0v-3"}],["circle",{cx:20,cy:10,r:2}]],"folder-tree":[["path",{d:"M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z"}],["path",{d:"M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.9-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z"}],["path",{d:"M3 5a2 2 0 0 1 2-2h3"}],["path",{d:"M3 3v13a3 3 0 0 0 3 3h4"}]],folder:[["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"}]],file:[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4"}]],paperclip:[["path",{d:"m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48"}]]};export function icon(e,a){const t=document.createElementNS(SVG_NS,"svg");return t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","none"),t.setAttribute("stroke","currentColor"),t.setAttribute("stroke-width","2"),t.setAttribute("stroke-linecap","round"),t.setAttribute("stroke-linejoin","round"),t.setAttribute("aria-hidden","true"),t.setAttribute("focusable","false"),t.setAttribute("class","svg-icon"+(a?" "+a:"")),(ICONS[e]||[]).forEach(([n,o])=>{const r=document.createElementNS(SVG_NS,n);Object.keys(o).forEach(d=>r.setAttribute(d,String(o[d]))),t.appendChild(r)}),t}export function setIcon(e,a,t){return e?(e.textContent="",e.appendChild(icon(a)),t!=null&&e.appendChild(el("span","",t)),e):null}export function makeToggle(e,a){const t=el("button","toggle"+(e?" on":""));return t.type="button",t.setAttribute("role","switch"),t.setAttribute("aria-checked",e?"true":"false"),t.addEventListener("click",()=>{const n=!t.classList.contains("on");a(n)&&(t.classList.toggle("on",n),t.setAttribute("aria-checked",n?"true":"false"))}),t}export function link(e,a,t){const n=el("button","linkbtn"+(a?" "+a:""),e);return n.type="button",n.addEventListener("click",t),n}export function inlineTextNodes(e){const a=document.createDocumentFragment();return String(e??"").replace(/^-\s*/,"").split("**").forEach((n,o)=>{if(n!=="")if(o%2===1){const r=document.createElement("b");r.textContent=n,a.appendChild(r)}else a.appendChild(document.createTextNode(n))}),a}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{usageEl as
|
|
1
|
+
import{usageEl as p,envEl as x,wsLine as m,el as s,icon as v,attachTooltip as k}from"../dom.js";import{I18N as S,t as a,pluralCount as y}from"../i18n.js";import{feed as g,settings as E}from"../store.js";import{fmtTokens as b}from"../format.js";import{copyText as L}from"../../md.js";function f(e,o,n){const t=s("div","kv");return t.appendChild(s("span","",e)),t.appendChild(s("b",n||"",o)),t}function _(e){return[["seg-system","web.usage.part_system",e.system],["seg-tools","web.usage.part_tools",e.tools],["seg-history","web.usage.part_history",e.history],["seg-reserve","web.usage.part_reserve",e.reserve],["seg-free","web.usage.part_free",e.free]]}function M(e,o,n,t){const i=document.createDocumentFragment();return i.appendChild(s("i","ctip-dot "+e)),i.appendChild(s("span","ctip-label",a(o))),i.appendChild(s("b","",b(n))),i.appendChild(s("span","ctip-pct",Math.round(n/t*100)+"%")),i}const U=new Map;function A(e,o,n){const t=U.get(o);if(U.set(o,n),t===void 0||t===n){e.style.flexGrow=String(n);return}e.style.flexGrow=String(t);const i=()=>{e.style.flexGrow=String(n)};typeof requestAnimationFrame=="function"?requestAnimationFrame(i):i()}function I(e,o,n){const t=s("div","bar segbar"),i=e.contextBreakdown;if(!i||typeof i.window!="number"||i.window<=0){const d=s("i");return d.style.flex="0 0 "+Math.min(100,Math.round(o/n*100))+"%",t.appendChild(d),t}const r=Math.max(i.window,i.used+i.reserve);for(const[d,l,c]of _(i)){if(!c||c<=0)continue;const u=s("i",d);u.style.flexBasis="0",A(u,d,c),u.tabIndex=0,u.setAttribute("aria-label",[a(l),b(c),Math.round(c/r*100)+"%"].join(" · ")),k(u,()=>M(d,l,c,r)),t.appendChild(u)}return t}function R(e){const o=s("div","seglegend"),n=e.contextBreakdown;if(!n)return o;const t=Math.max(n.window,n.used+n.reserve);for(const[i,r,d]of _(n)){if(!d||d<=0)continue;const l=s("span","segl-item");l.tabIndex=0,l.setAttribute("aria-label",[a(r),b(d),Math.round(d/t*100)+"%"].join(" · ")),l.appendChild(s("i","segl-dot "+i)),l.appendChild(s("span","segl-label",a(r))),l.appendChild(s("b","",b(d))),k(l,()=>M(i,r,d,t)),o.appendChild(l)}return o}function T(e){const o=s("div","kv");o.appendChild(s("span","",a("web.usage.session")));const n=s("span","kv-val");if(!e)n.appendChild(s("b","","—"));else{n.appendChild(s("b","",e));const t=s("button","copy-btn");t.type="button",t.title=a("web.usage.copy_id"),t.setAttribute("aria-label",a("web.usage.copy_id")),t.appendChild(v("copy")),t.addEventListener("click",()=>{L(e).then(i=>{t.replaceChildren(v(i?"check":"copy")),setTimeout(()=>t.replaceChildren(v("copy")),1500)})}),n.appendChild(t)}return o.appendChild(n),o}export function renderUsage(e){const o=E.config||{},n=JSON.stringify([e.sessionId,e.model,e.contextUsed,e.contextLimit,e.cacheHitRate,e.costUsd,e.compactionCount,e.contextQuality,e.contextProbe,e.contextBreakdown,o.model,o.contextWindow,S.locale]);if(n===g.lastUsageSig)return;g.lastUsageSig=n,p.textContent="";const t=e.sessionId?String(e.sessionId):"";p.appendChild(T(t)),p.appendChild(f(a("web.usage.model"),e.model||o.model||"—"));const i=typeof e.contextUsed=="number"?e.contextUsed:null,r=typeof e.contextLimit=="number"?e.contextLimit:o.contextWindow||null;p.appendChild(f(a("web.usage.context"),i!=null&&r?b(i)+" / "+b(r):"—")),i!=null&&r&&(p.appendChild(I(e,i,r)),p.appendChild(R(e)));const d=typeof e.cacheHitRate=="number"?e.cacheHitRate:null;p.appendChild(f(a("web.usage.cache"),d!=null?Math.round(d*100)+"%":"—",d!=null?"":"dim")),p.appendChild(f(a("web.usage.cost"),typeof e.costUsd=="number"?"$"+e.costUsd.toFixed(4):"—")),p.appendChild(f(a("web.usage.compactions"),"⟳ "+(e.compactionCount||0),e.compactionCount?"wn":"dim"));const l=typeof e.contextQuality=="number"?e.contextQuality:null;p.appendChild(f(a("web.usage.quality"),l!=null?Math.round(l)+"%":"—",l!=null?"":"dim"));let c="—",u="dim";const w=e.contextProbe;if(w&&typeof w.actual=="number"){const h=b(w.actual),C=e.contextLimit||o.contextWindow||null;C&&w.actual<C?(c=a("web.usage.probe_low",{actual:h,configured:b(C)}),u="wn"):(c=a("web.usage.probe_loaded",{actual:h}),u="")}p.appendChild(f(a("web.usage.probe"),c,u))}export function renderWorkspace(e){const o=e.workspace||"";if(m.dataset.ws===o||(m.dataset.ws=o,m.textContent="",m.hidden=!o,!o))return;m.appendChild(s("span","ws-k",a("web.env.dir")));const n=s("span","ws-v",o);n.title=o,m.appendChild(n)}function B(e,o){const n=s("div","env-item");return n.appendChild(s("div","env-k",e)),o.forEach(t=>{const i=s("div","env-v",t);i.title=t,n.appendChild(i)}),n}export function renderEnvironment(e){const o=!!(e.instructions&&e.instructions.disabled),n=e.instructions&&!o?e.instructions.files||[]:[],t=e.projectMap||null,i=JSON.stringify([o,n,t,S.locale]);i!==g.lastEnvSig&&(g.lastEnvSig=i,x.textContent="",x.appendChild(B(a("web.env.agents"),o?[a("web.env.agents_disabled")]:n.length?n:[a("web.env.agents_none")])),x.appendChild(B(a("web.env.map"),t&&t.indexed?[[y("web.env.files",t.files),y("web.env.symbols",t.symbols),y("web.env.tokens",t.tokens)].join(" · ")]:[a("web.env.map_not_indexed")])))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{inp as
|
|
1
|
+
import{inp as i,imgPicker as g,attachStrip as B,attachErr as k,sendBtn as p,el as f,icon as _}from"../dom.js";import{api as S}from"../api.js";import{t as c}from"../i18n.js";import{tabs as o,session as m,settings as y,MAX_IMAGES as C,MAX_IMAGE_BYTES as z}from"../store.js";import{contextLabel as W}from"../format.js";import{clearEmpty as N,activeFeed as Y,liveFeed as j,appendTo as v,scrollToBottom as P,clearFeed as J,finishMd as Q,resetTurnText as V,finishThink as Z,showBusy as $}from"../feed.js";import{setBusy as ee}from"../rail.js";import"../core/menus.js";import{openSessionsMenu as te}from"./sessions-menu.js";import{closeCmdk as F,updateCmdk as ne,cmdkKeydown as se,initCmdk as ae}from"./cmdk.js";let r={activeTab:()=>null,setTabStatus:()=>{},newChatTab:async()=>{},markTabDead:()=>{},openTab:()=>{},closeTab:()=>{},statusTitle:()=>""};export function initComposer(e){r={...r,...e}}ae({autogrow:T});const ie=200;function T(){i&&(i.style.height="auto",i.style.height=Math.min(i.scrollHeight,ie)+"px")}function oe(e){k&&(k.textContent=e,k.hidden=!1,clearTimeout(o.attachErrTimer),o.attachErrTimer=setTimeout(()=>{k.hidden=!0},4e3))}export function renderAttachments(){if(!B)return;B.textContent="",B.hidden=o.attachments.length===0,o.attachments.forEach((t,n)=>{const s=f("div","thumb"),a=document.createElement("img");a.alt="",a.src=t,s.appendChild(a);const d=f("button","rm");d.type="button",d.title=c("web.attach.remove"),d.setAttribute("aria-label",c("web.attach.remove")),d.appendChild(_("x")),d.addEventListener("click",()=>{o.attachments.splice(n,1),renderAttachments()}),s.appendChild(d),B.appendChild(s)});const e=r.activeTab();e&&(e.attachments=o.attachments.slice())}function re(e){return new Promise((t,n)=>{const s=new FileReader;s.onload=()=>t(String(s.result)),s.onerror=()=>n(s.error||new Error("read failed")),s.readAsDataURL(e)})}async function x(e){let t="";for(const n of e){if(!n||typeof n.type!="string"||n.type.indexOf("image/")!==0){t=c("web.attach.only_images");continue}if(o.attachments.length>=C){t=c("web.attach.too_many",{max:C});break}if(n.size>z){t=c("web.attach.too_large");continue}try{const s=await re(n);if(s.indexOf("data:image/")!==0){t=c("web.attach.invalid");continue}if(o.attachments.length>=C){t=c("web.attach.too_many",{max:C});break}o.attachments.push(s)}catch{t=c("web.attach.read_failed")}}renderAttachments(),t&&oe(t)}function ce(e,t){const n=f("div","u",e);return(t||[]).forEach(s=>{const a=document.createElement("img");a.className="uimg",a.alt="",a.src=s,n.appendChild(a)}),n}export function saveComposer(){const e=r.activeTab();!e||!i||(e.draft=i.value,e.attachments=o.attachments.slice())}export function restoreComposer(e){!e||!i||(i.value=e.draft||"",o.attachments=(e.attachments||[]).slice(),renderAttachments(),T(),F())}const de=document.getElementById("sessBar"),I=document.getElementById("sessNameBtn"),le=document.getElementById("sessName"),L=document.getElementById("sessPrev"),A=document.getElementById("sessNext"),D=document.getElementById("sessClose"),O=document.getElementById("sessTools"),q=document.getElementById("sessDD"),w=document.querySelector(".bar-top"),E=document.getElementById("newChat"),M=document.createComment("top-tools");w&&E&&w.insertBefore(M,E);function X(e){if(o.tabs.length<2)return;const t=o.tabs.findIndex(a=>a.id===o.activeTabId),n=t===-1?0:(t+e+o.tabs.length)%o.tabs.length,s=o.tabs[n];s&&r.openTab(s.id,s.name,s.kind,!0)}export function renderSessBar(){if(!de)return;const e=o.tabs.find(s=>s.id===o.activeTabId),t=e?e.name||String(e.id):"—";le.textContent=t,I.title=t+(e&&e.status&&e.status!=="idle"?" · "+r.statusTitle(e.status):"");const n=o.tabs.length>0;L.disabled=o.tabs.length<2,A.disabled=o.tabs.length<2,D.disabled=!n,I.disabled=!n}function U(){!w||!O||!E||!q||(window.matchMedia("(max-width: 760px)").matches?O.append(E,q):(w.insertBefore(E,M),w.insertBefore(q,M)))}if(L&&L.addEventListener("click",()=>X(-1)),A&&A.addEventListener("click",()=>X(1)),D&&D.addEventListener("click",()=>{o.activeTabId&&r.closeTab(o.activeTabId)}),I&&I.addEventListener("click",e=>{e.stopPropagation(),te()}),typeof window.matchMedia=="function"){const e=window.matchMedia("(max-width: 760px)");typeof e.addEventListener=="function"&&e.addEventListener("change",U),U()}g&&g.addEventListener("change",()=>{x(Array.from(g.files||[])),g.value=""});const G=document.getElementById("attachBtn");G&&g&&G.addEventListener("click",()=>g.click()),i.addEventListener("paste",e=>{const t=e.clipboardData&&e.clipboardData.items;if(!t)return;const n=[];for(const s of t)if(s.kind==="file"&&s.type&&s.type.indexOf("image/")===0){const a=s.getAsFile();a&&n.push(a)}n.length&&(e.preventDefault(),x(n))});const h=document.querySelector(".input-area");h&&(["dragenter","dragover"].forEach(e=>{h.addEventListener(e,t=>{t.preventDefault(),h.classList.add("dragover")})}),h.addEventListener("dragleave",e=>{const t=e;t.relatedTarget&&h.contains(t.relatedTarget)||h.classList.remove("dragover")}),h.addEventListener("drop",e=>{e.preventDefault(),h.classList.remove("dragover");const t=e.dataTransfer;t&&t.files&&t.files.length&&x(Array.from(t.files))}));function H(){i.value="",T(),F()}export function insertIntoDraft(e){if(!i||!e)return;const t=i.selectionStart??i.value.length,n=i.selectionEnd??t;i.value=i.value.slice(0,t)+e+i.value.slice(n);const s=t+e.length;i.selectionStart=i.selectionEnd=s;const a=r.activeTab();a&&(a.draft=i.value),T(),i.focus()}i&&i.addEventListener("input",()=>{const e=r.activeTab();e&&(e.draft=i.value),T(),ne()});async function K(){const e=i.value.trim(),t=o.attachments.slice();if(!e&&!t.length)return;const n=r.activeTab(),s=n&&n.kind==="session"?n.id:null,a=j()||Y();if(n&&n.dead){N(a),r.markTabDead(n.id);return}if(N(a),Q(),V(),Z(),e.startsWith("/")){v(a,f("div","u",e)),P(),n&&(n.draft="",n.attachments=[]),o.attachments=[],renderAttachments(),H();const u=e.slice(1).split(/\s+/)[0].toLowerCase();if(u==="clear"){J(a);return}if(u==="new"){r.newChatTab();return}const b={line:e};s&&(b.sessionId=s),(await S("/api/command",{method:"POST",body:b})).ok||v(a,f("div","detail","↳ "+c("web.misc.command_unavailable")));return}if(a&&a.querySelector(".startbanner")===null&&a.querySelector(".u")===null){const u=f("div","startbanner");u.appendChild(document.createTextNode(c("web.start.label")+" ")),u.appendChild(f("b","",y.config&&y.config.model||m.host.model||"—"));const b=m.host.sessionId?" · "+c("web.start.session")+" "+String(m.host.sessionId):"";u.appendChild(document.createTextNode(" · "+(m.host.provider||y.config&&y.config.provider&&y.config.provider.active||"—")+" · "+W()+b)),a.insertBefore(u,a.firstChild)}v(a,ce(e,t)),P(),n&&(n.draft="",n.attachments=[]),o.attachments=[],renderAttachments(),H(),s&&r.setTabStatus(s,"working");const d={text:e};t.length&&(d.images=t),s&&(d.sessionId=s);const l=await S("/api/message",{method:"POST",body:d});if(l.ok)if(l.data&&l.data.noop)l.data.notice&&v(a,f("div","detail",String(l.data.notice)));else if(l.data&&l.data.queued){const u=l.data.queuedForSession||l.data.queued;v(a,f("div","detail","↳ "+c("web.input.queued",{n:u}))),s&&r.setTabStatus(s,"queued")}else window.setTimeout(()=>$(a),180);else{const u=l.data&&l.data.error||l.status,b=u==="queue_full"?c("web.input.queue_full"):u;v(a,f("div","warnline","⚠ "+b)),s&&r.setTabStatus(s,"failed")}}async function R(){const e=r.activeTab(),t=e&&e.kind==="session"?e.id:null,n=m.runningSessionIds||[];t&&!n.includes(t)||!t&&!m.busy||await S("/api/interrupt",{method:"POST",body:t?{sessionId:t}:{}})}i.addEventListener("keydown",e=>{e.isComposing||e.keyCode===229||se(e)||(e.key==="Enter"&&!e.shiftKey?(e.preventDefault(),K()):e.key==="Escape"&&(e.preventDefault(),R()))}),p&&p.addEventListener("click",()=>{const e=r.activeTab();e&&e.kind==="session"&&m.runningSessionIds.includes(e.id)?R():K()});export function reflectBusy(){const e=r.activeTab(),t=m.runningSessionIds||[],n=!!(e&&e.kind==="session"&&t.includes(e.id));i&&i.setAttribute("aria-busy",n?"true":"false");const s=document.querySelector(".input-area");if(s&&s.classList.toggle("busy",n),p){const d=n?c("web.input.stop"):c("web.input.send");p.textContent="",p.appendChild(_(n?"square":"arrow-up")),p.classList.toggle("busy",n),p.title=d,p.setAttribute("aria-label",d)}const a=document.getElementById("hintEsc");a&&(a.hidden=!n),ee(m.busy)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{icon as m}from"../dom.js";import{session as g}from"../store.js";import{t as
|
|
1
|
+
import{icon as m}from"../dom.js";import{session as g}from"../store.js";import{t as f}from"../i18n.js";import{sb as e,TABS as a,ICON_NAME as b,paneEl as B,mqMobile as S,readStored as h,storeTab as v}from"./state.js";import{collapseDetail as d,renderList as u,renderDetail as x}from"./trace.js";import{sidebarMapState as y,sidebarMapIndicator as I}from"./map.js";import{renderLsp as E,sidebarLspState as p}from"./lsp.js";import{renderFilesTree as T,refreshFilesTree as k}from"./files.js";export function setSidebarTab(n,i=!0){a.includes(n)||(n="session"),i&&v(n);const t=n==="trace"&&S()?"session":n;t!==e.active&&d(),e.active=t,a.forEach(r=>{const s=B(r);s&&(s.hidden=r!==t);const l=e.el&&e.el.querySelector('.sb-tab[data-tab="'+r+'"]');if(l){const c=r===t;l.classList.toggle("on",c),l.setAttribute("aria-selected",c?"true":"false")}}),e.nameTextEl&&(e.nameTextEl.textContent=f("web.sidebar.tab_"+t));const o=e.nameEl&&e.nameEl.querySelector(".sb-ico");o&&(o.textContent="",o.appendChild(m(b[t]))),t==="lsp"&&p(),t==="files"&&T()}export function sidebarBusy(n){const i=e.el&&e.el.querySelector('.sb-tab[data-tab="trace"]');i&&(i.dataset.indicator=n?"live":"")}export function applySidebarI18n(){if(e.el){if(a.forEach(n=>{const i=e.el?.querySelector('.sb-tab[data-tab="'+n+'"]');if(i){const t=f("web.sidebar.tab_"+n);i.title=t,i.setAttribute("aria-label",t)}}),setSidebarTab(e.active,!1),u(),e.selected){const n=e.trace.find(i=>i.id===e.selected);n&&x(n)}y(g.host),E(),k()}}export function initSidebar(){if(e.el||(e.el=document.querySelector(".sb"),!e.el))return;const n=e.el;e.nameEl=document.getElementById("sbName"),e.nameTextEl=document.getElementById("sbNameText"),e.mapEl=document.getElementById("mapBody"),e.lspEl=document.getElementById("lspBody"),e.listEl=document.getElementById("traceList"),e.detailEl=document.getElementById("traceDetail"),e.detailGlyph=document.getElementById("detailGlyph"),e.detailTitle=document.getElementById("detailTitle"),e.detailBody=document.getElementById("detailBody"),e.detailClose=document.getElementById("detailClose"),e.detailClose&&e.detailClose.addEventListener("click",d),n.querySelectorAll(".sb-tab .sb-ico").forEach(t=>{const o=t.closest(".sb-tab")?.dataset.tab||"session";t.textContent="",t.appendChild(m(b[o]))}),n.querySelectorAll(".sb-tab").forEach(t=>{t.addEventListener("click",()=>setSidebarTab(t.dataset.tab||"session")),t.addEventListener("keydown",o=>{if(o.key!=="ArrowLeft"&&o.key!=="ArrowRight")return;o.preventDefault();const r=a.indexOf(t.dataset.tab||"session"),s=a[(r+(o.key==="ArrowRight"?1:a.length-1))%a.length];setSidebarTab(s);const l=n.querySelector('.sb-tab[data-tab="'+s+'"]');l&&l.focus()})}),document.addEventListener("keydown",t=>{if(!t.altKey||!["1","2","3","4","5"].includes(t.key))return;const o=document.activeElement?String(document.activeElement.tagName):"";o==="INPUT"||o==="TEXTAREA"||(t.preventDefault(),setSidebarTab(a[Number(t.key)-1]))}),document.addEventListener("keydown",t=>{t.key==="Escape"&&e.selected&&d()});const i=h();setSidebarTab(i&&a.includes(i)?i:"session"),u()}export{y as sidebarMapState,I as sidebarMapIndicator,E as renderLsp,p as sidebarLspState};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{el as o,icon as g}from"../dom.js";import{api as L}from"../api.js";import{t as r}from"../i18n.js";import{renderMarkdown as P}from"../../md.js";import{sb as t}from"./state.js";let m={insertPath:()=>{}};export function initFiles(e){m={...m,...e},t.files.treeEl=document.getElementById("filesTree"),t.files.detailEl=document.getElementById("filesDetail"),t.files.detailTitleEl=document.getElementById("filesTitle"),t.files.detailBodyEl=document.getElementById("filesBody"),t.files.detailAttachEl=document.getElementById("filesAttach"),document.getElementById("filesClose")?.addEventListener("click",closeFile),t.files.detailAttachEl?.addEventListener("click",()=>{t.files.selectedPath&&m.insertPath(t.files.selectedPath)}),document.addEventListener("keydown",n=>{n.key==="Escape"&&t.files.selectedPath&&closeFile()})}let w="",x=!0;const C=new Map,u=new Set,E=new Set;function c(){x=!0}export function sidebarFilesState(e){const n=e&&e.workspace||"";n!==w&&(w=n,t.files.listings.clear(),t.files.expanded.clear(),t.files.selectedPath=null,t.files.detailEl&&(t.files.detailEl.hidden=!0),t.el?.classList.remove("sb-expanded"),c()),t.active==="files"&&renderFilesTree()}function h(e){if(t.files.listings.has(e))return Promise.resolve();const n=C.get(e);if(n)return n;const i=L("/api/files?path="+encodeURIComponent(e)).then(s=>{s.ok&&s.data?(t.files.listings.set(e,s.data.entries||[]),s.data.truncated&&E.add(e),u.delete(e)):u.add(e),c()}).finally(()=>C.delete(e));return C.set(e,i),i}export function refreshFilesTree(){c(),renderFilesTree()}export function renderFilesTree(){const e=t.files.treeEl;if(!(!e||!x)){if(x=!1,e.textContent="",!w){e.appendChild(o("div","fdim",r("web.files.no_workspace")));return}if(!t.files.listings.has("")){e.appendChild(o("div","fdim",u.has("")?r("web.files.error"):r("web.files.loading"))),h("").then(renderFilesTree);return}b(e,"",0)}}function b(e,n,i){const s=t.files.listings.get(n)||[];if(s.length===0&&i===0){e.appendChild(o("div","fdim",r("web.files.empty")));return}for(const d of s){const l=n?`${n}/${d.name}`:d.name;if(e.appendChild(B(d,l,i)),d.type==="dir"&&t.files.expanded.has(l))if(t.files.listings.has(l))b(e,l,i+1);else{const f=o("div","fdim",u.has(l)?r("web.files.error"):r("web.files.loading"));f.style.paddingLeft=`${8+(i+1)*14}px`,e.appendChild(f),h(l).then(renderFilesTree)}}if(E.has(n)){const d=o("div","fdim",r("web.files.truncated"));d.style.paddingLeft=`${8+i*14}px`,e.appendChild(d)}}function B(e,n,i){const s=e.type==="dir",d=!s&&t.files.selectedPath===n,l=o("div",`frow${s?" dir":""}${d?" sel":""}`);l.style.paddingLeft=`${8+i*14}px`;const f=o("span","ftw");s&&f.appendChild(g(t.files.expanded.has(n)?"chevron-down":"chevron-right")),l.appendChild(f);const a=o("span","fic");if(a.appendChild(g(s?"folder":"file")),l.appendChild(a),l.appendChild(o("span","fname",e.name)),!s){const p=o("button","fattach");p.type="button",p.title=r("web.files.attach"),p.setAttribute("aria-label",r("web.files.attach")),p.appendChild(g("paperclip")),p.addEventListener("click",k=>{k.stopPropagation(),m.insertPath(n)}),l.appendChild(p)}return l.addEventListener("click",()=>{s?I(n):openFile(n)}),l}function I(e){t.files.expanded.has(e)?t.files.expanded.delete(e):(t.files.expanded.add(e),t.files.listings.has(e)||h(e).then(renderFilesTree)),c(),renderFilesTree()}export async function openFile(e){t.files.selectedPath=e;const n=t.files.detailEl;t.files.detailTitleEl&&(t.files.detailTitleEl.textContent=e,t.files.detailTitleEl.title=e),t.el?.classList.add("sb-expanded"),n&&(n.hidden=!1);const i=t.files.detailBodyEl;i&&(i.textContent="",i.appendChild(o("div","fdim",r("web.files.loading")))),c(),renderFilesTree();let s;try{s=await fetch(v(e))}catch{y();return}if(!s.ok||!i){y();return}const d=s.headers.get("content-type")||"";i.textContent="",d.indexOf("text/plain")===0?O(i,e,await s.text()):T(i,e,d)}export function closeFile(){t.files.selectedPath=null,t.files.detailEl&&(t.files.detailEl.hidden=!0),t.el?.classList.remove("sb-expanded"),c(),renderFilesTree()}export function sidebarFilesChanged(){const e=["",...t.files.expanded];e.forEach(i=>{t.files.listings.delete(i),u.delete(i),E.delete(i)}),c(),renderFilesTree();const n=t.files.selectedPath?openFile(t.files.selectedPath):Promise.resolve();Promise.all([...e.map(h),n]).then(renderFilesTree)}function y(){const e=t.files.detailBodyEl;e&&(e.textContent="",e.appendChild(o("div","fdim wn",r("web.files.open_failed"))))}function v(e){return"/api/file?path="+encodeURIComponent(e)}function F(e){const n=e.lastIndexOf(".");return n===-1?"":e.slice(n+1).toLowerCase()}function O(e,n,i){const s=F(n);if(s==="md"||s==="markdown"){const a=o("div","fmd");P(a,i),e.appendChild(a);return}const d=o("pre","fpre"),l=o("code","fcode");l.textContent=i;const f=window.hljs;if(f)try{const a=f.getLanguage(s)?f.highlight(i,{language:s,ignoreIllegals:!0}):f.highlightAuto(i);l.replaceChildren(...A(a.value))}catch{}d.appendChild(l),e.appendChild(d)}function T(e,n,i){const s=v(n);if(i.indexOf("image/")===0){const l=document.createElement("img");l.className="fimg",l.alt=n,l.src=s,e.appendChild(l);return}if(i.indexOf("application/pdf")===0){const l=o("embed","fembed");l.setAttribute("src",s),l.setAttribute("type","application/pdf"),e.appendChild(l);return}const d=i.indexOf("audio/")===0?"audio":i.indexOf("video/")===0?"video":null;if(d){const l=document.createElement(d);l.controls=!0,l.src=s,e.appendChild(l);return}y()}function A(e){const n=new DOMParser().parseFromString(e,"text/html");return Array.from(n.body.childNodes).map(i=>document.importNode(i,!0))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const TAB_KEY="mma-sidebar-tab",TABS=["session","map","trace","lsp"],ICON_NAME={session:"list-checks",map:"map",trace:"activity",lsp:"stethoscope"},TRACE_CAP=500,MAX_OUTPUT_CHARS=2e4,sb={el:null,nameEl:null,nameTextEl:null,mapEl:null,listEl:null,detailEl:null,detailGlyph:null,detailTitle:null,detailBody:null,detailClose:null,lspEl:null,active:"session",trace:[],selected:null,turn:0,seq:0,logCursor:null,logPulling:!1,nodeById:new Map,callIndex:new Map,headerByTurn:new Map,textEntry:null,lspDiag:null,lspFlags:null,lspProbing:!1,lspLoaded:!1,lspUnavailable:!1,reindexing:!1,postResolved:!1,reindexError:!1};export function paneEl(
|
|
1
|
+
export const TAB_KEY="mma-sidebar-tab",TABS=["session","map","trace","lsp","files"],ICON_NAME={session:"list-checks",map:"map",trace:"activity",lsp:"stethoscope",files:"folder-tree"},TRACE_CAP=500,MAX_OUTPUT_CHARS=2e4,sb={el:null,nameEl:null,nameTextEl:null,mapEl:null,listEl:null,detailEl:null,detailGlyph:null,detailTitle:null,detailBody:null,detailClose:null,lspEl:null,active:"session",trace:[],selected:null,turn:0,seq:0,logCursor:null,logPulling:!1,nodeById:new Map,callIndex:new Map,headerByTurn:new Map,textEntry:null,lspDiag:null,lspFlags:null,lspProbing:!1,lspLoaded:!1,lspUnavailable:!1,reindexing:!1,postResolved:!1,reindexError:!1,files:{treeEl:null,detailEl:null,detailTitleEl:null,detailBodyEl:null,detailAttachEl:null,expanded:new Set,listings:new Map,selectedPath:null}};export function paneEl(l){return document.getElementById("pane-"+l)}export function mqMobile(){return typeof window<"u"&&window.matchMedia?window.matchMedia("(max-width: 760px)").matches:!1}export function readStored(){try{return localStorage.getItem(TAB_KEY)}catch{return null}}export function storeTab(l){try{localStorage.setItem(TAB_KEY,l)}catch{}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./sidebar/core.js";export*from"./sidebar/trace.js";export*from"./sidebar/map.js";export*from"./sidebar/lsp.js";
|
|
1
|
+
export*from"./sidebar/core.js";export*from"./sidebar/trace.js";export*from"./sidebar/map.js";export*from"./sidebar/lsp.js";export*from"./sidebar/files.js";
|