ai-agent-session-center 2.2.0 → 2.3.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/README.md +33 -3
- package/dist/client/assets/{AnalyticsView-CKaEx_BQ.js → AnalyticsView-Cp9bp6_0.js} +1 -1
- package/dist/client/assets/{Charts.module-4IN9PtKZ.js → Charts.module-CI5L_KBD.js} +1 -1
- package/dist/client/assets/{CyberdromeScene-Be7Tk67x.js → CyberdromeScene-Bq3v-oAJ.js} +1 -1
- package/dist/client/assets/HistoryView-Cu23DcIM.css +1 -0
- package/dist/client/assets/HistoryView-t3XX1uxx.js +1 -0
- package/dist/client/assets/{QueueView-BsSbIjX1.js → QueueView-DMNeaIFi.js} +1 -1
- package/dist/client/assets/{TimelineView-DbxaiTrG.js → TimelineView-5N2kWFXa.js} +1 -1
- package/dist/client/assets/index-CVkyDAlX.css +1 -0
- package/dist/client/assets/{index-XnIHxZ2e.js → index-CwJoEN_x.js} +62 -62
- package/dist/client/assets/{useQuery-CSmjUocy.js → useQuery-CWX5YPbx.js} +1 -1
- package/dist/client/assets/{with-selector-BL3184_R.js → with-selector-CEvSnm1t.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/screenshot-dashboard.png +0 -0
- package/dist/client/screenshot-detail.png +0 -0
- package/dist/client/screenshot-terminal.png +0 -0
- package/package.json +1 -1
- package/server/apiRouter.ts +118 -2
- package/static/screenshot-dashboard.png +0 -0
- package/static/screenshot-detail.png +0 -0
- package/static/screenshot-terminal.png +0 -0
- package/dist/client/assets/HistoryView-4mf9THSD.js +0 -1
- package/dist/client/assets/HistoryView-I9nTyg4C.css +0 -1
- package/dist/client/assets/index-pnEv8W-w.css +0 -1
package/README.md
CHANGED
|
@@ -1,15 +1,37 @@
|
|
|
1
1
|
# AI Agent Session Center
|
|
2
2
|
|
|
3
|
-
Real-time 3D dashboard for monitoring Claude Code, Gemini CLI, and Codex sessions — live terminals, prompt history, tool logs, and queuing. Runs on any device.
|
|
3
|
+
Real-time 3D dashboard for monitoring and controlling Claude Code, Gemini CLI, and Codex sessions — live SSH terminals, prompt history, tool logs, and queuing. Runs on any device.
|
|
4
4
|
|
|
5
5
|
Every session spawns an animated robot in an interactive cyberdrome that visually reflects what the agent is doing — running when executing tools, waving when prompting, waiting when it needs your approval.
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/ai-agent-session-center)
|
|
8
|
+
[](https://www.npmjs.com/package/ai-agent-session-center)
|
|
8
9
|
[](https://nodejs.org)
|
|
9
10
|
[](./LICENSE)
|
|
10
11
|
|
|
12
|
+
<p align="center">
|
|
13
|
+
<img src="static/screenshot-dashboard.png" alt="AI Agent Session Center — 3D cyberdrome with 15 active agent sessions" width="800">
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<img src="static/screenshot-terminal.png" alt="SSH terminal session — control agents directly from the dashboard" width="800">
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
<details>
|
|
21
|
+
<summary>Detail panel view</summary>
|
|
22
|
+
|
|
23
|
+
<p align="center">
|
|
24
|
+
<img src="static/screenshot-detail.png" alt="Session detail panel with terminal, prompts, queue, and activity tabs" width="800">
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
</details>
|
|
28
|
+
|
|
11
29
|
https://github.com/user-attachments/assets/004ee6f9-942c-44c2-a4c5-d971fa0e824b
|
|
12
30
|
|
|
31
|
+
## Why?
|
|
32
|
+
|
|
33
|
+
When you're running multiple AI coding agents across different terminals — Claude Code in one, Gemini in another, Codex in a third — it's impossible to keep track of what each one is doing. Which agent is stuck waiting for approval? Which one finished and needs your next prompt? Which one is burning tokens on a runaway loop? Agent Session Center gives you a single view across all your AI coding sessions so you can stay in control without constantly switching terminals.
|
|
34
|
+
|
|
13
35
|
## Features
|
|
14
36
|
|
|
15
37
|
- **One agent, one robot** — every AI coding session gets its own animated 3D character in the cyberdrome
|
|
@@ -136,7 +158,7 @@ When a hook event arrives, a 5-priority fallback system links it to the correct
|
|
|
136
158
|
- **Terminal**: xterm.js, node-pty
|
|
137
159
|
- **Database**: SQLite (server, WAL mode) + IndexedDB via Dexie (browser)
|
|
138
160
|
- **Hooks**: Bash scripts (file-based MQ primary, HTTP fallback)
|
|
139
|
-
- **Testing**: Vitest (
|
|
161
|
+
- **Testing**: Vitest (400+ tests) + Playwright (E2E)
|
|
140
162
|
- **Charts**: Recharts
|
|
141
163
|
- **Drag & Drop**: @dnd-kit
|
|
142
164
|
|
|
@@ -196,7 +218,7 @@ npm run setup # Interactive setup wizard
|
|
|
196
218
|
npm run install-hooks # Install hooks into CLI configs
|
|
197
219
|
npm run uninstall-hooks # Remove all dashboard hooks
|
|
198
220
|
npm run reset # Reset everything (hooks, config, backup)
|
|
199
|
-
npm test # Run tests (
|
|
221
|
+
npm test # Run tests (400+ Vitest tests)
|
|
200
222
|
npm run test:watch # Watch mode
|
|
201
223
|
npm run test:e2e # E2E tests (Playwright)
|
|
202
224
|
npm run debug # Start with verbose logging
|
|
@@ -236,6 +258,14 @@ brew install jq
|
|
|
236
258
|
sudo apt-get install jq
|
|
237
259
|
```
|
|
238
260
|
|
|
261
|
+
## Contributing
|
|
262
|
+
|
|
263
|
+
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on how to get started.
|
|
264
|
+
|
|
265
|
+
## Changelog
|
|
266
|
+
|
|
267
|
+
See [CHANGELOG.md](CHANGELOG.md) for a detailed list of changes in each release.
|
|
268
|
+
|
|
239
269
|
## License
|
|
240
270
|
|
|
241
271
|
This project is licensed under the [MIT License](LICENSE).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as t,r as m,a as C}from"./index-
|
|
1
|
+
import{j as t,r as m,a as C}from"./index-CwJoEN_x.js";import{u as d}from"./useQuery-CWX5YPbx.js";import{m as r,R as f,B as y,C as j,X as g,Y as v,T as b,n as _,o as S}from"./Charts.module-CI5L_KBD.js";import"./with-selector-CEvSnm1t.js";async function u(e){const a=await C(e);if(!a.ok)throw new Error(`API error: ${a.status}`);return a.json()}function n(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":String(e)}function N(e,a){const s=a===0?0:Math.max(0,Math.min(1,e/a)),l=Math.round(18+-18*s),i=Math.round(18+237*s),o=Math.round(42+94*s);return`rgb(${l},${i},${o})`}const p=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];function K(){const{data:e}=d({queryKey:["analytics-summary"],queryFn:()=>u("/api/db/analytics/summary"),staleTime:3e4}),{data:a}=d({queryKey:["analytics-tools"],queryFn:()=>u("/api/db/analytics/tools"),staleTime:3e4}),{data:s}=d({queryKey:["analytics-projects"],queryFn:()=>u("/api/db/analytics/projects"),staleTime:3e4}),{data:l}=d({queryKey:["analytics-heatmap"],queryFn:()=>u("/api/db/analytics/heatmap"),staleTime:3e4});return t.jsxs("div",{className:r.analyticsView,"data-testid":"analytics-view",children:[t.jsx(T,{summary:e??null}),t.jsxs("div",{className:r.analyticsGrid,children:[t.jsxs("div",{className:r.analyticsCard,children:[t.jsx("h4",{children:"Tool Usage"}),t.jsx($,{data:a??[]})]}),t.jsxs("div",{className:r.analyticsCard,children:[t.jsx("h4",{children:"Active Projects"}),t.jsx(A,{data:s??[]})]}),t.jsxs("div",{className:r.analyticsCard,style:{gridColumn:"1 / -1"},children:[t.jsx("h4",{children:"Activity Heatmap"}),t.jsx(w,{data:l??[]})]})]})]})}function T({summary:e}){const a=[{label:"Total Sessions",value:n(e?.total_sessions??0),detail:"all time"},{label:"Total Prompts",value:n(e?.total_prompts??0),detail:"all time"},{label:"Total Tool Calls",value:n(e?.total_tool_calls??0),detail:"all time"},{label:"Active Sessions",value:n(e?.active_sessions??0),detail:"currently running"},{label:"Most Used Tool",value:e?.most_used_tool?.tool_name??"N/A",detail:e?.most_used_tool?n(e.most_used_tool.count)+" calls":""},{label:"Busiest Project",value:e?.busiest_project?.name??"N/A",detail:e?.busiest_project?n(e.busiest_project.count)+" sessions":""}];return t.jsx("div",{className:r.analyticsSummary,children:a.map(s=>t.jsxs("div",{className:r.summaryStat,children:[t.jsx("div",{className:r.statLabel,children:s.label}),t.jsx("div",{className:r.statValue,children:s.value}),t.jsx("div",{className:r.statDetail,children:s.detail})]},s.label))})}function $({data:e}){const a=e.slice(0,15);return a.length===0?t.jsx(h,{message:"No tool data"}):t.jsx(f,{width:"100%",height:Math.max(200,a.length*28),children:t.jsxs(y,{data:a,layout:"vertical",margin:{top:4,right:40,bottom:4,left:100},children:[t.jsx(j,{strokeDasharray:"3 3",stroke:"rgba(255,255,255,0.04)"}),t.jsx(g,{type:"number",tick:{fill:"#8888aa",fontSize:10}}),t.jsx(v,{type:"category",dataKey:"tool_name",tick:{fill:"#8888aa",fontSize:10},width:96}),t.jsx(b,{contentStyle:{background:"#12122a",border:"1px solid #00e5ff",borderRadius:4,fontSize:11,color:"#e0e0ff"},formatter:((s,l,i)=>[`${n(s)} (${i.payload.percentage}%)`,"Calls"])}),t.jsx(_,{dataKey:"count",radius:[0,4,4,0],children:a.map((s,l)=>t.jsx(S,{fill:"#00e5ff",fillOpacity:.85},l))})]})})}function A({data:e}){const a=m.useMemo(()=>[...e].sort((s,l)=>l.session_count-s.session_count).slice(0,15),[e]);return a.length===0?t.jsx(h,{message:"No project data"}):t.jsx(f,{width:"100%",height:Math.max(200,a.length*28),children:t.jsxs(y,{data:a,layout:"vertical",margin:{top:4,right:40,bottom:4,left:120},children:[t.jsx(j,{strokeDasharray:"3 3",stroke:"rgba(255,255,255,0.04)"}),t.jsx(g,{type:"number",tick:{fill:"#8888aa",fontSize:10}}),t.jsx(v,{type:"category",dataKey:"project_name",tick:{fill:"#8888aa",fontSize:10},width:116}),t.jsx(b,{contentStyle:{background:"#12122a",border:"1px solid #00e5ff",borderRadius:4,fontSize:11,color:"#e0e0ff"},formatter:(s=>[n(s)+" sessions","Sessions"])}),t.jsx(_,{dataKey:"session_count",radius:[0,4,4,0],children:a.map((s,l)=>t.jsx(S,{fill:"#00ff88",fillOpacity:.85},l))})]})})}function w({data:e}){const{grid:a,maxVal:s}=m.useMemo(()=>{const l=new Map;let i=0;for(const o of e){const c=`${o.day_of_week}-${o.hour}`;l.set(c,o.count),o.count>i&&(i=o.count)}return{grid:l,maxVal:i}},[e]);return e.length===0?t.jsx(h,{message:"No heatmap data"}):t.jsxs("div",{style:{display:"grid",gridTemplateColumns:"40px repeat(24, 14px)",gridTemplateRows:"14px repeat(7, 14px)",gap:"2px",alignItems:"center"},children:[t.jsx("div",{}),Array.from({length:24},(l,i)=>t.jsx("div",{style:{fontSize:"9px",color:"#8888aa",textAlign:"center"},children:i},`h-${i}`)),Array.from({length:7},(l,i)=>t.jsxs(m.Fragment,{children:[t.jsx("div",{style:{fontSize:"10px",color:"#8888aa",textAlign:"right",paddingRight:"4px"},children:p[i]}),Array.from({length:24},(o,c)=>{const x=a.get(`${i}-${c}`)??0;return t.jsx("div",{className:r.heatmapCell,title:`${p[i]} ${String(c).padStart(2,"0")}:00 - ${x} events`,style:{backgroundColor:N(x,s)}},`${i}-${c}`)})]},`row-${i}`))]})}function h({message:e}){return t.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%",minHeight:"120px",color:"var(--text-dim, #555577)",fontSize:"0.85rem"},children:e})}export{K as default};
|