code-squad-cli 1.2.17 → 1.2.20
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.
|
@@ -6,10 +6,10 @@ export interface Session {
|
|
|
6
6
|
cwd: string;
|
|
7
7
|
/** FileWatcher instance for this session */
|
|
8
8
|
watcher: FileWatcher;
|
|
9
|
-
/** Last activity timestamp (ms since epoch) */
|
|
10
|
-
lastActivity: number;
|
|
11
9
|
/** Changed files since last poll (for polling-based sync) */
|
|
12
10
|
pendingChanges: PendingChanges;
|
|
11
|
+
/** Timeout timer for session expiration */
|
|
12
|
+
timeoutTimer: ReturnType<typeof setTimeout> | null;
|
|
13
13
|
}
|
|
14
14
|
export interface PendingChanges {
|
|
15
15
|
filesChanged: boolean;
|
|
@@ -25,10 +25,9 @@ export interface SessionManagerOptions {
|
|
|
25
25
|
export declare class SessionManager {
|
|
26
26
|
private sessions;
|
|
27
27
|
private options;
|
|
28
|
-
private cleanupInterval;
|
|
29
28
|
constructor(options: SessionManagerOptions);
|
|
30
29
|
/**
|
|
31
|
-
* Start the session
|
|
30
|
+
* Start the session manager (no-op, kept for API compatibility)
|
|
32
31
|
*/
|
|
33
32
|
start(): void;
|
|
34
33
|
/**
|
|
@@ -40,15 +39,15 @@ export declare class SessionManager {
|
|
|
40
39
|
*/
|
|
41
40
|
registerSession(sessionId: string, cwd: string): Session;
|
|
42
41
|
/**
|
|
43
|
-
* Get a session by ID and
|
|
42
|
+
* Get a session by ID and reset timeout
|
|
44
43
|
*/
|
|
45
44
|
getSession(sessionId: string): Session | undefined;
|
|
46
45
|
/**
|
|
47
|
-
* Touch session to
|
|
46
|
+
* Touch session to reset timeout (called on every API request)
|
|
48
47
|
*/
|
|
49
48
|
touchSession(sessionId: string): void;
|
|
50
49
|
/**
|
|
51
|
-
* Unregister a session (e.g., on cancel/submit)
|
|
50
|
+
* Unregister a session (e.g., on cancel/submit/timeout)
|
|
52
51
|
*/
|
|
53
52
|
unregisterSession(sessionId: string): Promise<void>;
|
|
54
53
|
/**
|
|
@@ -65,5 +64,9 @@ export declare class SessionManager {
|
|
|
65
64
|
get hasSessions(): boolean;
|
|
66
65
|
private createWatcher;
|
|
67
66
|
private createEmptyPendingChanges;
|
|
68
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Reset the timeout timer for a session.
|
|
69
|
+
* Called on every activity (register, poll, etc.)
|
|
70
|
+
*/
|
|
71
|
+
private resetSessionTimeout;
|
|
69
72
|
}
|
|
@@ -3,29 +3,26 @@ const log = (...args) => console.error(...args);
|
|
|
3
3
|
export class SessionManager {
|
|
4
4
|
sessions = new Map();
|
|
5
5
|
options;
|
|
6
|
-
cleanupInterval = null;
|
|
7
6
|
constructor(options) {
|
|
8
7
|
this.options = options;
|
|
9
8
|
}
|
|
10
9
|
/**
|
|
11
|
-
* Start the session
|
|
10
|
+
* Start the session manager (no-op, kept for API compatibility)
|
|
12
11
|
*/
|
|
13
12
|
start() {
|
|
14
|
-
//
|
|
15
|
-
this.cleanupInterval = setInterval(() => {
|
|
16
|
-
this.cleanupTimedOutSessions();
|
|
17
|
-
}, 5000);
|
|
13
|
+
// No longer uses periodic cleanup - each session has its own timeout
|
|
18
14
|
}
|
|
19
15
|
/**
|
|
20
16
|
* Stop the session manager and clean up all sessions
|
|
21
17
|
*/
|
|
22
18
|
async stop() {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
// Clear all session timeouts and stop watchers
|
|
20
|
+
const stopPromises = Array.from(this.sessions.values()).map(session => {
|
|
21
|
+
if (session.timeoutTimer) {
|
|
22
|
+
clearTimeout(session.timeoutTimer);
|
|
23
|
+
}
|
|
24
|
+
return session.watcher.stop();
|
|
25
|
+
});
|
|
29
26
|
await Promise.all(stopPromises);
|
|
30
27
|
this.sessions.clear();
|
|
31
28
|
}
|
|
@@ -35,8 +32,8 @@ export class SessionManager {
|
|
|
35
32
|
registerSession(sessionId, cwd) {
|
|
36
33
|
const existing = this.sessions.get(sessionId);
|
|
37
34
|
if (existing) {
|
|
38
|
-
//
|
|
39
|
-
|
|
35
|
+
// Reset timeout on activity
|
|
36
|
+
this.resetSessionTimeout(sessionId);
|
|
40
37
|
// If cwd changed, need to restart watcher
|
|
41
38
|
if (existing.cwd !== cwd) {
|
|
42
39
|
existing.watcher.stop();
|
|
@@ -52,38 +49,40 @@ export class SessionManager {
|
|
|
52
49
|
id: sessionId,
|
|
53
50
|
cwd,
|
|
54
51
|
watcher,
|
|
55
|
-
lastActivity: Date.now(),
|
|
56
52
|
pendingChanges: this.createEmptyPendingChanges(),
|
|
53
|
+
timeoutTimer: null,
|
|
57
54
|
};
|
|
58
55
|
this.sessions.set(sessionId, session);
|
|
56
|
+
this.resetSessionTimeout(sessionId);
|
|
59
57
|
log(`[SessionManager] Session registered: ${sessionId} (cwd: ${cwd})`);
|
|
60
58
|
return session;
|
|
61
59
|
}
|
|
62
60
|
/**
|
|
63
|
-
* Get a session by ID and
|
|
61
|
+
* Get a session by ID and reset timeout
|
|
64
62
|
*/
|
|
65
63
|
getSession(sessionId) {
|
|
66
64
|
const session = this.sessions.get(sessionId);
|
|
67
65
|
if (session) {
|
|
68
|
-
|
|
66
|
+
this.resetSessionTimeout(sessionId);
|
|
69
67
|
}
|
|
70
68
|
return session;
|
|
71
69
|
}
|
|
72
70
|
/**
|
|
73
|
-
* Touch session to
|
|
71
|
+
* Touch session to reset timeout (called on every API request)
|
|
74
72
|
*/
|
|
75
73
|
touchSession(sessionId) {
|
|
76
|
-
|
|
77
|
-
if (session) {
|
|
78
|
-
session.lastActivity = Date.now();
|
|
79
|
-
}
|
|
74
|
+
this.resetSessionTimeout(sessionId);
|
|
80
75
|
}
|
|
81
76
|
/**
|
|
82
|
-
* Unregister a session (e.g., on cancel/submit)
|
|
77
|
+
* Unregister a session (e.g., on cancel/submit/timeout)
|
|
83
78
|
*/
|
|
84
79
|
async unregisterSession(sessionId) {
|
|
85
80
|
const session = this.sessions.get(sessionId);
|
|
86
81
|
if (session) {
|
|
82
|
+
// Clear timeout timer
|
|
83
|
+
if (session.timeoutTimer) {
|
|
84
|
+
clearTimeout(session.timeoutTimer);
|
|
85
|
+
}
|
|
87
86
|
await session.watcher.stop();
|
|
88
87
|
this.sessions.delete(sessionId);
|
|
89
88
|
log(`[SessionManager] Session unregistered: ${sessionId}`);
|
|
@@ -147,17 +146,24 @@ export class SessionManager {
|
|
|
147
146
|
changedFiles: new Set(),
|
|
148
147
|
};
|
|
149
148
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Reset the timeout timer for a session.
|
|
151
|
+
* Called on every activity (register, poll, etc.)
|
|
152
|
+
*/
|
|
153
|
+
resetSessionTimeout(sessionId) {
|
|
154
|
+
const session = this.sessions.get(sessionId);
|
|
155
|
+
if (!session)
|
|
156
|
+
return;
|
|
157
|
+
// Clear existing timeout
|
|
158
|
+
if (session.timeoutTimer) {
|
|
159
|
+
clearTimeout(session.timeoutTimer);
|
|
157
160
|
}
|
|
158
|
-
|
|
161
|
+
// Set new timeout
|
|
162
|
+
session.timeoutTimer = setTimeout(() => {
|
|
159
163
|
log(`[SessionManager] Session timed out: ${sessionId}`);
|
|
160
|
-
this.unregisterSession(sessionId)
|
|
161
|
-
|
|
164
|
+
this.unregisterSession(sessionId).catch(error => {
|
|
165
|
+
log(`[SessionManager] Error during session unregister for ${sessionId}:`, error);
|
|
166
|
+
});
|
|
167
|
+
}, this.options.sessionTimeoutMs);
|
|
162
168
|
}
|
|
163
169
|
}
|
package/dist/index.js
CHANGED
|
@@ -1265,8 +1265,7 @@ function createSessionRouter(sessionManager) {
|
|
|
1265
1265
|
}
|
|
1266
1266
|
res.json({
|
|
1267
1267
|
session_id: session.id,
|
|
1268
|
-
cwd: session.cwd
|
|
1269
|
-
lastActivity: session.lastActivity
|
|
1268
|
+
cwd: session.cwd
|
|
1270
1269
|
});
|
|
1271
1270
|
});
|
|
1272
1271
|
return router6;
|
|
@@ -1426,27 +1425,24 @@ var log = (...args) => console.error(...args);
|
|
|
1426
1425
|
var SessionManager = class {
|
|
1427
1426
|
sessions = /* @__PURE__ */ new Map();
|
|
1428
1427
|
options;
|
|
1429
|
-
cleanupInterval = null;
|
|
1430
1428
|
constructor(options) {
|
|
1431
1429
|
this.options = options;
|
|
1432
1430
|
}
|
|
1433
1431
|
/**
|
|
1434
|
-
* Start the session
|
|
1432
|
+
* Start the session manager (no-op, kept for API compatibility)
|
|
1435
1433
|
*/
|
|
1436
1434
|
start() {
|
|
1437
|
-
this.cleanupInterval = setInterval(() => {
|
|
1438
|
-
this.cleanupTimedOutSessions();
|
|
1439
|
-
}, 5e3);
|
|
1440
1435
|
}
|
|
1441
1436
|
/**
|
|
1442
1437
|
* Stop the session manager and clean up all sessions
|
|
1443
1438
|
*/
|
|
1444
1439
|
async stop() {
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1440
|
+
const stopPromises = Array.from(this.sessions.values()).map((session) => {
|
|
1441
|
+
if (session.timeoutTimer) {
|
|
1442
|
+
clearTimeout(session.timeoutTimer);
|
|
1443
|
+
}
|
|
1444
|
+
return session.watcher.stop();
|
|
1445
|
+
});
|
|
1450
1446
|
await Promise.all(stopPromises);
|
|
1451
1447
|
this.sessions.clear();
|
|
1452
1448
|
}
|
|
@@ -1456,7 +1452,7 @@ var SessionManager = class {
|
|
|
1456
1452
|
registerSession(sessionId, cwd) {
|
|
1457
1453
|
const existing = this.sessions.get(sessionId);
|
|
1458
1454
|
if (existing) {
|
|
1459
|
-
|
|
1455
|
+
this.resetSessionTimeout(sessionId);
|
|
1460
1456
|
if (existing.cwd !== cwd) {
|
|
1461
1457
|
existing.watcher.stop();
|
|
1462
1458
|
existing.cwd = cwd;
|
|
@@ -1470,38 +1466,39 @@ var SessionManager = class {
|
|
|
1470
1466
|
id: sessionId,
|
|
1471
1467
|
cwd,
|
|
1472
1468
|
watcher,
|
|
1473
|
-
|
|
1474
|
-
|
|
1469
|
+
pendingChanges: this.createEmptyPendingChanges(),
|
|
1470
|
+
timeoutTimer: null
|
|
1475
1471
|
};
|
|
1476
1472
|
this.sessions.set(sessionId, session);
|
|
1473
|
+
this.resetSessionTimeout(sessionId);
|
|
1477
1474
|
log(`[SessionManager] Session registered: ${sessionId} (cwd: ${cwd})`);
|
|
1478
1475
|
return session;
|
|
1479
1476
|
}
|
|
1480
1477
|
/**
|
|
1481
|
-
* Get a session by ID and
|
|
1478
|
+
* Get a session by ID and reset timeout
|
|
1482
1479
|
*/
|
|
1483
1480
|
getSession(sessionId) {
|
|
1484
1481
|
const session = this.sessions.get(sessionId);
|
|
1485
1482
|
if (session) {
|
|
1486
|
-
|
|
1483
|
+
this.resetSessionTimeout(sessionId);
|
|
1487
1484
|
}
|
|
1488
1485
|
return session;
|
|
1489
1486
|
}
|
|
1490
1487
|
/**
|
|
1491
|
-
* Touch session to
|
|
1488
|
+
* Touch session to reset timeout (called on every API request)
|
|
1492
1489
|
*/
|
|
1493
1490
|
touchSession(sessionId) {
|
|
1494
|
-
|
|
1495
|
-
if (session) {
|
|
1496
|
-
session.lastActivity = Date.now();
|
|
1497
|
-
}
|
|
1491
|
+
this.resetSessionTimeout(sessionId);
|
|
1498
1492
|
}
|
|
1499
1493
|
/**
|
|
1500
|
-
* Unregister a session (e.g., on cancel/submit)
|
|
1494
|
+
* Unregister a session (e.g., on cancel/submit/timeout)
|
|
1501
1495
|
*/
|
|
1502
1496
|
async unregisterSession(sessionId) {
|
|
1503
1497
|
const session = this.sessions.get(sessionId);
|
|
1504
1498
|
if (session) {
|
|
1499
|
+
if (session.timeoutTimer) {
|
|
1500
|
+
clearTimeout(session.timeoutTimer);
|
|
1501
|
+
}
|
|
1505
1502
|
await session.watcher.stop();
|
|
1506
1503
|
this.sessions.delete(sessionId);
|
|
1507
1504
|
log(`[SessionManager] Session unregistered: ${sessionId}`);
|
|
@@ -1564,18 +1561,23 @@ var SessionManager = class {
|
|
|
1564
1561
|
changedFiles: /* @__PURE__ */ new Set()
|
|
1565
1562
|
};
|
|
1566
1563
|
}
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1564
|
+
/**
|
|
1565
|
+
* Reset the timeout timer for a session.
|
|
1566
|
+
* Called on every activity (register, poll, etc.)
|
|
1567
|
+
*/
|
|
1568
|
+
resetSessionTimeout(sessionId) {
|
|
1569
|
+
const session = this.sessions.get(sessionId);
|
|
1570
|
+
if (!session)
|
|
1571
|
+
return;
|
|
1572
|
+
if (session.timeoutTimer) {
|
|
1573
|
+
clearTimeout(session.timeoutTimer);
|
|
1574
1574
|
}
|
|
1575
|
-
|
|
1575
|
+
session.timeoutTimer = setTimeout(() => {
|
|
1576
1576
|
log(`[SessionManager] Session timed out: ${sessionId}`);
|
|
1577
|
-
this.unregisterSession(sessionId)
|
|
1578
|
-
|
|
1577
|
+
this.unregisterSession(sessionId).catch((error) => {
|
|
1578
|
+
log(`[SessionManager] Error during session unregister for ${sessionId}:`, error);
|
|
1579
|
+
});
|
|
1580
|
+
}, this.options.sessionTimeoutMs);
|
|
1579
1581
|
}
|
|
1580
1582
|
};
|
|
1581
1583
|
|