ai-agent-session-center 1.0.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.
Files changed (41) hide show
  1. package/README.md +618 -0
  2. package/bin/cli.js +20 -0
  3. package/hooks/dashboard-hook-codex.sh +67 -0
  4. package/hooks/dashboard-hook-gemini.sh +102 -0
  5. package/hooks/dashboard-hook.ps1 +147 -0
  6. package/hooks/dashboard-hook.sh +142 -0
  7. package/hooks/dashboard-hooks-backup.json +103 -0
  8. package/hooks/install-hooks.js +543 -0
  9. package/hooks/reset.js +357 -0
  10. package/hooks/setup-wizard.js +156 -0
  11. package/package.json +52 -0
  12. package/public/css/dashboard.css +10200 -0
  13. package/public/index.html +915 -0
  14. package/public/js/analyticsPanel.js +467 -0
  15. package/public/js/app.js +1148 -0
  16. package/public/js/browserDb.js +806 -0
  17. package/public/js/chartUtils.js +383 -0
  18. package/public/js/historyPanel.js +298 -0
  19. package/public/js/movementManager.js +155 -0
  20. package/public/js/navController.js +32 -0
  21. package/public/js/robotManager.js +526 -0
  22. package/public/js/sceneManager.js +7 -0
  23. package/public/js/sessionPanel.js +2477 -0
  24. package/public/js/settingsManager.js +924 -0
  25. package/public/js/soundManager.js +249 -0
  26. package/public/js/statsPanel.js +118 -0
  27. package/public/js/terminalManager.js +391 -0
  28. package/public/js/timelinePanel.js +278 -0
  29. package/public/js/wsClient.js +88 -0
  30. package/server/apiRouter.js +321 -0
  31. package/server/config.js +120 -0
  32. package/server/hookProcessor.js +55 -0
  33. package/server/hookRouter.js +18 -0
  34. package/server/hookStats.js +107 -0
  35. package/server/index.js +314 -0
  36. package/server/logger.js +67 -0
  37. package/server/mqReader.js +218 -0
  38. package/server/serverConfig.js +27 -0
  39. package/server/sessionStore.js +1049 -0
  40. package/server/sshManager.js +339 -0
  41. package/server/wsManager.js +83 -0
