vibemon 1.5.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 +40 -0
- package/assets/characters/apto.png +0 -0
- package/assets/characters/claw.png +0 -0
- package/assets/characters/clawd.png +0 -0
- package/assets/characters/kiro.png +0 -0
- package/assets/generators/generate-icons.js +86 -0
- package/assets/generators/icon-128.png +0 -0
- package/assets/generators/icon-16.png +0 -0
- package/assets/generators/icon-256.png +0 -0
- package/assets/generators/icon-32.png +0 -0
- package/assets/generators/icon-64.png +0 -0
- package/assets/generators/icon-generator.html +221 -0
- package/assets/icon.icns +0 -0
- package/assets/icon.ico +0 -0
- package/assets/icon.png +0 -0
- package/bin/cli.js +16 -0
- package/index.html +26 -0
- package/main.js +358 -0
- package/modules/http-server.cjs +584 -0
- package/modules/http-utils.cjs +110 -0
- package/modules/multi-window-manager.cjs +927 -0
- package/modules/state-manager.cjs +168 -0
- package/modules/tray-manager.cjs +660 -0
- package/modules/validators.cjs +180 -0
- package/modules/ws-client.cjs +313 -0
- package/package.json +112 -0
- package/preload.js +22 -0
- package/renderer.js +84 -0
- package/shared/config.cjs +64 -0
- package/shared/constants.cjs +8 -0
- package/shared/data/constants.json +86 -0
- package/stats.html +521 -0
- package/styles.css +90 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State and timer management for Vibe Monitor (Multi-Window Architecture)
|
|
3
|
+
*
|
|
4
|
+
* Each window manages its own state. StateManager handles:
|
|
5
|
+
* - Per-project timers (state timeouts, window close timeouts)
|
|
6
|
+
* - State data validation
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
IDLE_TIMEOUT, SLEEP_TIMEOUT, WINDOW_CLOSE_TIMEOUT,
|
|
11
|
+
CHARACTER_CONFIG, DEFAULT_CHARACTER
|
|
12
|
+
} = require('../shared/config.cjs');
|
|
13
|
+
|
|
14
|
+
class StateManager {
|
|
15
|
+
constructor() {
|
|
16
|
+
// Per-project timers
|
|
17
|
+
this.stateTimeoutTimers = new Map();
|
|
18
|
+
this.windowCloseTimers = new Map();
|
|
19
|
+
|
|
20
|
+
// Callbacks (set by main.js)
|
|
21
|
+
this.onStateTimeout = null; // (projectId, newState) => void
|
|
22
|
+
this.onWindowCloseTimeout = null; // (projectId) => void
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Timer management - per project
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Clear state timeout timer for a specific project
|
|
29
|
+
* @param {string} projectId - Project identifier
|
|
30
|
+
*/
|
|
31
|
+
clearStateTimeout(projectId) {
|
|
32
|
+
const timer = this.stateTimeoutTimers.get(projectId);
|
|
33
|
+
if (timer) {
|
|
34
|
+
clearTimeout(timer);
|
|
35
|
+
this.stateTimeoutTimers.delete(projectId);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Clear window close timer for a specific project
|
|
41
|
+
* @param {string} projectId - Project identifier
|
|
42
|
+
*/
|
|
43
|
+
clearWindowCloseTimer(projectId) {
|
|
44
|
+
const timer = this.windowCloseTimers.get(projectId);
|
|
45
|
+
if (timer) {
|
|
46
|
+
clearTimeout(timer);
|
|
47
|
+
this.windowCloseTimers.delete(projectId);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Set up window close timer for a project in sleep state
|
|
53
|
+
* @param {string} projectId - Project identifier
|
|
54
|
+
* @param {string} currentState - Current state of the project
|
|
55
|
+
*/
|
|
56
|
+
setupWindowCloseTimer(projectId, currentState) {
|
|
57
|
+
this.clearWindowCloseTimer(projectId);
|
|
58
|
+
|
|
59
|
+
if (currentState === 'sleep' && this.onWindowCloseTimeout) {
|
|
60
|
+
const timer = setTimeout(() => {
|
|
61
|
+
this.windowCloseTimers.delete(projectId);
|
|
62
|
+
this.onWindowCloseTimeout(projectId);
|
|
63
|
+
}, WINDOW_CLOSE_TIMEOUT);
|
|
64
|
+
this.windowCloseTimers.set(projectId, timer);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Set up state timeout for automatic state transitions
|
|
70
|
+
* @param {string} projectId - Project identifier
|
|
71
|
+
* @param {string} currentState - Current state of the project
|
|
72
|
+
*/
|
|
73
|
+
setupStateTimeout(projectId, currentState) {
|
|
74
|
+
this.clearStateTimeout(projectId);
|
|
75
|
+
this.clearWindowCloseTimer(projectId);
|
|
76
|
+
|
|
77
|
+
if (currentState === 'start' || currentState === 'done') {
|
|
78
|
+
// start/done -> idle after 1 minute
|
|
79
|
+
const timer = setTimeout(() => {
|
|
80
|
+
this.stateTimeoutTimers.delete(projectId);
|
|
81
|
+
if (this.onStateTimeout) {
|
|
82
|
+
this.onStateTimeout(projectId, 'idle');
|
|
83
|
+
}
|
|
84
|
+
}, IDLE_TIMEOUT);
|
|
85
|
+
this.stateTimeoutTimers.set(projectId, timer);
|
|
86
|
+
} else if (currentState === 'planning' || currentState === 'thinking' ||
|
|
87
|
+
currentState === 'working' || currentState === 'notification') {
|
|
88
|
+
// planning/thinking/working/notification -> idle after 5 minutes
|
|
89
|
+
const timer = setTimeout(() => {
|
|
90
|
+
this.stateTimeoutTimers.delete(projectId);
|
|
91
|
+
if (this.onStateTimeout) {
|
|
92
|
+
this.onStateTimeout(projectId, 'idle');
|
|
93
|
+
}
|
|
94
|
+
}, SLEEP_TIMEOUT);
|
|
95
|
+
this.stateTimeoutTimers.set(projectId, timer);
|
|
96
|
+
} else if (currentState === 'idle') {
|
|
97
|
+
// idle -> sleep after 5 minutes
|
|
98
|
+
const timer = setTimeout(() => {
|
|
99
|
+
this.stateTimeoutTimers.delete(projectId);
|
|
100
|
+
if (this.onStateTimeout) {
|
|
101
|
+
this.onStateTimeout(projectId, 'sleep');
|
|
102
|
+
}
|
|
103
|
+
}, SLEEP_TIMEOUT);
|
|
104
|
+
this.stateTimeoutTimers.set(projectId, timer);
|
|
105
|
+
} else if (currentState === 'sleep') {
|
|
106
|
+
// sleep -> close window after 10 minutes
|
|
107
|
+
this.setupWindowCloseTimer(projectId, currentState);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Validation
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Validate and normalize state data
|
|
115
|
+
* @param {Object} data - Incoming state data
|
|
116
|
+
* @returns {Object} Normalized data with validated character field
|
|
117
|
+
*/
|
|
118
|
+
validateStateData(data) {
|
|
119
|
+
if (!data || typeof data !== 'object') {
|
|
120
|
+
return { valid: false, error: 'Invalid data format' };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Create a new normalized data object (immutability)
|
|
124
|
+
const normalized = { ...data };
|
|
125
|
+
|
|
126
|
+
// Validate and normalize character field
|
|
127
|
+
if (normalized.character !== undefined) {
|
|
128
|
+
normalized.character = CHARACTER_CONFIG[normalized.character]
|
|
129
|
+
? normalized.character
|
|
130
|
+
: DEFAULT_CHARACTER;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
valid: true,
|
|
135
|
+
data: normalized
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Cleanup
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Clear all timers for a specific project
|
|
143
|
+
* @param {string} projectId - Project identifier
|
|
144
|
+
*/
|
|
145
|
+
cleanupProject(projectId) {
|
|
146
|
+
this.clearStateTimeout(projectId);
|
|
147
|
+
this.clearWindowCloseTimer(projectId);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Clear all timers for all projects
|
|
152
|
+
*/
|
|
153
|
+
cleanup() {
|
|
154
|
+
// Clear all state timeout timers
|
|
155
|
+
for (const [, timer] of this.stateTimeoutTimers) {
|
|
156
|
+
clearTimeout(timer);
|
|
157
|
+
}
|
|
158
|
+
this.stateTimeoutTimers.clear();
|
|
159
|
+
|
|
160
|
+
// Clear all window close timers
|
|
161
|
+
for (const [, timer] of this.windowCloseTimers) {
|
|
162
|
+
clearTimeout(timer);
|
|
163
|
+
}
|
|
164
|
+
this.windowCloseTimers.clear();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
module.exports = { StateManager };
|