@co0ontty/wand 1.39.1 → 1.40.1

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.
@@ -1,176 +0,0 @@
1
- /**
2
- * Session Lifecycle Manager
3
- * Inspired by Happy's session lifecycle management
4
- */
5
- export class SessionLifecycleManager {
6
- sessions = new Map();
7
- events;
8
- idleTimeout;
9
- archiveTimeout;
10
- checkInterval = null;
11
- constructor(events = {}, options = {}) {
12
- this.events = events;
13
- this.idleTimeout = options.idleTimeout ?? 5 * 60 * 1000; // 5 minutes
14
- this.archiveTimeout = options.archiveTimeout ?? 30 * 60 * 1000; // 30 minutes
15
- // Start periodic check
16
- this.startPeriodicCheck();
17
- }
18
- /**
19
- * Register a new session
20
- */
21
- register(sessionId, initialState = "initializing") {
22
- const lifecycle = {
23
- state: initialState,
24
- stateSince: Date.now(),
25
- lastActivityAt: Date.now(),
26
- };
27
- this.sessions.set(sessionId, lifecycle);
28
- }
29
- /**
30
- * Update session state
31
- */
32
- setState(sessionId, newState) {
33
- const lifecycle = this.sessions.get(sessionId);
34
- if (!lifecycle) {
35
- return;
36
- }
37
- const oldState = lifecycle.state;
38
- if (oldState === newState) {
39
- return;
40
- }
41
- lifecycle.state = newState;
42
- lifecycle.stateSince = Date.now();
43
- lifecycle.lastActivityAt = Date.now();
44
- // Emit state change event
45
- this.events.onStateChange?.(sessionId, oldState, newState);
46
- }
47
- /**
48
- * Update last activity timestamp
49
- */
50
- touch(sessionId) {
51
- const lifecycle = this.sessions.get(sessionId);
52
- if (lifecycle) {
53
- lifecycle.lastActivityAt = Date.now();
54
- }
55
- }
56
- /**
57
- * Mark session as thinking
58
- */
59
- startThinking(sessionId) {
60
- this.setState(sessionId, "thinking");
61
- }
62
- /**
63
- * Mark session as done thinking
64
- */
65
- stopThinking(sessionId) {
66
- const lifecycle = this.sessions.get(sessionId);
67
- if (lifecycle?.state === "thinking") {
68
- this.setState(sessionId, "idle");
69
- }
70
- }
71
- /**
72
- * Mark session as waiting for input
73
- */
74
- waitingInput(sessionId) {
75
- this.setState(sessionId, "waiting-input");
76
- }
77
- /**
78
- * Archive a session
79
- */
80
- archive(sessionId, reason, by = "user") {
81
- const lifecycle = this.sessions.get(sessionId);
82
- if (!lifecycle) {
83
- return;
84
- }
85
- lifecycle.state = "archived";
86
- lifecycle.stateSince = Date.now();
87
- lifecycle.archivedBy = by;
88
- lifecycle.archiveReason = reason;
89
- // Emit archived event
90
- this.events.onArchived?.(sessionId, reason);
91
- }
92
- /**
93
- * Unregister a session
94
- */
95
- unregister(sessionId) {
96
- this.sessions.delete(sessionId);
97
- }
98
- /**
99
- * Get session lifecycle
100
- */
101
- get(sessionId) {
102
- return this.sessions.get(sessionId);
103
- }
104
- /**
105
- * Get all sessions
106
- */
107
- getAll() {
108
- return new Map(this.sessions);
109
- }
110
- /**
111
- * Get sessions by state
112
- */
113
- getByState(state) {
114
- const result = [];
115
- for (const [sessionId, lifecycle] of this.sessions) {
116
- if (lifecycle.state === state) {
117
- result.push(sessionId);
118
- }
119
- }
120
- return result;
121
- }
122
- /**
123
- * Start periodic check for idle/archived sessions
124
- */
125
- startPeriodicCheck() {
126
- if (this.checkInterval) {
127
- return;
128
- }
129
- this.checkInterval = setInterval(() => {
130
- this.checkSessions();
131
- }, 60 * 1000); // Check every minute
132
- }
133
- /**
134
- * Stop periodic check
135
- */
136
- stopPeriodicCheck() {
137
- if (this.checkInterval) {
138
- clearInterval(this.checkInterval);
139
- this.checkInterval = null;
140
- }
141
- }
142
- /**
143
- * Check sessions for idle/archived status
144
- */
145
- checkSessions() {
146
- const now = Date.now();
147
- for (const [sessionId, lifecycle] of this.sessions) {
148
- try {
149
- if (lifecycle.state === "archived") {
150
- continue;
151
- }
152
- const timeSinceLastActivity = now - lifecycle.lastActivityAt;
153
- // Check for archive timeout
154
- if (timeSinceLastActivity > this.archiveTimeout) {
155
- this.archive(sessionId, "Session timed out", "timeout");
156
- continue;
157
- }
158
- // Check for idle timeout
159
- if (timeSinceLastActivity > this.idleTimeout && lifecycle.state !== "idle") {
160
- this.setState(sessionId, "idle");
161
- this.events.onIdle?.(sessionId);
162
- }
163
- }
164
- catch (err) {
165
- console.error(`[Lifecycle] Error checking session ${sessionId}: ${String(err)}`);
166
- }
167
- }
168
- }
169
- /**
170
- * Cleanup all sessions
171
- */
172
- cleanup() {
173
- this.stopPeriodicCheck();
174
- this.sessions.clear();
175
- }
176
- }