crewly 1.4.47 → 1.4.48

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.
Files changed (28) hide show
  1. package/config/skills/agent/core/report-progress/execute.sh +0 -2
  2. package/dist/backend/backend/src/constants.d.ts +8 -0
  3. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  4. package/dist/backend/backend/src/constants.js +8 -0
  5. package/dist/backend/backend/src/constants.js.map +1 -1
  6. package/dist/backend/backend/src/controllers/cloud/relay.controller.d.ts.map +1 -1
  7. package/dist/backend/backend/src/controllers/cloud/relay.controller.js +16 -0
  8. package/dist/backend/backend/src/controllers/cloud/relay.controller.js.map +1 -1
  9. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +11 -0
  10. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  11. package/dist/backend/backend/src/services/agent/agent-registration.service.js +22 -0
  12. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  13. package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts +22 -0
  14. package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -1
  15. package/dist/backend/backend/src/services/cloud/cloud-client.service.js +54 -0
  16. package/dist/backend/backend/src/services/cloud/cloud-client.service.js.map +1 -1
  17. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts +86 -0
  18. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  19. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +257 -16
  20. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  21. package/dist/cli/backend/src/constants.d.ts +8 -0
  22. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  23. package/dist/cli/backend/src/constants.js +8 -0
  24. package/dist/cli/backend/src/constants.js.map +1 -1
  25. package/frontend/dist/assets/{index-7357dbef.js → index-3ae9392e.js} +140 -140
  26. package/frontend/dist/assets/{index-a393888e.css → index-78e43622.css} +1 -1
  27. package/frontend/dist/index.html +2 -2
  28. package/package.json +1 -1
