ai-agent-session-center 2.5.0 → 2.8.2
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 +93 -21
- package/dist/client/assets/AgendaView-DQAv5CVb.js +1 -0
- package/dist/client/assets/AgendaView-HRGSgVxX.css +1 -0
- package/dist/client/assets/{CyberdromeScene-D6GMcGwy.js → CyberdromeScene-DBlv7xBi.js} +184 -184
- package/dist/client/assets/HistoryView-DW2ffQlM.js +1 -0
- package/dist/client/assets/{ProjectBrowserView-D724NPOO.js → ProjectBrowserView-DB5IJ4IC.js} +1 -1
- package/dist/client/assets/QueueView-BOYx9a7Z.js +1 -0
- package/dist/client/assets/index-CCOZp8gY.js +193 -0
- package/dist/client/assets/index-bOzE64NK.css +1 -0
- package/dist/client/index.html +2 -2
- package/dist/client/screenshot-project-tab-compact.png +0 -0
- package/dist/client/screenshot-project-tab-detailed.png +0 -0
- package/hooks/dashboard-hook-codex.sh +9 -1
- package/hooks/dashboard-hook-gemini.sh +9 -1
- package/hooks/dashboard-hook.ps1 +12 -0
- package/hooks/dashboard-hook.sh +10 -1
- package/package.json +12 -9
- package/server/apiRouter.ts +391 -46
- package/server/db.ts +84 -61
- package/server/index.ts +80 -41
- package/server/sessionStore.ts +72 -4
- package/server/sshManager.ts +4 -2
- package/server/wsManager.ts +3 -3
- package/static/screenshot-project-tab-compact.png +0 -0
- package/static/screenshot-project-tab-detailed.png +0 -0
- package/dist/client/assets/AnalyticsView-DbmkUw41.js +0 -1
- package/dist/client/assets/Charts-IyRNWsxy.css +0 -1
- package/dist/client/assets/Charts.module-CzhUhM6q.js +0 -33
- package/dist/client/assets/HistoryView-CkXODdOZ.js +0 -1
- package/dist/client/assets/QueueView-BPSjpcyw.js +0 -1
- package/dist/client/assets/TimelineView-CgCuVJ9Y.js +0 -4
- package/dist/client/assets/index-DLjWFgFH.css +0 -1
- package/dist/client/assets/index-DP88ubkt.js +0 -155
- package/dist/client/assets/useQuery-c1wMNJ4i.js +0 -1
- package/dist/client/assets/with-selector-Cd7Xmf55.js +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# AI Agent Session Center
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
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.
|
|
3
|
+
A lightweight, real-time dashboard that replaces heavy IDEs like VS Code and JetBrains for AI agent workflows. Monitor and control all your Claude Code, Gemini CLI, and Codex sessions from one place — with live SSH terminals, prompt history, tool logs, and queuing. Every session spawns an animated 3D robot in an interactive cyberdrome that visually reflects what the agent is doing. Runs on any device, anywhere.
|
|
6
4
|
|
|
7
5
|
[](https://www.npmjs.com/package/ai-agent-session-center)
|
|
8
6
|
[](https://www.npmjs.com/package/ai-agent-session-center)
|
|
@@ -21,8 +19,8 @@ Every session spawns an animated robot in an interactive cyberdrome that visuall
|
|
|
21
19
|
<td><img src="static/screenshot-terminal.png" alt="SSH terminal session — control agents from the dashboard" width="400"></td>
|
|
22
20
|
</tr>
|
|
23
21
|
<tr>
|
|
24
|
-
<td><img src="static/screenshot-project-tab.png" alt="
|
|
25
|
-
<td><img src="static/screenshot-
|
|
22
|
+
<td><img src="static/screenshot-project-tab-detailed.png" alt="Split view with detailed session switcher cards — terminal and project file browser side by side" width="400"></td>
|
|
23
|
+
<td><img src="static/screenshot-project-tab-compact.png" alt="Split view with compact session switcher — terminal and project file browser side by side" width="400"></td>
|
|
26
24
|
</tr>
|
|
27
25
|
</table>
|
|
28
26
|
|
|
@@ -47,23 +45,97 @@ When you're running multiple AI coding agents across different terminals — Cla
|
|
|
47
45
|
|
|
48
46
|
## Features
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- **
|
|
53
|
-
- **
|
|
54
|
-
- **
|
|
55
|
-
- **
|
|
56
|
-
- **
|
|
57
|
-
- **
|
|
58
|
-
- **
|
|
59
|
-
- **
|
|
60
|
-
|
|
61
|
-
|
|
48
|
+
### 3D Cyberdrome Scene
|
|
49
|
+
|
|
50
|
+
- **One agent, one robot** — every AI coding session gets its own animated 3D character in an interactive cyberdrome
|
|
51
|
+
- **8 animation states** — robots idle, walk, run, wait, dance, wave, or go offline based on real-time session status
|
|
52
|
+
- **6 procedural robot models** — robot, mech, drone, spider, orb, and tank variants with auto-assigned neon colors
|
|
53
|
+
- **Dynamic room system** — four-quadrant office layout with desks, coffee lounge, gym, corridor rooms, and spatial navigation AI
|
|
54
|
+
- **Subagent connections** — parent-child agent teams render as connected robots with animated laser-line beams
|
|
55
|
+
- **Speech bubbles & particles** — floating dialogue shows current tool/prompt, burst particles on state transitions
|
|
56
|
+
- **Camera fly-to** — smooth animated camera focuses on the selected robot; OrbitControls for manual pan/zoom/rotate
|
|
57
|
+
- **Flat list fallback** — 2D sidebar list auto-activates if 3D crashes or for low-resource environments
|
|
58
|
+
|
|
59
|
+
### Session Detail Panel
|
|
60
|
+
|
|
61
|
+
- **Resizable detail panel** — slides in from the right (320px–95vw) with 7 tabs: Terminal, Prompts, Project, Queue, Notes, Activity, Summary
|
|
62
|
+
- **Session switcher** — horizontal tab strip shows all active sessions with sequence numbers, pin/unpin, compact/detailed display modes
|
|
63
|
+
- **Editable metadata** — inline-edit title, label, accent color (customizes robot glow), and pin state; all persisted to SQLite + IndexedDB
|
|
64
|
+
- **Session controls** — Resume, Kill, Archive, Delete, Summarize, Alert, room assignment, and label chips (ONEOFF, HEAVY, IMPORTANT)
|
|
65
|
+
- **Split view** — Terminal and Project side-by-side with a draggable divider (ratio persisted per session)
|
|
66
|
+
- **Approval alerts** — yellow card, visor flash, and 3-burst alarm when tools need user approval
|
|
67
|
+
|
|
68
|
+
### Terminal & SSH
|
|
69
|
+
|
|
70
|
+
- **Full terminal emulation** — xterm.js 5 with 256 colors, Unicode 11, WebLinks, and FitAddon
|
|
71
|
+
- **Local & SSH sessions** — create terminals with working directory, command, SSH host/key/password, tmux wrap/attach
|
|
72
|
+
- **Session resume** — reconnect to disconnected Claude sessions via `claude --resume` with one click
|
|
73
|
+
- **Terminal bookmarks** — save scroll positions with notes, jump back to any bookmarked line
|
|
74
|
+
- **Terminal toolbar** — fullscreen, clear, copy, paste, theme selector (auto, light, dark, Solarized, Dracula, custom)
|
|
75
|
+
- **Bidirectional WebSocket relay** — real-time I/O, 50ms debounced resize, Escape forwards `\x1b` to SSH
|
|
76
|
+
|
|
77
|
+
### Project File Browser
|
|
78
|
+
|
|
79
|
+
- **Browse & search** — navigate project directories, full-text file search with cached results
|
|
80
|
+
- **Syntax highlighting** — code viewer with line numbers, word wrap toggle, and markdown outline panel
|
|
81
|
+
- **Sub-tab system** — open multiple directories/files in tabs within the Project panel
|
|
82
|
+
- **File bookmarks** — save line references with notes; bookmarked lines highlighted in the code viewer; cross-file navigation
|
|
83
|
+
- **Sort & filter** — sort by name or date, toggle date/time display, file size shown per entry
|
|
84
|
+
- **File editing** — inline editor with save support for quick edits
|
|
85
|
+
|
|
86
|
+
### Multi-CLI Monitoring
|
|
87
|
+
|
|
88
|
+
- **Three AI CLIs** — Claude Code (up to 14 events), Gemini CLI (4 events), and Codex (1 event)
|
|
89
|
+
- **3 hook density levels** — High (full monitoring), Medium (default, 12 events), Low (5 events, minimal overhead)
|
|
90
|
+
- **File-based message queue** — hooks append to JSONL queue file via atomic POSIX append (~0.1ms); HTTP POST fallback
|
|
91
|
+
- **3–17ms end-to-end latency** — from hook fired to browser updated
|
|
92
|
+
- **5-priority session matching** — pending resume, terminal ID, working directory, path scan, PID parent check
|
|
93
|
+
- **Approval detection** — tool-category timeouts with child-process check; `PermissionRequest` event for reliable signal
|
|
94
|
+
- **CLI badge detection** — auto-detects CLAUDE, GEMINI, CODEX, or AIDER from launch command
|
|
95
|
+
|
|
96
|
+
### Prompt Queue
|
|
97
|
+
|
|
98
|
+
- **Global queue view** — see all pending prompts across every session in one place
|
|
99
|
+
- **Per-session queue** — compose, reorder (drag-and-drop), send, and move prompts between sessions
|
|
100
|
+
- **Auto-send mode** — queued prompts auto-dispatch when the target session becomes idle
|
|
101
|
+
|
|
102
|
+
### Analytics & History
|
|
103
|
+
|
|
104
|
+
- **History search** — full-text search across titles, projects, and labels with date range, status, and sort filters
|
|
105
|
+
- **Analytics dashboard** — summary cards, 7-day activity heatmap, tool usage breakdown, active projects ranking
|
|
106
|
+
- **Timeline view** — time-series visualization (hourly, daily, weekly) of sessions, prompts, and tool calls
|
|
107
|
+
|
|
108
|
+
### Theming & Sound
|
|
109
|
+
|
|
62
110
|
- **9 scene themes** — Command Center, Cyberpunk, Dracula, Nord, Monokai, Solarized, Light, Warm, Blonde
|
|
63
|
-
- **
|
|
64
|
-
- **
|
|
65
|
-
- **
|
|
66
|
-
|
|
111
|
+
- **16 synthesized sounds** — per-CLI profiles with per-event sound mapping (chime, ping, alarm, fanfare, etc.)
|
|
112
|
+
- **6 ambient presets** — rain, lo-fi, server room, deep space, coffee shop, or off
|
|
113
|
+
- **Visual effects** — glowing card borders, pulsing animations, scanline CRT overlay, status particles, fog depth by theme
|
|
114
|
+
|
|
115
|
+
### Notes & Summaries
|
|
116
|
+
|
|
117
|
+
- **Session notes** — plain-text notes with full CRUD, stored in both SQLite and IndexedDB
|
|
118
|
+
- **AI-powered summaries** — generate session summaries via configured LLM API with customizable prompt templates
|
|
119
|
+
|
|
120
|
+
### Authentication & Security
|
|
121
|
+
|
|
122
|
+
- **Password protection** — optional login with HttpOnly cookie (1-hour TTL), rate-limited (5 attempts/15min)
|
|
123
|
+
- **Security headers** — X-Frame-Options, CSP, CORS, localhost-only hook endpoint, shell metacharacter injection prevention
|
|
124
|
+
- **Directory traversal protection** — `resolveProjectPath()` validates all file browser paths
|
|
125
|
+
|
|
126
|
+
### Keyboard Shortcuts
|
|
127
|
+
|
|
128
|
+
- **Full keyboard navigation** — `/` search, `T` new terminal, `K` kill, `A` archive, `M` mute, `S` settings, `?` shortcuts panel
|
|
129
|
+
- **Rebindable shortcuts** — customize every shortcut from Settings with conflict detection
|
|
130
|
+
- **Session switching** — `Alt+Cmd+1`–`9` to select Nth session by status priority
|
|
131
|
+
|
|
132
|
+
### Data Persistence
|
|
133
|
+
|
|
134
|
+
- **Dual storage** — SQLite on server (sessions, prompts, tools, events, notes) + IndexedDB via Dexie in browser (12 tables)
|
|
135
|
+
- **Auto-snapshots** — server saves full state every 10 seconds; SSH terminals auto-respawn on restart
|
|
136
|
+
- **Session ID migration** — seamless re-keying when sessions resume with new IDs
|
|
137
|
+
|
|
138
|
+
> See [docs/feature/README.md](docs/feature/README.md) for the complete features reference with architecture details and API documentation.
|
|
67
139
|
|
|
68
140
|
## Requirements
|
|
69
141
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{y as j,h as i,k as e,o as M}from"./index-CCOZp8gY.js";const A="_container_pmjze_6",F="_filterBar_pmjze_15",P="_toggleLabel_pmjze_42",$="_taskList_pmjze_61",U="_groupHeader_pmjze_69",Y="_groupChevron_pmjze_78",G="_collapsed_pmjze_86",V="_groupLabel_pmjze_90",W="_groupCount_pmjze_99",q="_taskCard_pmjze_107",K="_completed_pmjze_124",J="_taskTitle_pmjze_128",Q="_overdue_pmjze_133",X="_dueToday_pmjze_138",Z="_checkbox_pmjze_145",ee="_taskContent_pmjze_160",te="_taskHeader_pmjze_165",se="_taskTitleInput_pmjze_189",ae="_priorityBadge_pmjze_204",ne="_priorityUrgent_pmjze_215",oe="_priorityHigh_pmjze_221",le="_priorityMedium_pmjze_227",ie="_priorityLow_pmjze_233",re="_taskMeta_pmjze_241",ce="_dueDate_pmjze_249",de="_dueDateOverdue_pmjze_255",ue="_dueDateToday_pmjze_259",pe="_tag_pmjze_263",me="_tagInput_pmjze_278",ge="_addTagBtn_pmjze_291",he="_description_pmjze_311",_e="_descriptionToggle_pmjze_321",je="_deleteBtn_pmjze_338",fe="_addForm_pmjze_359",ve="_titleInput_pmjze_402",xe="_tagsInput_pmjze_407",ye="_addBtn_pmjze_412",Te="_emptyState_pmjze_438",Ce="_loading_pmjze_459",ke="_stats_pmjze_472",De="_statsSep_pmjze_482",be="_confirmOverlay_pmjze_488",we="_confirmBtn_pmjze_497",ze="_cancelBtn_pmjze_512",s={container:A,filterBar:F,toggleLabel:P,taskList:$,groupHeader:U,groupChevron:Y,collapsed:G,groupLabel:V,groupCount:W,taskCard:q,completed:K,taskTitle:J,overdue:Q,dueToday:X,checkbox:Z,taskContent:ee,taskHeader:te,taskTitleInput:se,priorityBadge:ae,priorityUrgent:ne,priorityHigh:oe,priorityMedium:le,priorityLow:ie,taskMeta:re,dueDate:ce,dueDateOverdue:de,dueDateToday:ue,tag:pe,tagInput:me,addTagBtn:ge,description:he,descriptionToggle:_e,deleteBtn:je,addForm:fe,titleInput:ve,tagsInput:xe,addBtn:ye,emptyState:Te,loading:Ce,stats:ke,statsSep:De,confirmOverlay:be,confirmBtn:we,cancelBtn:ze},Se=[{value:"all",label:"All priorities"},{value:"urgent",label:"Urgent"},{value:"high",label:"High"},{value:"medium",label:"Medium"},{value:"low",label:"Low"}],Ne=[{value:"priority",label:"Priority"},{value:"dueDate",label:"Due date"},{value:"createdAt",label:"Created"}];function Be(){const t=j(l=>l.filter),o=j(l=>l.setFilter),n=i.useCallback(l=>o({search:l}),[o]),c=i.useCallback(l=>o({priority:l.target.value}),[o]),d=i.useCallback(l=>o({sortBy:l.target.value}),[o]),p=i.useCallback(()=>o({showCompleted:!t.showCompleted}),[o,t.showCompleted]);return e.jsxs("div",{className:s.filterBar,children:[e.jsx(M,{value:t.search,onChange:n,placeholder:"Search tasks...",debounceMs:200}),e.jsx("select",{value:t.priority,onChange:c,children:Se.map(l=>e.jsx("option",{value:l.value,children:l.label},l.value))}),e.jsx("select",{value:t.sortBy,onChange:d,children:Ne.map(l=>e.jsx("option",{value:l.value,children:l.label},l.value))}),e.jsxs("label",{className:s.toggleLabel,children:[e.jsx("input",{type:"checkbox",checked:t.showCompleted,onChange:p}),"Show completed"]})]})}const Ie={urgent:s.priorityUrgent,high:s.priorityHigh,medium:s.priorityMedium,low:s.priorityLow};function Le(t){if(!t)return null;const o=new Date;o.setHours(0,0,0,0);const n=new Date(t+"T00:00:00");return n<o?"overdue":n.getTime()===o.getTime()?"today":"future"}function He(t){return new Date(t+"T00:00:00").toLocaleDateString("en-US",{month:"short",day:"numeric"})}function N({task:t}){const o=j(a=>a.toggleTask),n=j(a=>a.updateTask),c=j(a=>a.deleteTask),[d,p]=i.useState(!1),[l,h]=i.useState(t.title),[_,v]=i.useState(!1),[u,y]=i.useState(""),[T,r]=i.useState(!1),[f,g]=i.useState(!1),C=i.useRef(null),b=i.useRef(null);i.useEffect(()=>{d&&(C.current?.focus(),C.current?.select())},[d]),i.useEffect(()=>{_&&b.current?.focus()},[_]),i.useEffect(()=>{d||h(t.title)},[t.title,d]);const k=i.useCallback(()=>{p(!1);const a=l.trim();a&&a!==t.title?n(t.id,{title:a}):h(t.title)},[l,t.id,t.title,n]),w=i.useCallback(()=>{o(t.id)},[o,t.id]),m=i.useCallback(()=>{c(t.id),g(!1)},[c,t.id]),x=i.useCallback(()=>{y(t.tags.join(", ")),v(!0)},[t.tags]),S=i.useCallback(()=>{v(!1);const a=u.split(",").map(R=>R.trim()).filter(Boolean),O=t.tags.join(","),E=a.join(",");O!==E&&n(t.id,{tags:a})},[u,t.id,t.tags,n]),D=Le(t.dueDate),z=[s.taskCard];return t.completed&&z.push(s.completed),!t.completed&&D==="overdue"&&z.push(s.overdue),!t.completed&&D==="today"&&z.push(s.dueToday),e.jsxs("div",{className:z.join(" "),children:[e.jsx("input",{type:"checkbox",className:s.checkbox,checked:t.completed,onChange:w,"aria-label":`Mark "${t.title}" as ${t.completed?"incomplete":"complete"}`}),e.jsxs("div",{className:s.taskContent,children:[e.jsxs("div",{className:s.taskHeader,children:[d?e.jsx("input",{ref:C,className:s.taskTitleInput,value:l,onChange:a=>h(a.target.value),onBlur:k,onKeyDown:a=>{a.key==="Enter"&&(a.preventDefault(),k()),a.key==="Escape"&&(h(t.title),p(!1))},onClick:a=>a.stopPropagation()}):e.jsx("span",{className:s.taskTitle,onClick:()=>{h(t.title),p(!0)},title:"Click to edit",children:t.title}),e.jsx("span",{className:`${s.priorityBadge} ${Ie[t.priority]}`,children:t.priority})]}),e.jsxs("div",{className:s.taskMeta,children:[t.dueDate&&e.jsxs("span",{className:`${s.dueDate} ${D==="overdue"?s.dueDateOverdue:""} ${D==="today"?s.dueDateToday:""}`,children:[D==="overdue"&&"Overdue: ",D==="today"&&"Today: ",He(t.dueDate)]}),_?e.jsx("input",{ref:b,className:s.tagInput,value:u,onChange:a=>y(a.target.value),onBlur:S,onKeyDown:a=>{a.key==="Enter"&&(a.preventDefault(),S()),a.key==="Escape"&&v(!1)},onClick:a=>a.stopPropagation(),placeholder:"tag1, tag2, ..."}):e.jsxs(e.Fragment,{children:[t.tags.map(a=>e.jsx("span",{className:s.tag,onClick:x,title:"Click to edit tags",style:{cursor:"pointer"},children:a},a)),e.jsx("button",{className:s.addTagBtn,onClick:x,title:"Add / edit tags",children:"+"})]})]}),t.description&&e.jsxs(e.Fragment,{children:[e.jsx("button",{className:s.descriptionToggle,onClick:()=>r(a=>!a),children:T?"- Hide details":"+ Show details"}),T&&e.jsx("div",{className:s.description,children:t.description})]})]}),f?e.jsxs("div",{className:s.confirmOverlay,children:[e.jsx("span",{children:"Delete?"}),e.jsx("button",{className:s.confirmBtn,onClick:m,children:"Yes"}),e.jsx("button",{className:s.cancelBtn,onClick:()=>g(!1),children:"No"})]}):e.jsx("button",{className:s.deleteBtn,onClick:()=>g(!0),"aria-label":`Delete "${t.title}"`,title:"Delete task",children:e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("polyline",{points:"3 6 5 6 21 6"}),e.jsx("path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"})]})})]})}function Oe(){const t=j(u=>u.createTask),[o,n]=i.useState(""),[c,d]=i.useState("medium"),[p,l]=i.useState(""),[h,_]=i.useState(""),v=i.useCallback(u=>{u.preventDefault();const y=o.trim();if(!y)return;const T=h.split(",").map(r=>r.trim()).filter(Boolean);t({title:y,priority:c,tags:T,dueDate:p||void 0}),n(""),d("medium"),l(""),_("")},[o,c,p,h,t]);return e.jsxs("form",{className:s.addForm,onSubmit:v,children:[e.jsx("input",{type:"text",className:s.titleInput,placeholder:"New task title...",value:o,onChange:u=>n(u.target.value),required:!0}),e.jsxs("select",{value:c,onChange:u=>d(u.target.value),children:[e.jsx("option",{value:"urgent",children:"Urgent"}),e.jsx("option",{value:"high",children:"High"}),e.jsx("option",{value:"medium",children:"Medium"}),e.jsx("option",{value:"low",children:"Low"})]}),e.jsx("input",{type:"date",value:p,onChange:u=>l(u.target.value),title:"Due date (optional)"}),e.jsx("input",{type:"text",className:s.tagsInput,placeholder:"Tags (comma-sep)",value:h,onChange:u=>_(u.target.value)}),e.jsx("button",{type:"submit",className:s.addBtn,disabled:!o.trim(),children:"ADD"})]})}const B=["urgent","high","medium","low"],I={urgent:0,high:1,medium:2,low:3},Ee={urgent:"Urgent",high:"High",medium:"Medium",low:"Low"};function Re(t,o,n,c){if(n!=="all"&&t.priority!==n||c!=="all"&&!t.tags.includes(c))return!1;if(o){const d=o.toLowerCase(),p=t.title.toLowerCase().includes(d),l=(t.description??"").toLowerCase().includes(d);if(!p&&!l)return!1}return!0}function L(t,o){return[...t].sort((n,c)=>{if(o==="priority"){const d=I[n.priority],p=I[c.priority];return d!==p?d-p:new Date(c.createdAt).getTime()-new Date(n.createdAt).getTime()}return o==="dueDate"?!n.dueDate&&!c.dueDate?0:n.dueDate?c.dueDate?n.dueDate.localeCompare(c.dueDate):-1:1:new Date(c.createdAt).getTime()-new Date(n.createdAt).getTime()})}function H({label:t,count:o,collapsed:n,onToggle:c}){return e.jsxs("div",{className:s.groupHeader,onClick:c,children:[e.jsx("svg",{className:`${s.groupChevron} ${n?s.collapsed:""}`,width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:e.jsx("polyline",{points:"6 9 12 15 18 9"})}),e.jsx("span",{className:s.groupLabel,children:t}),e.jsx("span",{className:s.groupCount,children:o})]})}function Ae(){const t=j(r=>r.tasks),o=j(r=>r.loading),n=j(r=>r.filter),c=j(r=>r.fetchTasks),[d,p]=i.useState(new Set);i.useEffect(()=>{c()},[c]);const l=i.useCallback(r=>{p(f=>{const g=new Set(f);return g.has(r)?g.delete(r):g.add(r),g})},[]),{groups:h,completedTasks:_,totalIncomplete:v,totalCompleted:u}=i.useMemo(()=>{const f=[...t.values()].filter(m=>Re(m,n.search,n.priority,n.tag)),g=f.filter(m=>!m.completed),C=f.filter(m=>m.completed),b=L(g,n.sortBy),k=new Map;for(const m of B)k.set(m,[]);for(const m of b){const x=k.get(m.priority);x&&x.push(m)}const w=[];for(const m of B){const x=k.get(m)??[];x.length>0&&w.push({id:m,label:Ee[m],tasks:x})}return{groups:w,completedTasks:L(C,n.sortBy),totalIncomplete:g.length,totalCompleted:C.length}},[t,n]);if(o)return e.jsx("div",{className:s.container,children:e.jsx("div",{className:s.loading,children:"Loading tasks..."})});const y=h.length===0&&_.length===0,T=t.size===0;return e.jsxs("div",{className:s.container,"data-testid":"agenda-view",children:[e.jsx(Be,{}),e.jsxs("div",{className:s.stats,children:[e.jsxs("span",{children:[v," task",v!==1?"s":""]}),e.jsx("span",{className:s.statsSep,children:"|"}),e.jsxs("span",{children:[u," completed"]})]}),e.jsx("div",{className:s.taskList,children:T?e.jsxs("div",{className:s.emptyState,children:[e.jsx("div",{children:"No tasks yet"}),e.jsx("span",{children:"Add your first task below"})]}):y?e.jsxs("div",{className:s.emptyState,children:[e.jsx("div",{children:"No tasks match the current filter"}),e.jsx("span",{children:"Try adjusting your search or filter criteria"})]}):e.jsxs(e.Fragment,{children:[h.map(r=>{const f=d.has(r.id);return e.jsxs("div",{children:[e.jsx(H,{label:r.label,count:r.tasks.length,collapsed:f,onToggle:()=>l(r.id)}),!f&&r.tasks.map(g=>e.jsx(N,{task:g},g.id))]},r.id)}),n.showCompleted&&_.length>0&&e.jsxs("div",{children:[e.jsx(H,{label:"Completed",count:_.length,collapsed:d.has("__completed__"),onToggle:()=>l("__completed__")}),!d.has("__completed__")&&_.map(r=>e.jsx(N,{task:r},r.id))]})]})}),e.jsx(Oe,{})]})}export{Ae as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._container_pmjze_6{display:flex;flex-direction:column;height:100%;overflow:hidden}._filterBar_pmjze_15{display:flex;align-items:center;gap:10px;padding:14px 24px;border-bottom:1px solid var(--border-subtle);flex-shrink:0;flex-wrap:wrap}._filterBar_pmjze_15 select{background:var(--bg-primary, #0a0a1a);border:1px solid var(--border-subtle);border-radius:6px;color:var(--text-primary);font-size:12px;font-family:var(--font-mono);padding:6px 10px;outline:none;cursor:pointer;min-width:100px}._filterBar_pmjze_15 select:focus{border-color:var(--accent-cyan)}._toggleLabel_pmjze_42{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--text-secondary);font-family:var(--font-mono);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}._toggleLabel_pmjze_42 input[type=checkbox]{accent-color:var(--accent-cyan);cursor:pointer}._taskList_pmjze_61{flex:1;overflow-y:auto;padding:12px 24px}._groupHeader_pmjze_69{display:flex;align-items:center;gap:8px;padding:8px 0 6px;cursor:pointer;-webkit-user-select:none;user-select:none}._groupChevron_pmjze_78{width:10px;height:10px;flex-shrink:0;transition:transform .15s ease;color:var(--text-dim)}._groupChevron_pmjze_78._collapsed_pmjze_86{transform:rotate(-90deg)}._groupLabel_pmjze_90{font-size:11px;letter-spacing:1.5px;color:var(--text-dim);text-transform:uppercase;font-family:var(--font-mono);flex:1}._groupCount_pmjze_99{font-size:10px;color:var(--text-dim);font-family:var(--font-mono)}._taskCard_pmjze_107{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;border:1px solid var(--border-subtle);border-radius:6px;margin-bottom:6px;background:transparent;transition:background .15s ease,border-color .15s ease,box-shadow .15s ease}._taskCard_pmjze_107:hover{background:var(--bg-subtle);border-color:#ffffff1a}._completed_pmjze_124{opacity:.5}._completed_pmjze_124 ._taskTitle_pmjze_128{text-decoration:line-through;color:var(--text-dim)}._overdue_pmjze_133{border-color:var(--accent-red);box-shadow:0 0 8px color-mix(in srgb,var(--accent-red) 30%,transparent)}._dueToday_pmjze_138{border-color:var(--accent-yellow);box-shadow:0 0 8px color-mix(in srgb,var(--accent-yellow) 20%,transparent)}._checkbox_pmjze_145{width:18px;height:18px;flex-shrink:0;margin-top:1px;accent-color:var(--accent-cyan);cursor:pointer}._checkbox_pmjze_145:checked{filter:drop-shadow(0 0 4px var(--accent-cyan))}._taskContent_pmjze_160{flex:1;min-width:0}._taskHeader_pmjze_165{display:flex;align-items:center;gap:8px;margin-bottom:2px}._taskTitle_pmjze_128{font-size:13px;color:var(--text-primary);font-family:var(--font-mono);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;line-height:1.4}._taskTitle_pmjze_128:hover{color:var(--accent-cyan)}._taskTitleInput_pmjze_189{width:100%;background:var(--bg-subtle);border:1px solid var(--accent-cyan);border-radius:3px;color:var(--text-primary);font-size:13px;font-family:var(--font-mono);padding:1px 6px;outline:none;line-height:1.4}._priorityBadge_pmjze_204{font-size:9px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:1px 6px;border-radius:3px;flex-shrink:0;line-height:1.6}._priorityUrgent_pmjze_215{background:color-mix(in srgb,var(--accent-red) 20%,transparent);color:var(--accent-red);border:1px solid color-mix(in srgb,var(--accent-red) 40%,transparent)}._priorityHigh_pmjze_221{background:color-mix(in srgb,var(--accent-orange) 20%,transparent);color:var(--accent-orange);border:1px solid color-mix(in srgb,var(--accent-orange) 40%,transparent)}._priorityMedium_pmjze_227{background:color-mix(in srgb,var(--accent-yellow) 20%,transparent);color:var(--accent-yellow);border:1px solid color-mix(in srgb,var(--accent-yellow) 40%,transparent)}._priorityLow_pmjze_233{background:color-mix(in srgb,var(--accent-green) 20%,transparent);color:var(--accent-green);border:1px solid color-mix(in srgb,var(--accent-green) 40%,transparent)}._taskMeta_pmjze_241{display:flex;align-items:center;gap:8px;margin-top:4px;flex-wrap:wrap}._dueDate_pmjze_249{font-size:10px;font-family:var(--font-mono);color:var(--text-dim)}._dueDateOverdue_pmjze_255{color:var(--accent-red)}._dueDateToday_pmjze_259{color:var(--accent-yellow)}._tag_pmjze_263{font-size:9px;color:var(--accent-cyan);background:color-mix(in srgb,var(--accent-cyan) 10%,transparent);border:1px solid color-mix(in srgb,var(--accent-cyan) 25%,transparent);padding:0 5px;border-radius:3px;line-height:1.7}._tag_pmjze_263:hover{background:color-mix(in srgb,var(--accent-cyan) 20%,transparent);border-color:var(--accent-cyan)}._tagInput_pmjze_278{font-size:10px;font-family:var(--font-mono);color:var(--text-primary);background:var(--bg-subtle);border:1px solid var(--accent-cyan);border-radius:3px;padding:1px 6px;outline:none;min-width:120px;line-height:1.5}._addTagBtn_pmjze_291{font-size:10px;color:var(--text-dim);background:none;border:1px dashed color-mix(in srgb,var(--text-dim) 40%,transparent);border-radius:3px;padding:0 5px;cursor:pointer;font-family:var(--font-mono);line-height:1.6;transition:all .15s ease}._addTagBtn_pmjze_291:hover{color:var(--accent-cyan);border-color:var(--accent-cyan)}._description_pmjze_311{margin-top:6px;font-size:11px;color:var(--text-secondary);font-family:var(--font-mono);line-height:1.5;white-space:pre-wrap;word-break:break-word}._descriptionToggle_pmjze_321{font-size:10px;color:var(--text-dim);cursor:pointer;background:none;border:none;padding:0;font-family:var(--font-mono);margin-top:4px}._descriptionToggle_pmjze_321:hover{color:var(--accent-cyan)}._deleteBtn_pmjze_338{flex-shrink:0;background:none;border:none;color:var(--text-dim);cursor:pointer;padding:4px;border-radius:3px;transition:color .15s ease,background .15s ease;display:flex;align-items:center;justify-content:center}._deleteBtn_pmjze_338:hover{color:var(--accent-red);background:color-mix(in srgb,var(--accent-red) 15%,transparent)}._addForm_pmjze_359{display:flex;align-items:flex-end;gap:8px;padding:12px 24px 16px;border-top:1px solid var(--border-subtle);flex-shrink:0;flex-wrap:wrap}._addForm_pmjze_359 input[type=text],._addForm_pmjze_359 input[type=date]{background:var(--bg-primary, #0a0a1a);border:1px solid var(--border-subtle);border-radius:6px;color:var(--text-primary);font-size:12px;font-family:var(--font-mono);padding:7px 10px;outline:none}._addForm_pmjze_359 input[type=text]:focus,._addForm_pmjze_359 input[type=date]:focus{border-color:var(--accent-cyan)}._addForm_pmjze_359 select{background:var(--bg-primary, #0a0a1a);border:1px solid var(--border-subtle);border-radius:6px;color:var(--text-primary);font-size:12px;font-family:var(--font-mono);padding:7px 10px;outline:none;cursor:pointer}._addForm_pmjze_359 select:focus{border-color:var(--accent-cyan)}._titleInput_pmjze_402{flex:1;min-width:180px}._tagsInput_pmjze_407{min-width:120px;width:140px}._addBtn_pmjze_412{background:color-mix(in srgb,var(--accent-cyan) 15%,transparent);border:1px solid var(--accent-cyan);border-radius:6px;color:var(--accent-cyan);font-size:11px;font-family:var(--font-mono);font-weight:600;letter-spacing:1px;padding:7px 16px;cursor:pointer;transition:background .15s ease;white-space:nowrap}._addBtn_pmjze_412:hover:not(:disabled){background:color-mix(in srgb,var(--accent-cyan) 25%,transparent)}._addBtn_pmjze_412:disabled{opacity:.4;cursor:not-allowed}._emptyState_pmjze_438{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 24px;color:var(--text-dim);font-size:13px;font-family:var(--font-mono);text-align:center;gap:8px}._emptyState_pmjze_438 span{font-size:11px;color:var(--text-dim);opacity:.6}._loading_pmjze_459{display:flex;align-items:center;justify-content:center;padding:60px 24px;color:var(--text-dim);font-size:12px;font-family:var(--font-mono);letter-spacing:1px}._stats_pmjze_472{padding:6px 24px;font-size:11px;color:var(--text-secondary);font-family:var(--font-mono);display:flex;gap:6px;flex-shrink:0}._statsSep_pmjze_482{color:var(--text-dim)}._confirmOverlay_pmjze_488{display:flex;align-items:center;gap:6px;font-size:10px;font-family:var(--font-mono);color:var(--accent-red)}._confirmBtn_pmjze_497{background:color-mix(in srgb,var(--accent-red) 15%,transparent);border:1px solid var(--accent-red);border-radius:3px;color:var(--accent-red);font-size:10px;font-family:var(--font-mono);padding:2px 8px;cursor:pointer}._confirmBtn_pmjze_497:hover{background:color-mix(in srgb,var(--accent-red) 30%,transparent)}._cancelBtn_pmjze_512{background:none;border:1px solid var(--border-subtle);border-radius:3px;color:var(--text-secondary);font-size:10px;font-family:var(--font-mono);padding:2px 8px;cursor:pointer}._cancelBtn_pmjze_512:hover{border-color:var(--text-dim)}
|