@@ -0,0 +1,155 @@
1
+ // movementManager.js — Per-action movement effect configuration
2
+ // Mirrors the soundManager pattern: each action can be assigned a movement effect.
3
+
4
+ import * as settingsManager from './settingsManager.js';
5
+
6
+ // Available movement effects library
7
+ const effectLibrary = {
8
+ none: 'None',
9
+ sweat: 'Sweat Drops',
10
+ 'energy-ring':'Energy Ring',
11
+ sparks: 'Sparks',
12
+ steam: 'Steam',
13
+ 'eye-cycle': 'Eye Cycle',
14
+ 'think-pulse':'Think Pulse',
15
+ 'head-tilt': 'Head Tilt',
16
+ float: 'Float',
17
+ breathe: 'Breathe',
18
+ sway: 'Sway',
19
+ sparkle: 'Sparkle',
20
+ bounce: 'Bounce',
21
+ flash: 'Flash Glow',
22
+ shake: 'Shake',
23
+ fade: 'Fade Out',
24
+ shrink: 'Shrink',
25
+ dissolve: 'Dissolve',
26
+ questions: 'Question Marks',
27
+ };
28
+
29
+ // Default effect for each action
30
+ const defaultActionEffects = {
31
+ sessionStart: 'sparkle',
32
+ sessionEnd: 'fade',
33
+ promptSubmit: 'eye-cycle',
34
+ taskComplete: 'bounce',
35
+ toolRead: 'eye-cycle',
36
+ toolWrite: 'sweat',
37
+ toolEdit: 'sweat',
38
+ toolBash: 'energy-ring',
39
+ toolGrep: 'eye-cycle',
40
+ toolGlob: 'eye-cycle',
41
+ toolWebFetch: 'steam',
42
+ toolTask: 'sparks',
43
+ toolOther: 'sweat',
44
+ approvalNeeded: 'shake',
45
+ inputNeeded: 'sparkle',
46
+ alert: 'flash',
47
+ kill: 'dissolve',
48
+ archive: 'shrink',
49
+ subagentStart: 'sparkle',
50
+ subagentStop: 'fade',
51
+ };
52
+
53
+ const actionLabels = {
54
+ sessionStart: 'Session Start',
55
+ sessionEnd: 'Session End',
56
+ promptSubmit: 'Prompt Submit',
57
+ taskComplete: 'Task Complete',
58
+ toolRead: 'Tool: Read',
59
+ toolWrite: 'Tool: Write',
60
+ toolEdit: 'Tool: Edit',
61
+ toolBash: 'Tool: Bash',
62
+ toolGrep: 'Tool: Grep',
63
+ toolGlob: 'Tool: Glob',
64
+ toolWebFetch: 'Tool: WebFetch',
65
+ toolTask: 'Tool: Task',
66
+ toolOther: 'Tool: Other',
67
+ approvalNeeded: 'Approval Needed',
68
+ inputNeeded: 'Input Needed',
69
+ alert: 'Alert',
70
+ kill: 'Kill',
71
+ archive: 'Archive',
72
+ subagentStart: 'Subagent Start',
73
+ subagentStop: 'Subagent Stop',
74
+ };
75
+
76
+ const actionCategories = {
77
+ 'Session Events': ['sessionStart', 'sessionEnd', 'promptSubmit', 'taskComplete'],
78
+ 'Tool Calls': ['toolRead', 'toolWrite', 'toolEdit', 'toolBash', 'toolGrep', 'toolGlob', 'toolWebFetch', 'toolTask', 'toolOther'],
79
+ 'System': ['approvalNeeded', 'inputNeeded', 'alert', 'kill', 'archive', 'subagentStart', 'subagentStop'],
80
+ };
81
+
82
+ let actionEffects = {};
83
+
84
+ // Active effects per session: sessionId -> { timer, effect }
85
+ const activeEffects = new Map();
86
+
87
+ export function init() {
88
+ const saved = settingsManager.get('movementActions');
89
+ if (saved) {
90
+ try {
91
+ actionEffects = JSON.parse(saved);
92
+ } catch (e) {
93
+ actionEffects = {};
94
+ }
95
+ }
96
+ }
97
+
98
+ export function getEffectLibrary() {
99
+ return { ...effectLibrary };
100
+ }
101
+
102
+ export function getActionEffects() {
103
+ return { ...defaultActionEffects, ...actionEffects };
104
+ }
105
+
106
+ export function getActionLabels() {
107
+ return { ...actionLabels };
108
+ }
109
+
110
+ export function getActionCategories() {
111
+ return actionCategories;
112
+ }
113
+
114
+ export function setActionEffect(action, effectName) {
115
+ actionEffects[action] = effectName;
116
+ settingsManager.set('movementActions', JSON.stringify(actionEffects));
117
+ }
118
+
119
+ /**
120
+ * Trigger a movement effect on a session's character element.
121
+ * The effect is applied as a data-attribute so CSS can activate the right animation.
122
+ * Effects auto-clear after a duration (except for persistent status effects).
123
+ */
124
+ export function trigger(actionName, sessionId) {
125
+ const effectName = actionEffects[actionName] || defaultActionEffects[actionName] || 'none';
126
+ if (effectName === 'none') return;
127
+
128
+ // Find the session card's character element
129
+ const card = document.querySelector(`.session-card[data-id="${sessionId}"] .css-robot`);
130
+ if (!card) return;
131
+
132
+ // Clear any previous triggered effect
133
+ clearEffect(sessionId);
134
+
135
+ // Apply the effect
136
+ card.setAttribute('data-movement', effectName);
137
+
138
+ // Auto-clear after duration (persistent status effects like sweat are handled by CSS status selectors)
139
+ const timer = setTimeout(() => {
140
+ card.removeAttribute('data-movement');
141
+ activeEffects.delete(sessionId);
142
+ }, 3500);
143
+
144
+ activeEffects.set(sessionId, { timer, effect: effectName });
145
+ }
146
+
147
+ export function clearEffect(sessionId) {
148
+ const existing = activeEffects.get(sessionId);
149
+ if (existing) {
150
+ clearTimeout(existing.timer);
151
+ activeEffects.delete(sessionId);
152
+ }
153
+ const card = document.querySelector(`.session-card[data-id="${sessionId}"] .css-robot`);
154
+ if (card) card.removeAttribute('data-movement');
155
+ }
@@ -0,0 +1,32 @@
1
+ const views = ['live', 'history', 'timeline', 'analytics'];
2
+ const callbacks = {};
3
+
4
+ export function init() {
5
+ document.getElementById('main-nav').addEventListener('click', (e) => {
6
+ const btn = e.target.closest('.nav-btn');
7
+ if (!btn) return;
8
+ const view = btn.dataset.view;
9
+ switchTo(view);
10
+ });
11
+ }
12
+
13
+ export function onViewChange(viewName, callback) {
14
+ callbacks[viewName] = callback;
15
+ }
16
+
17
+ export function switchTo(viewName) {
18
+ // Toggle active class on nav buttons
19
+ document.querySelectorAll('.nav-btn').forEach(b => b.classList.toggle('active', b.dataset.view === viewName));
20
+ // Toggle active class on view panels
21
+ views.forEach(v => {
22
+ const panel = document.getElementById(`view-${v}`);
23
+ if (panel) panel.classList.toggle('active', v === viewName);
24
+ if (panel) panel.classList.toggle('hidden', v !== viewName);
25
+ });
26
+ // Call view callback
27
+ if (callbacks[viewName]) callbacks[viewName]();
28
+ }
29
+
30
+ export function getCurrentView() {
31
+ return document.querySelector('.nav-btn.active')?.dataset.view || 'live';
32
+ }