@@ -231,6 +231,9 @@ export class CloudClientService {
231
231
  * ```
232
232
  */
233
233
  async getTemplates() {
234
+ // If token is already known to be expired, return empty without hitting the API
235
+ if (this.isTokenExpired())
236
+ return [];
234
237
  this.ensureConnected();
235
238
  const url = `${this.cloudUrl}${CLOUD_CONSTANTS.ENDPOINTS.TEMPLATES}`;
236
239
  const response = await fetch(url, {
@@ -239,6 +242,11 @@ export class CloudClientService {
239
242
  signal: AbortSignal.timeout(CLOUD_CONSTANTS.TIMEOUTS.FETCH_TEMPLATES),
240
243
  });
241
244
  if (!response.ok) {
245
+ // 401/403 means token expired or revoked — return empty list + update status
246
+ if (this.isAuthError(response.status)) {
247
+ this.handleAuthFailure('getTemplates', response.status);
248
+ return [];
249
+ }
242
250
  this.logger.error('Failed to fetch templates', { status: response.status });
243
251
  throw new Error(`Failed to fetch templates: ${response.status}`);
244
252
  }
@@ -262,6 +270,10 @@ export class CloudClientService {
262
270
  * ```
263
271
  */
264
272
  async getTemplateDetail(id) {
273
+ // If token is already known to be expired, throw user-friendly error
274
+ if (this.isTokenExpired()) {
275
+ throw new Error('Cloud token expired. Please reconnect to CrewlyAI Cloud.');
276
+ }
265
277
  this.ensureConnected();
266
278
  const endpoint = CLOUD_CONSTANTS.ENDPOINTS.TEMPLATE_DETAIL.replace(':id', id);
267
279
  const url = `${this.cloudUrl}${endpoint}`;
@@ -271,6 +283,11 @@ export class CloudClientService {
271
283
  signal: AbortSignal.timeout(CLOUD_CONSTANTS.TIMEOUTS.FETCH_TEMPLATE_DETAIL),
272
284
  });
273
285
  if (!response.ok) {
286
+ // 401/403 means token expired or revoked
287
+ if (this.isAuthError(response.status)) {
288
+ this.handleAuthFailure('getTemplateDetail', response.status);
289
+ throw new Error('Cloud token expired. Please reconnect to CrewlyAI Cloud.');
290
+ }
274
291
  if (response.status === 404) {
275
292
  throw new Error(`Template not found: ${id}`);
276
293
  }
@@ -310,6 +327,14 @@ export class CloudClientService {
310
327
  isConnected() {
311
328
  return this.connectionStatus === CLOUD_CONSTANTS.CONNECTION_STATUS.CONNECTED;
312
329
  }
330
+ /**
331
+ * Check whether the cloud token has expired (401/403 from cloud API).
332
+ *
333
+ * @returns true if the token has expired
334
+ */
335
+ isTokenExpired() {
336
+ return this.connectionStatus === CLOUD_CONSTANTS.CONNECTION_STATUS.TOKEN_EXPIRED;
337
+ }
313
338
  /**
314
339
  * Get the current subscription tier.
315
340
  *
@@ -328,6 +353,9 @@ export class CloudClientService {
328
353
  * @throws Error when not connected or fetch fails
329
354
  */
330
355
  async fetchCloudDevices() {
356
+ // If token is already known to be expired, return empty without hitting the API
357
+ if (this.isTokenExpired())
358
+ return [];
331
359
  this.ensureConnected();
332
360
  const url = `${this.cloudUrl}${CLOUD_CONSTANTS.RELAY_ENDPOINTS.DEVICES}`;
333
361
  const response = await fetch(url, {
@@ -336,6 +364,11 @@ export class CloudClientService {
336
364
  signal: AbortSignal.timeout(CLOUD_CONSTANTS.TIMEOUTS.FETCH_TEMPLATES),
337
365
  });
338
366
  if (!response.ok) {
367
+ // 401/403 means token expired or revoked — return empty list + update status
368
+ if (this.isAuthError(response.status)) {
369
+ this.handleAuthFailure('fetchCloudDevices', response.status);
370
+ return [];
371
+ }
339
372
  // 404 means the cloud devices endpoint is not yet available — return empty list gracefully
340
373
  if (response.status === 404) {
341
374
  this.logger.warn('Cloud devices endpoint not available (404), returning empty list');
@@ -375,5 +408,26 @@ export class CloudClientService {
375
408
  'Content-Type': 'application/json',
376
409
  };
377
410
  }
411
+ /**
412
+ * Check if an HTTP status code indicates an authentication/authorization failure.
413
+ *
414
+ * @param status - HTTP status code
415
+ * @returns true if the status is 401 or 403
416
+ */
417
+ isAuthError(status) {
418
+ return status === 401 || status === 403;
419
+ }
420
+ /**
421
+ * Handle a 401/403 response from the cloud API by transitioning
422
+ * the connection status to TOKEN_EXPIRED. This signals the frontend
423
+ * to show a reconnect prompt instead of a raw error.
424
+ *
425
+ * @param context - Description of the failed operation (for logging)
426
+ * @param status - HTTP status code from the cloud API
427
+ */
428
+ handleAuthFailure(context, status) {
429
+ this.logger.warn(`Cloud token expired or revoked during ${context}`, { status });
430
+ this.connectionStatus = CLOUD_CONSTANTS.CONNECTION_STATUS.TOKEN_EXPIRED;
431
+ }
378
432
  }
379
433
  //# sourceMappingURL=cloud-client.service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-client.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/cloud-client.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,aAAa,EAAwB,MAAM,2BAA2B,CAAC;AAChF,OAAO,EACL,eAAe,GAGhB,MAAM,oBAAoB,CAAC;AA+E5B,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,OAAO,kBAAkB;IACrB,MAAM,CAAC,QAAQ,GAA8B,IAAI,CAAC;IACzC,MAAM,CAAkB;IAEzC,2DAA2D;IACnD,QAAQ,GAAkB,IAAI,CAAC;IACvC,6CAA6C;IACrC,KAAK,GAAkB,IAAI,CAAC;IACpC,gCAAgC;IACxB,gBAAgB,GAA0B,eAAe,CAAC,iBAAiB,CAAC,YAAY,CAAC;IACjG,0CAA0C;IAClC,IAAI,GAAc,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC;IACrD,6DAA6D;IACrD,UAAU,GAAkB,IAAI,CAAC;IAEzC;QACE,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC,qBAAqB,CAAC,oBAAoB,CAAC,CAAC;IACxF,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,CAAC;YACjC,kBAAkB,CAAC,QAAQ,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACzD,CAAC;QACD,OAAO,kBAAkB,CAAC,QAAQ,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,aAAa;QAClB,kBAAkB,CAAC,QAAQ,GAAG,IAAI,CAAC;IACrC,CAAC;IAED,4EAA4E;IAC5E,aAAa;IACb,4EAA4E;IAE5E;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,OAAO,CAAC,QAAgB,EAAE,KAAa;QAC3C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE/D,MAAM,GAAG,GAAG,GAAG,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;QAEjE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,KAAK,EAAE;aACjC;YACD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;SAC9D,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC,iBAAiB,CAAC,KAAK,CAAC;YAChE,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC;YACrE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YACrF,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC;QAClF,CAAC;QAED,2EAA2E;QAC3E,+DAA+D;QAC/D,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAgD,CAAC;QACpF,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;QAElD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAI,YAA0B,IAAI,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC;QACtE,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC,iBAAiB,CAAC,SAAS,CAAC;QACpE,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE3C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAErE,oDAAoD;QACpD,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4CAA4C,EAAE;gBAC7D,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5C,CAAC;IAED;;;;;;;;;;OAUG;IACH,YAAY,CAAC,QAAgB,EAAE,KAAa,EAAE,IAAe;QAC3D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC;QAC/C,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC,iBAAiB,CAAC,SAAS,CAAC;QACpE,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE3C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kDAAkD,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAE1F,oDAAoD;QACpD,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4CAA4C,EAAE;gBAC7D,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,UAAU;QACR,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QACtD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC,iBAAiB,CAAC,YAAY,CAAC;QACvE,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC;QACvC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,0BAA0B;QAC1B,IAAI,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACzC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qDAAqD,EAAE;gBACtE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,4EAA4E;IAC5E,qBAAqB;IACrB,4EAA4E;IAE5E;;OAEG;IACH,MAAM,CAAC,aAAa;QAClB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IACpE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,mBAAmB;QACvB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,aAAa,EAAE,EAAE,OAAO,CAAC,CAAC;YACzE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAyB,CAAC;YACxD,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBACnD,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QAE1C,MAAM,MAAM,GAAyB;YACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACtC,CAAC;QAEF,MAAM,UAAU,GAAG,kBAAkB,CAAC,aAAa,EAAE,CAAC;QACtD,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,MAAM,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACtE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,qBAAqB;QACjC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,kBAAkB,CAAC,aAAa,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,oBAAoB;IACpB,4EAA4E;IAE5E;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,eAAe,EAAE,CAAC;QAEvB,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;QAErE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE;YAC3B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,eAAe,CAAC;SACtE,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5E,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA0C,CAAC;QAC9E,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,iBAAiB,CAAC,EAAU;QAChC,IAAI,CAAC,eAAe,EAAE,CAAC;QAEvB,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC9E,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC;QAE1C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE;YAC3B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,qBAAqB,CAAC;SAC5E,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;YAC/C,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACtF,MAAM,IAAI,KAAK,CAAC,oCAAoC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;QAC5D,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,OAAO;YACL,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,gBAAgB,KAAK,eAAe,CAAC,iBAAiB,CAAC,SAAS,CAAC;IAC/E,CAAC;IAED;;;;OAIG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,iBAAiB;QACrB,IAAI,CAAC,eAAe,EAAE,CAAC;QAEvB,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,GAAG,eAAe,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;QAEzE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE;YAC3B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,eAAe,CAAC;SACtE,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,2FAA2F;YAC3F,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;gBACrF,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAChF,MAAM,IAAI,KAAK,CAAC,kCAAkC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuD,CAAC;QAE3F,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,4EAA4E;IAC5E,kBAAkB;IAClB,4EAA4E;IAE5E;;;;OAIG;IACK,eAAe;QACrB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,WAAW;QACjB,OAAO;YACL,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;YACrC,cAAc,EAAE,kBAAkB;SACnC,CAAC;IACJ,CAAC"}
1
+ {"version":3,"file":"cloud-client.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/cloud-client.service.ts"],"names":[],"mappings":"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"}
@@ -6,12 +6,40 @@
6
6
  * fire-and-forget pattern. Responses are handled asynchronously by the
7
7
  * orchestrator through reply-* skills (reply-slack, reply-chat, reply-gchat).
8
8
  *
9
+ * #239: Force-delivered user messages (Slack/web chat) are tracked in a
10
+ * pending-ack list. When the agent returns to prompt, the PTY output is
11
+ * checked for evidence the message was processed. If not found, the message
12
+ * is re-delivered to prevent silent loss.
13
+ *
9
14
  * @module services/messaging/queue-processor
10
15
  */
11
16
  import { EventEmitter } from 'events';
12
17
  import { MessageQueueService } from './message-queue.service.js';
13
18
  import { ResponseRouterService } from './response-router.service.js';
14
19
  import { AgentRegistrationService } from '../agent/agent-registration.service.js';
20
+ import { type RuntimeType } from '../../constants.js';
21
+ /**
22
+ * Entry in the pending-ack list for force-delivered user messages.
23
+ * Tracks all information needed to verify or redeliver the message.
24
+ */
25
+ export interface PendingAckEntry {
26
+ /** Unique message ID */
27
+ messageId: string;
28
+ /** Conversation ID used as a fingerprint to detect processing in PTY output */
29
+ conversationId: string;
30
+ /** The formatted delivery content (for redelivery) */
31
+ deliveryContent: string;
32
+ /** Target session the message was delivered to */
33
+ targetSession: string;
34
+ /** Runtime type of the target agent */
35
+ runtimeType: RuntimeType;
36
+ /** Timestamp when force-delivered */
37
+ deliveredAt: number;
38
+ /** Number of redelivery attempts so far */
39
+ retryCount: number;
40
+ /** The original queued message (for markCompleted / markFailed / routeResponse) */
41
+ originalMessage: import('../../types/messaging.types.js').QueuedMessage;
42
+ }
15
43
  export declare class QueueProcessorService extends EventEmitter {
16
44
  private logger;
17
45
  private queueService;
@@ -31,6 +59,16 @@ export declare class QueueProcessorService extends EventEmitter {
31
59
  private deliveredMessageIds;
32
60
  /** Timer for periodic cleanup of stale dedup entries */
33
61
  private dedupCleanupTimer;
62
+ /** Timer for periodic cleanup of stale pending-ack entries */
63
+ private pendingAckCleanupTimer;
64
+ /**
65
+ * #239: Tracks force-delivered user messages awaiting acknowledgment.
66
+ * When a user message is force-delivered (agent not at prompt), it is
67
+ * added here instead of being marked completed. On the next successful
68
+ * waitForAgentReady (agent returns to prompt), the PTY output is checked
69
+ * for evidence that each pending message was actually processed.
70
+ */
71
+ private pendingAckMessages;
34
72
  constructor(queueService: MessageQueueService, responseRouter: ResponseRouterService, agentRegistrationService: AgentRegistrationService);
35
73
  /**
36
74
  * Start the processor. Listens to queue 'enqueued' events and
@@ -96,5 +134,53 @@ export declare class QueueProcessorService extends EventEmitter {
96
134
  * @returns Number of entries in the dedup set
97
135
  */
98
136
  getDeliveredMessageCount(): number;
137
+ /**
138
+ * Get the number of messages awaiting acknowledgment (for testing).
139
+ *
140
+ * @returns Number of entries in the pending-ack list
141
+ */
142
+ getPendingAckCount(): number;
143
+ /**
144
+ * Start periodic cleanup of stale pending-ack entries.
145
+ * Runs at PENDING_ACK_TTL_MS intervals and fails entries that have exceeded
146
+ * the TTL — prevents memory leaks if an agent crashes and never returns to prompt.
147
+ */
148
+ private startPendingAckCleanup;
149
+ /**
150
+ * Stop the periodic pending-ack cleanup timer.
151
+ */
152
+ private stopPendingAckCleanup;
153
+ /**
154
+ * Remove pending-ack entries that have exceeded the TTL.
155
+ * Marks them as failed and routes error to the source so the user is notified.
156
+ */
157
+ private purgeExpiredPendingAcks;
158
+ /**
159
+ * Check if a pending-ack message's fingerprint appears in PTY output.
160
+ *
161
+ * Matches the full [CHAT:conversationId] or [GCHAT:conversationId] prefix
162
+ * rather than a bare conversationId to avoid false positives from short
163
+ * or common IDs appearing in unrelated output.
164
+ *
165
+ * @param output - Captured PTY output string
166
+ * @param conversationId - The conversation ID to search for
167
+ * @returns true if the message fingerprint was found
168
+ */
169
+ private isPendingAckInOutput;
170
+ /**
171
+ * #239: Flush pending-ack messages by verifying them against PTY output.
172
+ *
173
+ * Called when the agent returns to prompt (waitForAgentReady succeeds).
174
+ * For each pending-ack entry:
175
+ * - Captures the agent's recent PTY output
176
+ * - Checks if the conversationId or CHAT prefix appears in the output
177
+ * - If found → message was processed, mark completed
178
+ * - If not found → message was swallowed, redeliver
179
+ * - If max retries exceeded → mark failed
180
+ *
181
+ * @param sessionName - The agent session to check
182
+ * @param runtimeType - Runtime type for redelivery
183
+ */
184
+ private flushPendingAcks;
99
185
  }
100
186
  //# sourceMappingURL=queue-processor.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queue-processor.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/queue-processor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AAmClF,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,wBAAwB,CAA2B;IAC3D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,kBAAkB,CAA8C;IACxE,gFAAgF;IAChF,OAAO,CAAC,oBAAoB,CAAS;IAErC;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB,CAAkC;IAE7D,wDAAwD;IACxD,OAAO,CAAC,iBAAiB,CAA+C;gBAGtE,YAAY,EAAE,mBAAmB,EACjC,cAAc,EAAE,qBAAqB,EACrC,wBAAwB,EAAE,wBAAwB;IASpD;;;OAGG;IACH,KAAK,IAAI,IAAI;IAcb;;OAEG;IACH,IAAI,IAAI,IAAI;IAiBZ;;;;OAIG;IACH,SAAS,IAAI,OAAO;IAIpB;;;;OAIG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;OAEG;IACH,OAAO,CAAC,iBAAiB,CAIvB;IAEF;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;;OAGG;YACW,WAAW;IAiXzB;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB;IAS7B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAcvB;;;;OAIG;IACH,wBAAwB,IAAI,MAAM;CAGnC"}
1
+ {"version":3,"file":"queue-processor.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/queue-processor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AAGlF,OAAO,EASL,KAAK,WAAW,EACjB,MAAM,oBAAoB,CAAC;AAsB5B;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,cAAc,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,eAAe,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,WAAW,EAAE,WAAW,CAAC;IACzB,qCAAqC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,eAAe,EAAE,OAAO,gCAAgC,EAAE,aAAa,CAAC;CACzE;AAED,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,wBAAwB,CAA2B;IAC3D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,kBAAkB,CAA8C;IACxE,gFAAgF;IAChF,OAAO,CAAC,oBAAoB,CAAS;IAErC;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB,CAAkC;IAE7D,wDAAwD;IACxD,OAAO,CAAC,iBAAiB,CAA+C;IAExE,8DAA8D;IAC9D,OAAO,CAAC,sBAAsB,CAA+C;IAE7E;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB,CAA2C;gBAGnE,YAAY,EAAE,mBAAmB,EACjC,cAAc,EAAE,qBAAqB,EACrC,wBAAwB,EAAE,wBAAwB;IASpD;;;OAGG;IACH,KAAK,IAAI,IAAI;IAeb;;OAEG;IACH,IAAI,IAAI,IAAI;IAmBZ;;;;OAIG;IACH,SAAS,IAAI,OAAO;IAIpB;;;;OAIG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;OAEG;IACH,OAAO,CAAC,iBAAiB,CAIvB;IAEF;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;;OAGG;YACW,WAAW;IA4azB;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB;IAe7B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAcvB;;;;OAIG;IACH,wBAAwB,IAAI,MAAM;IAIlC;;;;OAIG;IACH,kBAAkB,IAAI,MAAM;IAI5B;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAW9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAoB/B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,oBAAoB;IAO5B;;;;;;;;;;;;;OAaG;YACW,gBAAgB;CA0G/B"}
@@ -6,6 +6,11 @@
6
6
  * fire-and-forget pattern. Responses are handled asynchronously by the
7
7
  * orchestrator through reply-* skills (reply-slack, reply-chat, reply-gchat).
8
8
  *
9
+ * #239: Force-delivered user messages (Slack/web chat) are tracked in a
10
+ * pending-ack list. When the agent returns to prompt, the PTY output is
11
+ * checked for evidence the message was processed. If not found, the message
12
+ * is re-delivered to prevent silent loss.
13
+ *
9
14
  * @module services/messaging/queue-processor
10
15
  */
11
16
  import { EventEmitter } from 'events';
@@ -51,6 +56,16 @@ export class QueueProcessorService extends EventEmitter {
51
56
  deliveredMessageIds = new Map();
52
57
  /** Timer for periodic cleanup of stale dedup entries */
53
58
  dedupCleanupTimer = null;
59
+ /** Timer for periodic cleanup of stale pending-ack entries */
60
+ pendingAckCleanupTimer = null;
61
+ /**
62
+ * #239: Tracks force-delivered user messages awaiting acknowledgment.
63
+ * When a user message is force-delivered (agent not at prompt), it is
64
+ * added here instead of being marked completed. On the next successful
65
+ * waitForAgentReady (agent returns to prompt), the PTY output is checked
66
+ * for evidence that each pending message was actually processed.
67
+ */
68
+ pendingAckMessages = new Map();
54
69
  constructor(queueService, responseRouter, agentRegistrationService) {
55
70
  super();
56
71
  this.logger = LoggerService.getInstance().createComponentLogger('QueueProcessor');
@@ -68,6 +83,7 @@ export class QueueProcessorService extends EventEmitter {
68
83
  this.running = true;
69
84
  this.queueService.on('enqueued', this.onMessageEnqueued);
70
85
  this.startDedupCleanup();
86
+ this.startPendingAckCleanup();
71
87
  this.logger.info('Queue processor started');
72
88
  // Process any messages already in the queue
73
89
  if (this.queueService.hasPending()) {
@@ -87,7 +103,9 @@ export class QueueProcessorService extends EventEmitter {
87
103
  this.processNextTimeout = null;
88
104
  }
89
105
  this.stopDedupCleanup();
106
+ this.stopPendingAckCleanup();
90
107
  this.deliveredMessageIds.clear();
108
+ this.pendingAckMessages.clear();
91
109
  this.logger.info('Queue processor stopped');
92
110
  }
93
111
  /**
@@ -154,6 +172,21 @@ export class QueueProcessorService extends EventEmitter {
154
172
  }
155
173
  const message = this.queueService.dequeue();
156
174
  if (!message) {
175
+ // #239: Even with no new messages, flush any pending-ack entries
176
+ // when the agent is potentially idle. This handles the case where
177
+ // the queue is empty but force-delivered messages need verification.
178
+ if (this.pendingAckMessages.size > 0) {
179
+ const storedRuntimeType = orchestratorInfo?.runtimeType;
180
+ const rt = storedRuntimeType || RUNTIME_TYPES.CLAUDE_CODE;
181
+ const isReady = await this.agentRegistrationService.waitForAgentReady(ORCHESTRATOR_SESSION_NAME, EVENT_DELIVERY_CONSTANTS.USER_MESSAGE_TIMEOUT, rt);
182
+ if (isReady) {
183
+ await this.flushPendingAcks(ORCHESTRATOR_SESSION_NAME, rt);
184
+ }
185
+ // Schedule another check if there are still pending acks
186
+ if (this.pendingAckMessages.size > 0) {
187
+ this.scheduleProcessNext(EVENT_DELIVERY_CONSTANTS.AGENT_READY_POLL_INTERVAL);
188
+ }
189
+ }
157
190
  return;
158
191
  }
159
192
  this.processing = true;
@@ -206,6 +239,12 @@ export class QueueProcessorService extends EventEmitter {
206
239
  // After processing a previous message the agent may still be busy
207
240
  // (managing agents, running commands) before returning to the input prompt.
208
241
  const isReady = await this.agentRegistrationService.waitForAgentReady(deliveryTarget, readyTimeout, runtimeType);
242
+ // #239: When the agent returns to prompt, flush any force-delivered
243
+ // messages that are pending acknowledgment. This is the key mechanism
244
+ // to detect and redeliver messages that were silently consumed by the PTY.
245
+ if (isReady && this.pendingAckMessages.size > 0) {
246
+ await this.flushPendingAcks(deliveryTarget, runtimeType);
247
+ }
209
248
  // Check if message was force-cancelled while waiting for agent readiness
210
249
  if (message.status === 'cancelled') {
211
250
  this.logger.info('Message was cancelled during processing, skipping delivery', {
@@ -214,6 +253,9 @@ export class QueueProcessorService extends EventEmitter {
214
253
  clearInterval(keepaliveInterval);
215
254
  return;
216
255
  }
256
+ // #239: Track whether this delivery was forced (agent not at prompt).
257
+ // Force-delivered user messages need pending-ack tracking.
258
+ let wasForceDelivered = false;
217
259
  if (!isReady) {
218
260
  // For user messages and system events: force-deliver immediately instead
219
261
  // of re-queuing to avoid the retry loop that causes multi-minute delays.
@@ -222,6 +264,7 @@ export class QueueProcessorService extends EventEmitter {
222
264
  const shouldForceDeliver = (isUserMessage && EVENT_DELIVERY_CONSTANTS.USER_MESSAGE_FORCE_DELIVER) ||
223
265
  (isSystemEvent && EVENT_DELIVERY_CONSTANTS.SYSTEM_EVENT_FORCE_DELIVER);
224
266
  if (shouldForceDeliver) {
267
+ wasForceDelivered = true;
225
268
  this.logger.warn('Agent not ready but force-delivering message to reduce delay', {
226
269
  messageId: message.id,
227
270
  source: message.source,
@@ -408,22 +451,49 @@ export class QueueProcessorService extends EventEmitter {
408
451
  }
409
452
  return;
410
453
  }
411
- // Fire-and-forget: mark as completed immediately after delivery.
412
- // Responses are handled asynchronously by the orchestrator through
413
- // reply-* skills (reply-slack, reply-chat, reply-gchat).
414
- this.queueService.markCompleted(message.id, '');
415
- // Mark all batched system event messages as completed too
416
- if (batchedMessages.length > 0) {
417
- this.queueService.markBatchCompleted(batchedMessages);
454
+ // #239: For force-delivered user messages, add to pending-ack list
455
+ // instead of marking completed. The message will be verified or
456
+ // redelivered when the agent next returns to prompt.
457
+ if (wasForceDelivered && isUserMessage) {
458
+ this.pendingAckMessages.set(message.id, {
459
+ messageId: message.id,
460
+ conversationId: message.conversationId,
461
+ deliveryContent,
462
+ targetSession,
463
+ runtimeType: deliveryRuntimeType,
464
+ deliveredAt: Date.now(),
465
+ retryCount: 0,
466
+ originalMessage: message,
467
+ });
468
+ // Resolve source callbacks immediately to unblock callers (e.g. Slack bridge).
469
+ // The actual reply comes via reply-* skills; pending-ack only guards against
470
+ // the message being silently swallowed by the PTY.
471
+ this.responseRouter.routeResponse(message, '');
472
+ this.logger.info('Force-delivered user message added to pending-ack list', {
473
+ messageId: message.id,
474
+ source: message.source,
475
+ conversationId: message.conversationId,
476
+ pendingAckCount: this.pendingAckMessages.size,
477
+ });
478
+ }
479
+ else {
480
+ // Normal path: mark as completed immediately after delivery.
481
+ // Responses are handled asynchronously by the orchestrator through
482
+ // reply-* skills (reply-slack, reply-chat, reply-gchat).
483
+ this.queueService.markCompleted(message.id, '');
484
+ // Mark all batched system event messages as completed too
485
+ if (batchedMessages.length > 0) {
486
+ this.queueService.markBatchCompleted(batchedMessages);
487
+ }
488
+ // Resolve any pending source callbacks (e.g. slackResolve, googleChatResolve)
489
+ // with empty response to unblock callers. The actual reply comes via reply-* skills.
490
+ this.responseRouter.routeResponse(message, '');
491
+ this.logger.info('Message delivered (fire-and-forget)', {
492
+ messageId: message.id,
493
+ source: message.source,
494
+ batchSize: isSystemEvent ? 1 + batchedMessages.length : 1,
495
+ });
418
496
  }
419
- // Resolve any pending source callbacks (e.g. slackResolve, googleChatResolve)
420
- // with empty response to unblock callers. The actual reply comes via reply-* skills.
421
- this.responseRouter.routeResponse(message, '');
422
- this.logger.info('Message delivered (fire-and-forget)', {
423
- messageId: message.id,
424
- source: message.source,
425
- batchSize: isSystemEvent ? 1 + batchedMessages.length : 1,
426
- });
427
497
  // Wait for orchestrator to finish post-delivery work before next message.
428
498
  // Skip for system events: they're fire-and-forget notifications.
429
499
  // The next processNext() iteration already calls waitForAgentReady before
@@ -461,12 +531,19 @@ export class QueueProcessorService extends EventEmitter {
461
531
  * blocked behind the 500ms cooldown after system event delivery.
462
532
  */
463
533
  scheduleNextIfPending() {
464
- if (this.running && this.queueService.hasPending()) {
534
+ if (!this.running)
535
+ return;
536
+ if (this.queueService.hasPending()) {
465
537
  const delay = this.queueService.hasUserMessagePending()
466
538
  ? 0
467
539
  : MESSAGE_QUEUE_CONSTANTS.INTER_MESSAGE_DELAY;
468
540
  this.scheduleProcessNext(delay);
469
541
  }
542
+ else if (this.pendingAckMessages.size > 0) {
543
+ // #239: No new queue messages but pending-ack entries need flushing.
544
+ // Schedule a poll to check if agent returned to prompt.
545
+ this.scheduleProcessNext(EVENT_DELIVERY_CONSTANTS.AGENT_READY_POLL_INTERVAL);
546
+ }
470
547
  }
471
548
  /**
472
549
  * Start periodic cleanup of stale entries in the delivered message dedup set.
@@ -515,5 +592,169 @@ export class QueueProcessorService extends EventEmitter {
515
592
  getDeliveredMessageCount() {
516
593
  return this.deliveredMessageIds.size;
517
594
  }
595
+ /**
596
+ * Get the number of messages awaiting acknowledgment (for testing).
597
+ *
598
+ * @returns Number of entries in the pending-ack list
599
+ */
600
+ getPendingAckCount() {
601
+ return this.pendingAckMessages.size;
602
+ }
603
+ /**
604
+ * Start periodic cleanup of stale pending-ack entries.
605
+ * Runs at PENDING_ACK_TTL_MS intervals and fails entries that have exceeded
606
+ * the TTL — prevents memory leaks if an agent crashes and never returns to prompt.
607
+ */
608
+ startPendingAckCleanup() {
609
+ if (this.pendingAckCleanupTimer)
610
+ return;
611
+ const ttlMs = EVENT_DELIVERY_CONSTANTS.PENDING_ACK_TTL_MS ?? 600_000;
612
+ this.pendingAckCleanupTimer = setInterval(() => {
613
+ this.purgeExpiredPendingAcks();
614
+ }, ttlMs);
615
+ if (this.pendingAckCleanupTimer.unref) {
616
+ this.pendingAckCleanupTimer.unref();
617
+ }
618
+ }
619
+ /**
620
+ * Stop the periodic pending-ack cleanup timer.
621
+ */
622
+ stopPendingAckCleanup() {
623
+ if (this.pendingAckCleanupTimer) {
624
+ clearInterval(this.pendingAckCleanupTimer);
625
+ this.pendingAckCleanupTimer = null;
626
+ }
627
+ }
628
+ /**
629
+ * Remove pending-ack entries that have exceeded the TTL.
630
+ * Marks them as failed and routes error to the source so the user is notified.
631
+ */
632
+ purgeExpiredPendingAcks() {
633
+ const ttlMs = EVENT_DELIVERY_CONSTANTS.PENDING_ACK_TTL_MS ?? 600_000;
634
+ const now = Date.now();
635
+ let purged = 0;
636
+ for (const [id, entry] of this.pendingAckMessages) {
637
+ if (now - entry.deliveredAt > ttlMs) {
638
+ this.queueService.markFailed(id, 'Force-delivered message expired without acknowledgment (TTL cleanup)');
639
+ this.responseRouter.routeError(entry.originalMessage, 'Message delivery failed: the orchestrator did not process your message in time. Please try again.');
640
+ this.pendingAckMessages.delete(id);
641
+ purged++;
642
+ }
643
+ }
644
+ if (purged > 0) {
645
+ this.logger.warn('Purged expired pending-ack entries', { purged, remaining: this.pendingAckMessages.size });
646
+ }
647
+ }
648
+ /**
649
+ * Check if a pending-ack message's fingerprint appears in PTY output.
650
+ *
651
+ * Matches the full [CHAT:conversationId] or [GCHAT:conversationId] prefix
652
+ * rather than a bare conversationId to avoid false positives from short
653
+ * or common IDs appearing in unrelated output.
654
+ *
655
+ * @param output - Captured PTY output string
656
+ * @param conversationId - The conversation ID to search for
657
+ * @returns true if the message fingerprint was found
658
+ */
659
+ isPendingAckInOutput(output, conversationId) {
660
+ return output.includes(`[CHAT:${conversationId}]`)
661
+ || output.includes(`[GCHAT:${conversationId}]`)
662
+ || output.includes(`[CHAT:${conversationId} `)
663
+ || output.includes(`[GCHAT:${conversationId} `);
664
+ }
665
+ /**
666
+ * #239: Flush pending-ack messages by verifying them against PTY output.
667
+ *
668
+ * Called when the agent returns to prompt (waitForAgentReady succeeds).
669
+ * For each pending-ack entry:
670
+ * - Captures the agent's recent PTY output
671
+ * - Checks if the conversationId or CHAT prefix appears in the output
672
+ * - If found → message was processed, mark completed
673
+ * - If not found → message was swallowed, redeliver
674
+ * - If max retries exceeded → mark failed
675
+ *
676
+ * @param sessionName - The agent session to check
677
+ * @param runtimeType - Runtime type for redelivery
678
+ */
679
+ async flushPendingAcks(sessionName, runtimeType) {
680
+ if (this.pendingAckMessages.size === 0)
681
+ return;
682
+ const scanLines = EVENT_DELIVERY_CONSTANTS.PENDING_ACK_SCAN_LINES ?? 300;
683
+ const maxRetries = EVENT_DELIVERY_CONSTANTS.PENDING_ACK_MAX_RETRIES ?? 3;
684
+ const ttlMs = EVENT_DELIVERY_CONSTANTS.PENDING_ACK_TTL_MS ?? 600_000;
685
+ // Capture PTY output once for all pending checks
686
+ const ptyOutput = await this.agentRegistrationService.captureAgentOutput(sessionName, scanLines);
687
+ const now = Date.now();
688
+ const entriesToProcess = Array.from(this.pendingAckMessages.values());
689
+ for (const entry of entriesToProcess) {
690
+ // Skip entries for different sessions
691
+ if (entry.targetSession !== sessionName)
692
+ continue;
693
+ // Purge stale entries beyond TTL
694
+ if (now - entry.deliveredAt > ttlMs) {
695
+ this.logger.warn('Pending-ack entry expired beyond TTL, marking failed', {
696
+ messageId: entry.messageId,
697
+ conversationId: entry.conversationId,
698
+ ageMs: now - entry.deliveredAt,
699
+ });
700
+ this.queueService.markFailed(entry.messageId, 'Force-delivered message expired without acknowledgment');
701
+ this.pendingAckMessages.delete(entry.messageId);
702
+ continue;
703
+ }
704
+ // Check if the delivery prefix [CHAT:conversationId] or [GCHAT:conversationId]
705
+ // appears in the PTY output. Using the full prefix avoids false positives from
706
+ // short or common conversationIds that might appear in unrelated output.
707
+ const wasProcessed = this.isPendingAckInOutput(ptyOutput, entry.conversationId);
708
+ if (wasProcessed) {
709
+ this.logger.info('Pending-ack message confirmed in PTY output', {
710
+ messageId: entry.messageId,
711
+ conversationId: entry.conversationId,
712
+ });
713
+ this.queueService.markCompleted(entry.messageId, '');
714
+ this.pendingAckMessages.delete(entry.messageId);
715
+ continue;
716
+ }
717
+ // Message not found in output — was likely swallowed by the PTY
718
+ if (entry.retryCount >= maxRetries) {
719
+ this.logger.error('Force-delivered message not acknowledged after max retries, marking failed', {
720
+ messageId: entry.messageId,
721
+ conversationId: entry.conversationId,
722
+ retryCount: entry.retryCount,
723
+ });
724
+ this.queueService.markFailed(entry.messageId, `Force-delivered message was not processed by the agent after ${entry.retryCount} redelivery attempts`);
725
+ this.responseRouter.routeError(entry.originalMessage, 'Message delivery failed: the orchestrator did not process your message. Please try again.');
726
+ this.pendingAckMessages.delete(entry.messageId);
727
+ continue;
728
+ }
729
+ // Redeliver: double-check PTY output right before sending to minimize duplicates
730
+ const freshOutput = await this.agentRegistrationService.captureAgentOutput(sessionName, scanLines);
731
+ if (this.isPendingAckInOutput(freshOutput, entry.conversationId)) {
732
+ this.logger.info('Pending-ack message found on re-check, marking completed', {
733
+ messageId: entry.messageId,
734
+ conversationId: entry.conversationId,
735
+ });
736
+ this.queueService.markCompleted(entry.messageId, '');
737
+ this.pendingAckMessages.delete(entry.messageId);
738
+ continue;
739
+ }
740
+ // Redeliver the message
741
+ entry.retryCount++;
742
+ this.logger.warn('Redelivering force-delivered message (not found in PTY output)', {
743
+ messageId: entry.messageId,
744
+ conversationId: entry.conversationId,
745
+ retryCount: entry.retryCount,
746
+ maxRetries,
747
+ });
748
+ const redeliveryResult = await this.agentRegistrationService.sendMessageToAgent(entry.targetSession, entry.deliveryContent, entry.runtimeType);
749
+ if (!redeliveryResult.success) {
750
+ this.logger.warn('Redelivery failed, will retry on next idle', {
751
+ messageId: entry.messageId,
752
+ error: redeliveryResult.error,
753
+ });
754
+ }
755
+ // Keep in pendingAckMessages for next flush attempt regardless of success,
756
+ // because we still need to verify the agent actually processes it.
757
+ }
758
+ }
518
759
  }
519
760
  //# sourceMappingURL=queue-processor.service.js.map