ai-agent-session-center 2.0.7 → 2.0.8

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 CHANGED
@@ -56,11 +56,10 @@ ai-agent-session-center
56
56
  ### Uninstall
57
57
 
58
58
  ```bash
59
- # Remove hooks and clean up config
60
- npx ai-agent-session-center --setup # choose uninstall, or:
61
- npm run uninstall-hooks # if installed from source
59
+ # Remove hooks from all CLI configs
60
+ npx ai-agent-session-center --uninstall
62
61
 
63
- # Remove global install
62
+ # If installed globally
64
63
  npm uninstall -g ai-agent-session-center
65
64
  ```
66
65
 
@@ -91,6 +90,7 @@ Options:
91
90
  --no-open Don't auto-open browser
92
91
  --debug Enable verbose logging
93
92
  --setup Re-run the interactive setup wizard
93
+ --uninstall Remove all hooks from CLI configs and exit
94
94
  ```
95
95
 
96
96
  ## How It Works
package/bin/cli.js CHANGED
@@ -14,8 +14,11 @@ const configPath = join(projectRoot, 'data', 'server-config.json');
14
14
 
15
15
  const args = process.argv.slice(2);
16
16
  const forceSetup = args.includes('--setup');
17
+ const forceUninstall = args.includes('--uninstall');
17
18
  const isFirstRun = !existsSync(configPath);
18
19
 
20
+ const installHooksPath = join(projectRoot, 'hooks', 'install-hooks.js');
21
+
19
22
  function startServer() {
20
23
  const serverArgs = args.filter(a => a !== '--setup');
21
24
  const child = spawn('tsx', [serverPath, ...serverArgs], {
@@ -25,7 +28,14 @@ function startServer() {
25
28
  child.on('exit', (code) => process.exit(code || 0));
26
29
  }
27
30
 
28
- if (forceSetup || isFirstRun) {
31
+ if (forceUninstall) {
32
+ // Run uninstall hooks and exit
33
+ const uninstall = spawn('node', [installHooksPath, '--uninstall'], {
34
+ stdio: 'inherit',
35
+ cwd: projectRoot,
36
+ });
37
+ uninstall.on('exit', (code) => process.exit(code || 0));
38
+ } else if (forceSetup || isFirstRun) {
29
39
  // Run setup wizard, then start server on success
30
40
  const setup = spawn('node', [setupPath], {
31
41
  stdio: 'inherit',
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env node
2
+ // Postinstall script — shows version banner and setup progress
3
+
4
+ import { readFileSync, chmodSync, existsSync, readdirSync } from 'fs';
5
+ import { join, dirname } from 'path';
6
+ import { fileURLToPath } from 'url';
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ const projectRoot = join(__dirname, '..');
10
+
11
+ // ── ANSI colors ──
12
+ const RESET = '\x1b[0m';
13
+ const BOLD = '\x1b[1m';
14
+ const DIM = '\x1b[2m';
15
+ const GREEN = '\x1b[32m';
16
+ const CYAN = '\x1b[36m';
17
+ const YELLOW = '\x1b[33m';
18
+
19
+ // ── Read version from package.json ──
20
+ let version = 'unknown';
21
+ try {
22
+ const pkg = JSON.parse(readFileSync(join(projectRoot, 'package.json'), 'utf8'));
23
+ version = pkg.version;
24
+ } catch { /* ignore */ }
25
+
26
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
27
+
28
+ // ── Animated progress bar ──
29
+ async function animatedProgress(label, stepFn) {
30
+ const width = 30;
31
+ // Animate filling up
32
+ for (let i = 0; i <= width; i += 3) {
33
+ const filled = Math.min(i, width);
34
+ const bar = '█'.repeat(filled) + '░'.repeat(width - filled);
35
+ const pct = Math.round((filled / width) * 100);
36
+ process.stdout.write(`\r ${DIM}${label}${RESET} ${GREEN}${bar}${RESET} ${pct}%`);
37
+ await sleep(20);
38
+ }
39
+ // Run the actual step
40
+ const result = stepFn ? stepFn() : undefined;
41
+ // Complete the bar
42
+ const bar = '█'.repeat(width);
43
+ process.stdout.write(`\r ${DIM}${label}${RESET} ${GREEN}${bar}${RESET} ${GREEN}done${RESET}\n`);
44
+ return result;
45
+ }
46
+
47
+ // ── Banner ──
48
+ console.log('');
49
+ console.log(`${CYAN}╭──────────────────────────────────────────────────────╮${RESET}`);
50
+ console.log(`${CYAN}│${RESET} ${BOLD}AI Agent Session Center${RESET} v${version} ${CYAN}│${RESET}`);
51
+ console.log(`${CYAN}╰──────────────────────────────────────────────────────╯${RESET}`);
52
+ console.log('');
53
+
54
+ // ── Step 1: Fix native module permissions ──
55
+ await animatedProgress('Setting up native modules...', () => {
56
+ if (process.platform !== 'win32') {
57
+ try {
58
+ const prebuildsDir = join(projectRoot, 'node_modules', 'node-pty', 'prebuilds');
59
+ if (existsSync(prebuildsDir)) {
60
+ const dirs = readdirSync(prebuildsDir);
61
+ for (const dir of dirs) {
62
+ const helper = join(prebuildsDir, dir, 'spawn-helper');
63
+ if (existsSync(helper)) {
64
+ chmodSync(helper, 0o755);
65
+ }
66
+ }
67
+ }
68
+ } catch { /* non-critical */ }
69
+ }
70
+ });
71
+
72
+ // ── Step 2: Verify dependencies ──
73
+ const missing = await animatedProgress('Verifying dependencies... ', () => {
74
+ const criticalDeps = ['express', 'ws', 'better-sqlite3', 'tsx'];
75
+ return criticalDeps.filter(dep =>
76
+ !existsSync(join(projectRoot, 'node_modules', dep))
77
+ );
78
+ });
79
+
80
+ // ── Step 3: Finalize ──
81
+ await animatedProgress('Finalizing installation... ');
82
+
83
+ console.log('');
84
+ if (missing.length > 0) {
85
+ console.log(` ${YELLOW}⚠ Missing dependencies: ${missing.join(', ')}${RESET}`);
86
+ console.log(` ${DIM}Run: npm install${RESET}`);
87
+ } else {
88
+ console.log(` ${GREEN}✓${RESET} All dependencies installed`);
89
+ }
90
+
91
+ console.log('');
92
+ console.log(` ${DIM}Start the dashboard:${RESET}`);
93
+ console.log(` ${BOLD}ai-agent-session-center${RESET} ${DIM}# if installed globally${RESET}`);
94
+ console.log(` ${BOLD}npx ai-agent-session-center${RESET} ${DIM}# via npx${RESET}`);
95
+ console.log('');
96
+ console.log(` ${DIM}Options:${RESET}`);
97
+ console.log(` ${BOLD}--setup${RESET} ${DIM}Interactive setup wizard${RESET}`);
98
+ console.log(` ${BOLD}--port 4444${RESET} ${DIM}Custom port${RESET}`);
99
+ console.log(` ${BOLD}--uninstall${RESET} ${DIM}Remove hooks${RESET}`);
100
+ console.log('');
@@ -1 +1 @@
1
- import{j as t,r as m,a as C}from"./index-DC-R8-cX.js";import{u as d}from"./useQuery-CbQQ30QW.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-BMDTSmVW.js";import"./with-selector-R97Q9Knv.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};
1
+ import{j as t,r as m,a as C}from"./index-B30FiFVx.js";import{u as d}from"./useQuery-B1U9OHkP.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-C1wCgvE8.js";import"./with-selector-CjaPkL84.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};