happy-mcp-server 1.0.0 → 1.0.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.
@@ -149,6 +149,10 @@ export class RelayClient extends EventEmitter {
149
149
  : null;
150
150
  this.sessionManager.updateAgentState(sessionId, decrypted, agentState.version);
151
151
  }
152
+ // Handle active flag
153
+ if (body.active !== undefined) {
154
+ this.sessionManager.updateSessionActivity(sessionId, body.active);
155
+ }
152
156
  this.emit('session_update', sessionId);
153
157
  }
154
158
  handleUpdateMachine(body) {
@@ -202,6 +206,12 @@ export class RelayClient extends EventEmitter {
202
206
  }
203
207
  }
204
208
  break;
209
+ case 'activity':
210
+ if (event.id && this.sessionManager.has(event.id)) {
211
+ this.sessionManager.updateSessionActivity(event.id, event.active ?? false, event.activeAt, event.thinking);
212
+ this.emit('session_update', event.id);
213
+ }
214
+ break;
205
215
  default:
206
216
  logger.debug('Unhandled ephemeral type:', event.type);
207
217
  }
@@ -13,6 +13,7 @@ export declare class SessionManager {
13
13
  remove(id: string): void;
14
14
  updateMetadata(id: string, metadata: SessionMetadata | null, version: number): void;
15
15
  updateAgentState(id: string, agentState: AgentState | null, version: number): void;
16
+ updateSessionActivity(id: string, active: boolean, activeAt?: number, thinking?: boolean): void;
16
17
  applyMessage(sessionId: string, messageId: string, seq: number, content: unknown, createdAt: number): void;
17
18
  getMessages(sessionId: string, limit?: number): DecryptedMessage[];
18
19
  getSessionStatus(sessionId: string): SessionStatus;
@@ -39,6 +39,9 @@ export class SessionManager {
39
39
  lastSeq: 0,
40
40
  lastActivity: Date.now(),
41
41
  active,
42
+ activeAt: Date.now(),
43
+ thinking: false,
44
+ thinkingAt: 0,
42
45
  createdAt,
43
46
  updatedAt,
44
47
  });
@@ -78,6 +81,20 @@ export class SessionManager {
78
81
  logger.debug(`Session ${id} agentState updated to v${version}`);
79
82
  }
80
83
  }
84
+ updateSessionActivity(id, active, activeAt, thinking) {
85
+ const session = this.sessions.get(id);
86
+ if (!session)
87
+ return;
88
+ session.active = active;
89
+ if (activeAt !== undefined)
90
+ session.activeAt = activeAt;
91
+ if (thinking !== undefined) {
92
+ session.thinking = thinking;
93
+ session.thinkingAt = Date.now();
94
+ }
95
+ session.lastActivity = Date.now();
96
+ logger.debug(`Session ${id} activity updated: active=${active}, thinking=${thinking ?? session.thinking}`);
97
+ }
81
98
  // --- Message Handling ---
82
99
  applyMessage(sessionId, messageId, seq, content, createdAt) {
83
100
  const session = this.sessions.get(sessionId);
@@ -104,13 +121,16 @@ export class SessionManager {
104
121
  // --- Status Derivation ---
105
122
  getSessionStatus(sessionId) {
106
123
  const session = this.sessions.get(sessionId);
107
- if (!session?.agentState)
124
+ if (!session)
108
125
  return 'idle';
109
- const state = session.agentState;
110
- const hasRequests = state.requests && Object.keys(state.requests).length > 0;
111
- if (hasRequests)
112
- return 'waiting_permission';
113
- if (state.controlledByUser)
126
+ // Permission requests take highest priority
127
+ if (session.agentState) {
128
+ const hasRequests = session.agentState.requests && Object.keys(session.agentState.requests).length > 0;
129
+ if (hasRequests)
130
+ return 'waiting_permission';
131
+ }
132
+ // Session is active if the relay says it's active or it's thinking
133
+ if (session.active || session.thinking)
114
134
  return 'active';
115
135
  return 'idle';
116
136
  }
@@ -52,6 +52,9 @@ export interface CachedSession {
52
52
  lastSeq: number;
53
53
  lastActivity: number;
54
54
  active: boolean;
55
+ activeAt: number;
56
+ thinking: boolean;
57
+ thinkingAt: number;
55
58
  createdAt: number;
56
59
  updatedAt: number;
57
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "happy-mcp-server",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "MCP server for observing and controlling Happy Coder sessions",
5
5
  "author": {
6
6
  "name": "Jared Spencer",