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.
- package/README.md +618 -0
- package/bin/cli.js +20 -0
- package/hooks/dashboard-hook-codex.sh +67 -0
- package/hooks/dashboard-hook-gemini.sh +102 -0
- package/hooks/dashboard-hook.ps1 +147 -0
- package/hooks/dashboard-hook.sh +142 -0
- package/hooks/dashboard-hooks-backup.json +103 -0
- package/hooks/install-hooks.js +543 -0
- package/hooks/reset.js +357 -0
- package/hooks/setup-wizard.js +156 -0
- package/package.json +52 -0
- package/public/css/dashboard.css +10200 -0
- package/public/index.html +915 -0
- package/public/js/analyticsPanel.js +467 -0
- package/public/js/app.js +1148 -0
- package/public/js/browserDb.js +806 -0
- package/public/js/chartUtils.js +383 -0
- package/public/js/historyPanel.js +298 -0
- package/public/js/movementManager.js +155 -0
- package/public/js/navController.js +32 -0
- package/public/js/robotManager.js +526 -0
- package/public/js/sceneManager.js +7 -0
- package/public/js/sessionPanel.js +2477 -0
- package/public/js/settingsManager.js +924 -0
- package/public/js/soundManager.js +249 -0
- package/public/js/statsPanel.js +118 -0
- package/public/js/terminalManager.js +391 -0
- package/public/js/timelinePanel.js +278 -0
- package/public/js/wsClient.js +88 -0
- package/server/apiRouter.js +321 -0
- package/server/config.js +120 -0
- package/server/hookProcessor.js +55 -0
- package/server/hookRouter.js +18 -0
- package/server/hookStats.js +107 -0
- package/server/index.js +314 -0
- package/server/logger.js +67 -0
- package/server/mqReader.js +218 -0
- package/server/serverConfig.js +27 -0
- package/server/sessionStore.js +1049 -0
- package/server/sshManager.js +339 -0
- 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
|
+
}
|