@yeaft/webchat-agent 1.0.222 → 1.0.224

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "1.0.222",
3
+ "version": "1.0.224",
4
4
  "description": "Remote worker agent for Yeaft Web Code Agent — connects the native Yeaft engine, CLI providers, and workbench tools",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -31,6 +31,7 @@ const BROWSER_FILE_FIELDS = Object.freeze({
31
31
  work_item_message: ['id', 'text', 'revision'],
32
32
  action_input: ['id', 'text', 'actionId', 'revision', 'generation', 'files'],
33
33
  retry_action: ['id', 'actionId', 'revision', 'generation'],
34
+ delete: ['id', 'revision'],
34
35
  guide: ['id', 'guidance', 'actionId', 'revision', 'generation', 'files'],
35
36
  get_action_messages: ['id', 'actionId', 'cursor', 'limit'],
36
37
  get_action_requests: ['id', 'actionId'],
@@ -887,9 +887,19 @@ export function projectWorkItemSummary(detail) {
887
887
  }
888
888
 
889
889
  export function projectWorkCenterEvent(event) {
890
+ const type = truncateUtf8(event?.type || 'work_item.updated', 256);
891
+ if (type === 'work_item.deleted') {
892
+ return {
893
+ type,
894
+ workItem: {
895
+ id: String(event?.workItem?.id || ''),
896
+ revision: count(event?.workItem?.revision),
897
+ },
898
+ };
899
+ }
890
900
  const liveActionId = bodyActionId(event?.workItem);
891
901
  return enforceWorkItemBrowserDtoBudget({
892
- type: truncateUtf8(event?.type || 'work_item.updated', 256),
902
+ type,
893
903
  workItem: {
894
904
  ...projectWorkItemSummary(event?.workItem),
895
905
  actionStats: projectActionStats(event?.workItem),
@@ -247,6 +247,20 @@ export class WorkCenterService {
247
247
  this.#emit({ type: 'work_item.cancelled', workItem: detail });
248
248
  return detail;
249
249
  }
250
+ case 'delete': {
251
+ const id = requiredString(payload.id, 'id');
252
+ const deleted = this.store.deleteWorkItemAtomic(id, Number(payload.revision));
253
+ if (!deleted) throw new Error(`WorkItem not found: ${id}`);
254
+ for (const action of deleted.actions || []) {
255
+ try { this.watcher.runner?.cleanup?.(action); } catch {}
256
+ }
257
+ let cleanupWarning = null;
258
+ try { removeWorkItemAttachments(this.attachmentRoot, id); } catch {
259
+ cleanupWarning = 'WorkItem data was deleted, but attachment cleanup needs maintenance';
260
+ }
261
+ this.#emit({ type: 'work_item.deleted', workItem: { id, revision: deleted.revision } });
262
+ return { id, deleted: true, cleanupWarning };
263
+ }
250
264
  case 'work_item_message': {
251
265
  const id = requiredString(payload.id, 'id');
252
266
  const detail = this.controller.message(id, {
@@ -1415,6 +1415,26 @@ export class WorkItemStore {
1415
1415
  return graphExecutionState(detail, detail.actions);
1416
1416
  }
1417
1417
 
1418
+ deleteWorkItemAtomic(id, expectedRevision) {
1419
+ return withTransaction(this.db, () => {
1420
+ const detail = this.getWorkItemDetail(id);
1421
+ if (!detail) return null;
1422
+ if (!Number.isInteger(expectedRevision) || detail.revision !== expectedRevision) {
1423
+ throw new Error('WorkItem changed before deletion; refresh and try again');
1424
+ }
1425
+ const activeRun = detail.runs.find(run => run.status === 'running');
1426
+ if (activeRun || !['done', 'cancelled', 'draft', 'needs_attention'].includes(detail.status)) {
1427
+ throw new Error('Stop this WorkItem before deleting it');
1428
+ }
1429
+ const result = this.db.prepare('DELETE FROM work_items WHERE id = ? AND revision = ?')
1430
+ .run(id, expectedRevision);
1431
+ if (Number(result.changes) !== 1) {
1432
+ throw new Error('WorkItem changed before deletion; refresh and try again');
1433
+ }
1434
+ return detail;
1435
+ });
1436
+ }
1437
+
1418
1438
  listActionEvents(actionId) {
1419
1439
  return this.db.prepare(`SELECT * FROM events WHERE action_id = ? ORDER BY id`).all(actionId).map(mapEvent);
1420
1440
  }