forge-openclaw-plugin 0.2.18 → 0.2.19

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 (56) hide show
  1. package/README.md +36 -4
  2. package/dist/assets/{board-2KevHCI0.js → board-8L3uX7_O.js} +2 -2
  3. package/dist/assets/{board-2KevHCI0.js.map → board-8L3uX7_O.js.map} +1 -1
  4. package/dist/assets/index-Cj1IBH_w.js +36 -0
  5. package/dist/assets/index-Cj1IBH_w.js.map +1 -0
  6. package/dist/assets/index-DQT6EbuS.css +1 -0
  7. package/dist/assets/{motion-q19HPmWs.js → motion-1GAqqi8M.js} +2 -2
  8. package/dist/assets/{motion-q19HPmWs.js.map → motion-1GAqqi8M.js.map} +1 -1
  9. package/dist/assets/{table-BDMHBY4a.js → table-DBGlgRjk.js} +2 -2
  10. package/dist/assets/{table-BDMHBY4a.js.map → table-DBGlgRjk.js.map} +1 -1
  11. package/dist/assets/{ui-CQ_AsFs8.js → ui-iTluWjC4.js} +2 -2
  12. package/dist/assets/{ui-CQ_AsFs8.js.map → ui-iTluWjC4.js.map} +1 -1
  13. package/dist/assets/{vendor-5HifrnRK.js → vendor-BvM2F9Dp.js} +139 -84
  14. package/dist/assets/vendor-BvM2F9Dp.js.map +1 -0
  15. package/dist/assets/{viz-CQzkRnTu.js → viz-CNeunkfu.js} +2 -2
  16. package/dist/assets/{viz-CQzkRnTu.js.map → viz-CNeunkfu.js.map} +1 -1
  17. package/dist/index.html +8 -8
  18. package/dist/openclaw/parity.js +1 -0
  19. package/dist/openclaw/routes.js +7 -0
  20. package/dist/openclaw/tools.js +183 -16
  21. package/dist/server/app.js +2509 -263
  22. package/dist/server/managers/platform/secrets-manager.js +44 -1
  23. package/dist/server/managers/runtime.js +3 -1
  24. package/dist/server/openapi.js +2037 -172
  25. package/dist/server/repositories/calendar.js +1101 -0
  26. package/dist/server/repositories/deleted-entities.js +10 -2
  27. package/dist/server/repositories/notes.js +161 -28
  28. package/dist/server/repositories/projects.js +45 -13
  29. package/dist/server/repositories/rewards.js +114 -6
  30. package/dist/server/repositories/settings.js +47 -5
  31. package/dist/server/repositories/task-runs.js +46 -10
  32. package/dist/server/repositories/tasks.js +25 -9
  33. package/dist/server/repositories/weekly-reviews.js +109 -0
  34. package/dist/server/repositories/work-adjustments.js +105 -0
  35. package/dist/server/services/calendar-runtime.js +1301 -0
  36. package/dist/server/services/entity-crud.js +94 -3
  37. package/dist/server/services/projects.js +32 -8
  38. package/dist/server/services/reviews.js +15 -1
  39. package/dist/server/services/work-time.js +27 -0
  40. package/dist/server/types.js +934 -49
  41. package/openclaw.plugin.json +1 -1
  42. package/package.json +1 -1
  43. package/server/migrations/006_work_adjustments.sql +14 -0
  44. package/server/migrations/007_weekly_review_closures.sql +17 -0
  45. package/server/migrations/008_calendar_execution.sql +147 -0
  46. package/server/migrations/009_true_calendar_events.sql +195 -0
  47. package/server/migrations/010_calendar_selection_state.sql +6 -0
  48. package/server/migrations/011_calendar_timezone_backfill.sql +11 -0
  49. package/server/migrations/012_work_block_ranges.sql +7 -0
  50. package/server/migrations/013_microsoft_local_auth_settings.sql +8 -0
  51. package/server/migrations/014_note_tags_and_ephemeral.sql +8 -0
  52. package/skills/forge-openclaw/SKILL.md +117 -11
  53. package/dist/assets/index-CDYW4WDH.js +0 -36
  54. package/dist/assets/index-CDYW4WDH.js.map +0 -1
  55. package/dist/assets/index-yroQr6YZ.css +0 -1
  56. package/dist/assets/vendor-5HifrnRK.js.map +0 -1
@@ -55,7 +55,18 @@ export function buildOpenApiDocument() {
55
55
  const goal = {
56
56
  type: "object",
57
57
  additionalProperties: false,
58
- required: ["id", "title", "description", "horizon", "status", "targetPoints", "themeColor", "createdAt", "updatedAt", "tagIds"],
58
+ required: [
59
+ "id",
60
+ "title",
61
+ "description",
62
+ "horizon",
63
+ "status",
64
+ "targetPoints",
65
+ "themeColor",
66
+ "createdAt",
67
+ "updatedAt",
68
+ "tagIds"
69
+ ],
59
70
  properties: {
60
71
  id: { type: "string" },
61
72
  title: { type: "string" },
@@ -75,7 +86,14 @@ export function buildOpenApiDocument() {
75
86
  {
76
87
  type: "object",
77
88
  additionalProperties: false,
78
- required: ["progress", "totalTasks", "completedTasks", "earnedPoints", "momentumLabel", "tags"],
89
+ required: [
90
+ "progress",
91
+ "totalTasks",
92
+ "completedTasks",
93
+ "earnedPoints",
94
+ "momentumLabel",
95
+ "tags"
96
+ ],
79
97
  properties: {
80
98
  progress: { type: "number" },
81
99
  totalTasks: { type: "integer" },
@@ -90,7 +108,18 @@ export function buildOpenApiDocument() {
90
108
  const project = {
91
109
  type: "object",
92
110
  additionalProperties: false,
93
- required: ["id", "goalId", "title", "description", "status", "targetPoints", "themeColor", "createdAt", "updatedAt"],
111
+ required: [
112
+ "id",
113
+ "goalId",
114
+ "title",
115
+ "description",
116
+ "status",
117
+ "targetPoints",
118
+ "themeColor",
119
+ "schedulingRules",
120
+ "createdAt",
121
+ "updatedAt"
122
+ ],
94
123
  properties: {
95
124
  id: { type: "string" },
96
125
  goalId: { type: "string" },
@@ -99,6 +128,7 @@ export function buildOpenApiDocument() {
99
128
  status: { type: "string", enum: ["active", "paused", "completed"] },
100
129
  targetPoints: { type: "integer" },
101
130
  themeColor: { type: "string" },
131
+ schedulingRules: { $ref: "#/components/schemas/CalendarSchedulingRules" },
102
132
  createdAt: { type: "string", format: "date-time" },
103
133
  updatedAt: { type: "string", format: "date-time" }
104
134
  }
@@ -106,10 +136,22 @@ export function buildOpenApiDocument() {
106
136
  const taskTimeSummary = {
107
137
  type: "object",
108
138
  additionalProperties: false,
109
- required: ["totalTrackedSeconds", "totalCreditedSeconds", "activeRunCount", "hasCurrentRun", "currentRunId"],
139
+ required: [
140
+ "totalTrackedSeconds",
141
+ "totalCreditedSeconds",
142
+ "liveTrackedSeconds",
143
+ "liveCreditedSeconds",
144
+ "manualAdjustedSeconds",
145
+ "activeRunCount",
146
+ "hasCurrentRun",
147
+ "currentRunId"
148
+ ],
110
149
  properties: {
111
150
  totalTrackedSeconds: { type: "integer" },
112
151
  totalCreditedSeconds: { type: "number" },
152
+ liveTrackedSeconds: { type: "integer" },
153
+ liveCreditedSeconds: { type: "number" },
154
+ manualAdjustedSeconds: { type: "integer" },
113
155
  activeRunCount: { type: "integer" },
114
156
  hasCurrentRun: { type: "boolean" },
115
157
  currentRunId: nullable({ type: "string" })
@@ -164,6 +206,8 @@ export function buildOpenApiDocument() {
164
206
  "effort",
165
207
  "energy",
166
208
  "points",
209
+ "plannedDurationSeconds",
210
+ "schedulingRules",
167
211
  "sortOrder",
168
212
  "completedAt",
169
213
  "createdAt",
@@ -175,7 +219,10 @@ export function buildOpenApiDocument() {
175
219
  id: { type: "string" },
176
220
  title: { type: "string" },
177
221
  description: { type: "string" },
178
- status: { type: "string", enum: ["backlog", "focus", "in_progress", "blocked", "done"] },
222
+ status: {
223
+ type: "string",
224
+ enum: ["backlog", "focus", "in_progress", "blocked", "done"]
225
+ },
179
226
  priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
180
227
  owner: { type: "string" },
181
228
  goalId: nullable({ type: "string" }),
@@ -184,6 +231,10 @@ export function buildOpenApiDocument() {
184
231
  effort: { type: "string", enum: ["light", "deep", "marathon"] },
185
232
  energy: { type: "string", enum: ["low", "steady", "high"] },
186
233
  points: { type: "integer" },
234
+ plannedDurationSeconds: nullable({ type: "integer" }),
235
+ schedulingRules: nullable({
236
+ $ref: "#/components/schemas/CalendarSchedulingRules"
237
+ }),
187
238
  sortOrder: { type: "integer" },
188
239
  completedAt: nullable({ type: "string", format: "date-time" }),
189
240
  createdAt: { type: "string", format: "date-time" },
@@ -216,14 +267,18 @@ export function buildOpenApiDocument() {
216
267
  "creditedSeconds",
217
268
  "remainingSeconds",
218
269
  "overtimeSeconds",
219
- "isCurrent"
270
+ "isCurrent",
271
+ "overrideReason"
220
272
  ],
221
273
  properties: {
222
274
  id: { type: "string" },
223
275
  taskId: { type: "string" },
224
276
  taskTitle: { type: "string" },
225
277
  actor: { type: "string" },
226
- status: { type: "string", enum: ["active", "completed", "released", "timed_out"] },
278
+ status: {
279
+ type: "string",
280
+ enum: ["active", "completed", "released", "timed_out"]
281
+ },
227
282
  note: { type: "string" },
228
283
  leaseTtlSeconds: { type: "integer" },
229
284
  claimedAt: { type: "string", format: "date-time" },
@@ -239,13 +294,435 @@ export function buildOpenApiDocument() {
239
294
  creditedSeconds: { type: "number" },
240
295
  remainingSeconds: nullable({ type: "integer" }),
241
296
  overtimeSeconds: { type: "integer" },
242
- isCurrent: { type: "boolean" }
297
+ isCurrent: { type: "boolean" },
298
+ overrideReason: nullable({ type: "string" })
299
+ }
300
+ };
301
+ const calendarSchedulingRules = {
302
+ type: "object",
303
+ additionalProperties: false,
304
+ required: [
305
+ "allowWorkBlockKinds",
306
+ "blockWorkBlockKinds",
307
+ "allowCalendarIds",
308
+ "blockCalendarIds",
309
+ "allowEventTypes",
310
+ "blockEventTypes",
311
+ "allowEventKeywords",
312
+ "blockEventKeywords",
313
+ "allowAvailability",
314
+ "blockAvailability"
315
+ ],
316
+ properties: {
317
+ allowWorkBlockKinds: arrayOf({
318
+ type: "string",
319
+ enum: [
320
+ "main_activity",
321
+ "secondary_activity",
322
+ "third_activity",
323
+ "rest",
324
+ "holiday",
325
+ "custom"
326
+ ]
327
+ }),
328
+ blockWorkBlockKinds: arrayOf({
329
+ type: "string",
330
+ enum: [
331
+ "main_activity",
332
+ "secondary_activity",
333
+ "third_activity",
334
+ "rest",
335
+ "holiday",
336
+ "custom"
337
+ ]
338
+ }),
339
+ allowCalendarIds: arrayOf({ type: "string" }),
340
+ blockCalendarIds: arrayOf({ type: "string" }),
341
+ allowEventTypes: arrayOf({ type: "string" }),
342
+ blockEventTypes: arrayOf({ type: "string" }),
343
+ allowEventKeywords: arrayOf({ type: "string" }),
344
+ blockEventKeywords: arrayOf({ type: "string" }),
345
+ allowAvailability: arrayOf({ type: "string", enum: ["busy", "free"] }),
346
+ blockAvailability: arrayOf({ type: "string", enum: ["busy", "free"] })
347
+ }
348
+ };
349
+ const calendarConnection = {
350
+ type: "object",
351
+ additionalProperties: false,
352
+ required: [
353
+ "id",
354
+ "provider",
355
+ "label",
356
+ "accountLabel",
357
+ "status",
358
+ "config",
359
+ "forgeCalendarId",
360
+ "lastSyncedAt",
361
+ "lastSyncError",
362
+ "createdAt",
363
+ "updatedAt"
364
+ ],
365
+ properties: {
366
+ id: { type: "string" },
367
+ provider: { type: "string", enum: ["google", "apple", "caldav"] },
368
+ label: { type: "string" },
369
+ accountLabel: { type: "string" },
370
+ status: {
371
+ type: "string",
372
+ enum: ["connected", "needs_attention", "error"]
373
+ },
374
+ config: { type: "object", additionalProperties: true },
375
+ forgeCalendarId: nullable({ type: "string" }),
376
+ lastSyncedAt: nullable({ type: "string", format: "date-time" }),
377
+ lastSyncError: nullable({ type: "string" }),
378
+ createdAt: { type: "string", format: "date-time" },
379
+ updatedAt: { type: "string", format: "date-time" }
380
+ }
381
+ };
382
+ const calendarResource = {
383
+ type: "object",
384
+ additionalProperties: false,
385
+ required: [
386
+ "id",
387
+ "connectionId",
388
+ "remoteId",
389
+ "title",
390
+ "description",
391
+ "color",
392
+ "timezone",
393
+ "isPrimary",
394
+ "canWrite",
395
+ "forgeManaged",
396
+ "lastSyncedAt",
397
+ "createdAt",
398
+ "updatedAt"
399
+ ],
400
+ properties: {
401
+ id: { type: "string" },
402
+ connectionId: { type: "string" },
403
+ remoteId: { type: "string" },
404
+ title: { type: "string" },
405
+ description: { type: "string" },
406
+ color: { type: "string" },
407
+ timezone: { type: "string" },
408
+ isPrimary: { type: "boolean" },
409
+ canWrite: { type: "boolean" },
410
+ forgeManaged: { type: "boolean" },
411
+ lastSyncedAt: nullable({ type: "string", format: "date-time" }),
412
+ createdAt: { type: "string", format: "date-time" },
413
+ updatedAt: { type: "string", format: "date-time" }
414
+ }
415
+ };
416
+ const calendarEventSource = {
417
+ type: "object",
418
+ additionalProperties: false,
419
+ required: [
420
+ "id",
421
+ "provider",
422
+ "connectionId",
423
+ "calendarId",
424
+ "remoteCalendarId",
425
+ "remoteEventId",
426
+ "remoteUid",
427
+ "recurrenceInstanceId",
428
+ "isMasterRecurring",
429
+ "remoteHref",
430
+ "remoteEtag",
431
+ "syncState",
432
+ "lastSyncedAt",
433
+ "createdAt",
434
+ "updatedAt"
435
+ ],
436
+ properties: {
437
+ id: { type: "string" },
438
+ provider: { type: "string", enum: ["google", "apple", "caldav"] },
439
+ connectionId: nullable({ type: "string" }),
440
+ calendarId: nullable({ type: "string" }),
441
+ remoteCalendarId: nullable({ type: "string" }),
442
+ remoteEventId: { type: "string" },
443
+ remoteUid: nullable({ type: "string" }),
444
+ recurrenceInstanceId: nullable({ type: "string" }),
445
+ isMasterRecurring: { type: "boolean" },
446
+ remoteHref: nullable({ type: "string" }),
447
+ remoteEtag: nullable({ type: "string" }),
448
+ syncState: {
449
+ type: "string",
450
+ enum: [
451
+ "pending_create",
452
+ "pending_update",
453
+ "pending_delete",
454
+ "synced",
455
+ "error",
456
+ "deleted"
457
+ ]
458
+ },
459
+ lastSyncedAt: nullable({ type: "string", format: "date-time" }),
460
+ createdAt: { type: "string", format: "date-time" },
461
+ updatedAt: { type: "string", format: "date-time" }
462
+ }
463
+ };
464
+ const calendarEventLink = {
465
+ type: "object",
466
+ additionalProperties: false,
467
+ required: [
468
+ "id",
469
+ "entityType",
470
+ "entityId",
471
+ "relationshipType",
472
+ "createdAt",
473
+ "updatedAt"
474
+ ],
475
+ properties: {
476
+ id: { type: "string" },
477
+ entityType: { $ref: "#/components/schemas/CrudEntityType" },
478
+ entityId: { type: "string" },
479
+ relationshipType: { type: "string" },
480
+ createdAt: { type: "string", format: "date-time" },
481
+ updatedAt: { type: "string", format: "date-time" }
482
+ }
483
+ };
484
+ const calendarEvent = {
485
+ type: "object",
486
+ additionalProperties: false,
487
+ required: [
488
+ "id",
489
+ "connectionId",
490
+ "calendarId",
491
+ "remoteId",
492
+ "ownership",
493
+ "originType",
494
+ "status",
495
+ "title",
496
+ "description",
497
+ "location",
498
+ "startAt",
499
+ "endAt",
500
+ "timezone",
501
+ "isAllDay",
502
+ "availability",
503
+ "eventType",
504
+ "categories",
505
+ "sourceMappings",
506
+ "links",
507
+ "remoteUpdatedAt",
508
+ "deletedAt",
509
+ "createdAt",
510
+ "updatedAt"
511
+ ],
512
+ properties: {
513
+ id: { type: "string" },
514
+ connectionId: nullable({ type: "string" }),
515
+ calendarId: nullable({ type: "string" }),
516
+ remoteId: nullable({ type: "string" }),
517
+ ownership: { type: "string", enum: ["external", "forge"] },
518
+ originType: {
519
+ type: "string",
520
+ enum: ["native", "google", "apple", "caldav", "derived"]
521
+ },
522
+ status: { type: "string", enum: ["confirmed", "tentative", "cancelled"] },
523
+ title: { type: "string" },
524
+ description: { type: "string" },
525
+ location: { type: "string" },
526
+ startAt: { type: "string", format: "date-time" },
527
+ endAt: { type: "string", format: "date-time" },
528
+ timezone: { type: "string" },
529
+ isAllDay: { type: "boolean" },
530
+ availability: { type: "string", enum: ["busy", "free"] },
531
+ eventType: { type: "string" },
532
+ categories: arrayOf({ type: "string" }),
533
+ sourceMappings: arrayOf({
534
+ $ref: "#/components/schemas/CalendarEventSource"
535
+ }),
536
+ links: arrayOf({ $ref: "#/components/schemas/CalendarEventLink" }),
537
+ remoteUpdatedAt: nullable({ type: "string", format: "date-time" }),
538
+ deletedAt: nullable({ type: "string", format: "date-time" }),
539
+ createdAt: { type: "string", format: "date-time" },
540
+ updatedAt: { type: "string", format: "date-time" }
541
+ }
542
+ };
543
+ const workBlockTemplate = {
544
+ type: "object",
545
+ additionalProperties: false,
546
+ required: [
547
+ "id",
548
+ "title",
549
+ "kind",
550
+ "color",
551
+ "timezone",
552
+ "weekDays",
553
+ "startMinute",
554
+ "endMinute",
555
+ "startsOn",
556
+ "endsOn",
557
+ "blockingState",
558
+ "createdAt",
559
+ "updatedAt"
560
+ ],
561
+ properties: {
562
+ id: { type: "string" },
563
+ title: { type: "string" },
564
+ kind: {
565
+ type: "string",
566
+ enum: [
567
+ "main_activity",
568
+ "secondary_activity",
569
+ "third_activity",
570
+ "rest",
571
+ "holiday",
572
+ "custom"
573
+ ]
574
+ },
575
+ color: { type: "string" },
576
+ timezone: { type: "string" },
577
+ weekDays: arrayOf({ type: "integer", minimum: 0, maximum: 6 }),
578
+ startMinute: { type: "integer" },
579
+ endMinute: { type: "integer" },
580
+ startsOn: nullable({ type: "string", format: "date" }),
581
+ endsOn: nullable({ type: "string", format: "date" }),
582
+ blockingState: { type: "string", enum: ["allowed", "blocked"] },
583
+ createdAt: { type: "string", format: "date-time" },
584
+ updatedAt: { type: "string", format: "date-time" }
585
+ }
586
+ };
587
+ const workBlockInstance = {
588
+ type: "object",
589
+ additionalProperties: false,
590
+ required: [
591
+ "id",
592
+ "templateId",
593
+ "dateKey",
594
+ "startAt",
595
+ "endAt",
596
+ "title",
597
+ "kind",
598
+ "color",
599
+ "blockingState",
600
+ "calendarEventId",
601
+ "createdAt",
602
+ "updatedAt"
603
+ ],
604
+ properties: {
605
+ id: { type: "string" },
606
+ templateId: { type: "string" },
607
+ dateKey: { type: "string", format: "date" },
608
+ startAt: { type: "string", format: "date-time" },
609
+ endAt: { type: "string", format: "date-time" },
610
+ title: { type: "string" },
611
+ kind: {
612
+ type: "string",
613
+ enum: [
614
+ "main_activity",
615
+ "secondary_activity",
616
+ "third_activity",
617
+ "rest",
618
+ "holiday",
619
+ "custom"
620
+ ]
621
+ },
622
+ color: { type: "string" },
623
+ blockingState: { type: "string", enum: ["allowed", "blocked"] },
624
+ calendarEventId: nullable({ type: "string" }),
625
+ createdAt: { type: "string", format: "date-time" },
626
+ updatedAt: { type: "string", format: "date-time" }
627
+ }
628
+ };
629
+ const taskTimebox = {
630
+ type: "object",
631
+ additionalProperties: false,
632
+ required: [
633
+ "id",
634
+ "taskId",
635
+ "projectId",
636
+ "connectionId",
637
+ "calendarId",
638
+ "remoteEventId",
639
+ "linkedTaskRunId",
640
+ "status",
641
+ "source",
642
+ "title",
643
+ "startsAt",
644
+ "endsAt",
645
+ "overrideReason",
646
+ "createdAt",
647
+ "updatedAt"
648
+ ],
649
+ properties: {
650
+ id: { type: "string" },
651
+ taskId: { type: "string" },
652
+ projectId: nullable({ type: "string" }),
653
+ connectionId: nullable({ type: "string" }),
654
+ calendarId: nullable({ type: "string" }),
655
+ remoteEventId: nullable({ type: "string" }),
656
+ linkedTaskRunId: nullable({ type: "string" }),
657
+ status: {
658
+ type: "string",
659
+ enum: ["planned", "active", "completed", "cancelled"]
660
+ },
661
+ source: { type: "string", enum: ["manual", "suggested", "live_run"] },
662
+ title: { type: "string" },
663
+ startsAt: { type: "string", format: "date-time" },
664
+ endsAt: { type: "string", format: "date-time" },
665
+ overrideReason: nullable({ type: "string" }),
666
+ createdAt: { type: "string", format: "date-time" },
667
+ updatedAt: { type: "string", format: "date-time" }
668
+ }
669
+ };
670
+ const calendarOverviewPayload = {
671
+ type: "object",
672
+ additionalProperties: false,
673
+ required: [
674
+ "generatedAt",
675
+ "providers",
676
+ "connections",
677
+ "calendars",
678
+ "events",
679
+ "workBlockTemplates",
680
+ "workBlockInstances",
681
+ "timeboxes"
682
+ ],
683
+ properties: {
684
+ generatedAt: { type: "string", format: "date-time" },
685
+ providers: arrayOf({
686
+ type: "object",
687
+ additionalProperties: false,
688
+ required: [
689
+ "provider",
690
+ "label",
691
+ "supportsDedicatedForgeCalendar",
692
+ "connectionHelp"
693
+ ],
694
+ properties: {
695
+ provider: { type: "string", enum: ["google", "apple", "caldav"] },
696
+ label: { type: "string" },
697
+ supportsDedicatedForgeCalendar: { type: "boolean" },
698
+ connectionHelp: { type: "string" }
699
+ }
700
+ }),
701
+ connections: arrayOf({ $ref: "#/components/schemas/CalendarConnection" }),
702
+ calendars: arrayOf({ $ref: "#/components/schemas/CalendarResource" }),
703
+ events: arrayOf({ $ref: "#/components/schemas/CalendarEvent" }),
704
+ workBlockTemplates: arrayOf({
705
+ $ref: "#/components/schemas/WorkBlockTemplate"
706
+ }),
707
+ workBlockInstances: arrayOf({
708
+ $ref: "#/components/schemas/WorkBlockInstance"
709
+ }),
710
+ timeboxes: arrayOf({ $ref: "#/components/schemas/TaskTimebox" })
243
711
  }
244
712
  };
245
713
  const habitCheckIn = {
246
714
  type: "object",
247
715
  additionalProperties: false,
248
- required: ["id", "habitId", "dateKey", "status", "note", "deltaXp", "createdAt", "updatedAt"],
716
+ required: [
717
+ "id",
718
+ "habitId",
719
+ "dateKey",
720
+ "status",
721
+ "note",
722
+ "deltaXp",
723
+ "createdAt",
724
+ "updatedAt"
725
+ ],
249
726
  properties: {
250
727
  id: { type: "string" },
251
728
  habitId: { type: "string" },
@@ -328,7 +805,18 @@ export function buildOpenApiDocument() {
328
805
  const activityEvent = {
329
806
  type: "object",
330
807
  additionalProperties: false,
331
- required: ["id", "entityType", "entityId", "eventType", "title", "description", "actor", "source", "metadata", "createdAt"],
808
+ required: [
809
+ "id",
810
+ "entityType",
811
+ "entityId",
812
+ "eventType",
813
+ "title",
814
+ "description",
815
+ "actor",
816
+ "source",
817
+ "metadata",
818
+ "createdAt"
819
+ ],
332
820
  properties: {
333
821
  id: { type: "string" },
334
822
  entityType: {
@@ -368,7 +856,12 @@ export function buildOpenApiDocument() {
368
856
  metadata: {
369
857
  type: "object",
370
858
  additionalProperties: {
371
- anyOf: [{ type: "string" }, { type: "number" }, { type: "boolean" }, { type: "null" }]
859
+ anyOf: [
860
+ { type: "string" },
861
+ { type: "number" },
862
+ { type: "boolean" },
863
+ { type: "null" }
864
+ ]
372
865
  }
373
866
  },
374
867
  createdAt: { type: "string", format: "date-time" }
@@ -377,7 +870,18 @@ export function buildOpenApiDocument() {
377
870
  const gamificationProfile = {
378
871
  type: "object",
379
872
  additionalProperties: false,
380
- required: ["totalXp", "level", "currentLevelXp", "nextLevelXp", "weeklyXp", "streakDays", "comboMultiplier", "momentumScore", "topGoalId", "topGoalTitle"],
873
+ required: [
874
+ "totalXp",
875
+ "level",
876
+ "currentLevelXp",
877
+ "nextLevelXp",
878
+ "weeklyXp",
879
+ "streakDays",
880
+ "comboMultiplier",
881
+ "momentumScore",
882
+ "topGoalId",
883
+ "topGoalTitle"
884
+ ],
381
885
  properties: {
382
886
  totalXp: { type: "integer" },
383
887
  level: { type: "integer" },
@@ -404,7 +908,18 @@ export function buildOpenApiDocument() {
404
908
  const note = {
405
909
  type: "object",
406
910
  additionalProperties: false,
407
- required: ["id", "contentMarkdown", "contentPlain", "author", "source", "createdAt", "updatedAt", "links"],
911
+ required: [
912
+ "id",
913
+ "contentMarkdown",
914
+ "contentPlain",
915
+ "author",
916
+ "source",
917
+ "createdAt",
918
+ "updatedAt",
919
+ "links",
920
+ "tags",
921
+ "destroyAt"
922
+ ],
408
923
  properties: {
409
924
  id: { type: "string" },
410
925
  contentMarkdown: { type: "string" },
@@ -413,7 +928,9 @@ export function buildOpenApiDocument() {
413
928
  source: { type: "string", enum: ["ui", "openclaw", "agent", "system"] },
414
929
  createdAt: { type: "string", format: "date-time" },
415
930
  updatedAt: { type: "string", format: "date-time" },
416
- links: arrayOf({ $ref: "#/components/schemas/NoteLink" })
931
+ links: arrayOf({ $ref: "#/components/schemas/NoteLink" }),
932
+ tags: arrayOf({ type: "string" }),
933
+ destroyAt: nullable({ type: "string", format: "date-time" })
417
934
  }
418
935
  };
419
936
  const noteSummary = {
@@ -433,7 +950,15 @@ export function buildOpenApiDocument() {
433
950
  const achievementSignal = {
434
951
  type: "object",
435
952
  additionalProperties: false,
436
- required: ["id", "title", "summary", "tier", "progressLabel", "unlocked", "unlockedAt"],
953
+ required: [
954
+ "id",
955
+ "title",
956
+ "summary",
957
+ "tier",
958
+ "progressLabel",
959
+ "unlocked",
960
+ "unlockedAt"
961
+ ],
437
962
  properties: {
438
963
  id: { type: "string" },
439
964
  title: { type: "string" },
@@ -447,7 +972,16 @@ export function buildOpenApiDocument() {
447
972
  const milestoneReward = {
448
973
  type: "object",
449
974
  additionalProperties: false,
450
- required: ["id", "title", "summary", "rewardLabel", "progressLabel", "current", "target", "completed"],
975
+ required: [
976
+ "id",
977
+ "title",
978
+ "summary",
979
+ "rewardLabel",
980
+ "progressLabel",
981
+ "current",
982
+ "target",
983
+ "completed"
984
+ ],
451
985
  properties: {
452
986
  id: { type: "string" },
453
987
  title: { type: "string" },
@@ -462,12 +996,35 @@ export function buildOpenApiDocument() {
462
996
  const dashboardPayload = {
463
997
  type: "object",
464
998
  additionalProperties: false,
465
- required: ["stats", "goals", "projects", "tasks", "habits", "tags", "suggestedTags", "owners", "executionBuckets", "gamification", "achievements", "milestoneRewards", "recentActivity", "notesSummaryByEntity"],
999
+ required: [
1000
+ "stats",
1001
+ "goals",
1002
+ "projects",
1003
+ "tasks",
1004
+ "habits",
1005
+ "tags",
1006
+ "suggestedTags",
1007
+ "owners",
1008
+ "executionBuckets",
1009
+ "gamification",
1010
+ "achievements",
1011
+ "milestoneRewards",
1012
+ "recentActivity",
1013
+ "notesSummaryByEntity"
1014
+ ],
466
1015
  properties: {
467
1016
  stats: {
468
1017
  type: "object",
469
1018
  additionalProperties: false,
470
- required: ["totalPoints", "completedThisWeek", "activeGoals", "alignmentScore", "focusTasks", "overdueTasks", "dueThisWeek"],
1019
+ required: [
1020
+ "totalPoints",
1021
+ "completedThisWeek",
1022
+ "activeGoals",
1023
+ "alignmentScore",
1024
+ "focusTasks",
1025
+ "overdueTasks",
1026
+ "dueThisWeek"
1027
+ ],
471
1028
  properties: {
472
1029
  totalPoints: { type: "integer" },
473
1030
  completedThisWeek: { type: "integer" },
@@ -490,30 +1047,60 @@ export function buildOpenApiDocument() {
490
1047
  additionalProperties: false,
491
1048
  required: ["id", "label", "summary", "tone", "tasks"],
492
1049
  properties: {
493
- id: { type: "string", enum: ["overdue", "due_soon", "focus_now", "recently_completed"] },
1050
+ id: {
1051
+ type: "string",
1052
+ enum: ["overdue", "due_soon", "focus_now", "recently_completed"]
1053
+ },
494
1054
  label: { type: "string" },
495
1055
  summary: { type: "string" },
496
- tone: { type: "string", enum: ["urgent", "accent", "neutral", "success"] },
1056
+ tone: {
1057
+ type: "string",
1058
+ enum: ["urgent", "accent", "neutral", "success"]
1059
+ },
497
1060
  tasks: arrayOf({ $ref: "#/components/schemas/Task" })
498
1061
  }
499
1062
  }),
500
1063
  gamification: { $ref: "#/components/schemas/GamificationProfile" },
501
1064
  achievements: arrayOf({ $ref: "#/components/schemas/AchievementSignal" }),
502
- milestoneRewards: arrayOf({ $ref: "#/components/schemas/MilestoneReward" }),
1065
+ milestoneRewards: arrayOf({
1066
+ $ref: "#/components/schemas/MilestoneReward"
1067
+ }),
503
1068
  recentActivity: arrayOf({ $ref: "#/components/schemas/ActivityEvent" }),
504
- notesSummaryByEntity: { $ref: "#/components/schemas/NotesSummaryByEntity" }
1069
+ notesSummaryByEntity: {
1070
+ $ref: "#/components/schemas/NotesSummaryByEntity"
1071
+ }
505
1072
  }
506
1073
  };
507
1074
  const overviewContext = {
508
1075
  type: "object",
509
1076
  additionalProperties: false,
510
- required: ["generatedAt", "strategicHeader", "projects", "activeGoals", "topTasks", "dueHabits", "recentEvidence", "achievements", "domainBalance", "neglectedGoals"],
1077
+ required: [
1078
+ "generatedAt",
1079
+ "strategicHeader",
1080
+ "projects",
1081
+ "activeGoals",
1082
+ "topTasks",
1083
+ "dueHabits",
1084
+ "recentEvidence",
1085
+ "achievements",
1086
+ "domainBalance",
1087
+ "neglectedGoals"
1088
+ ],
511
1089
  properties: {
512
1090
  generatedAt: { type: "string", format: "date-time" },
513
1091
  strategicHeader: {
514
1092
  type: "object",
515
1093
  additionalProperties: false,
516
- required: ["streakDays", "level", "totalXp", "currentLevelXp", "nextLevelXp", "momentumScore", "focusTasks", "overdueTasks"],
1094
+ required: [
1095
+ "streakDays",
1096
+ "level",
1097
+ "totalXp",
1098
+ "currentLevelXp",
1099
+ "nextLevelXp",
1100
+ "momentumScore",
1101
+ "focusTasks",
1102
+ "overdueTasks"
1103
+ ],
517
1104
  properties: {
518
1105
  streakDays: { type: "integer" },
519
1106
  level: { type: "integer" },
@@ -534,7 +1121,15 @@ export function buildOpenApiDocument() {
534
1121
  domainBalance: arrayOf({
535
1122
  type: "object",
536
1123
  additionalProperties: false,
537
- required: ["tagId", "label", "color", "goalCount", "activeTaskCount", "completedPoints", "momentumLabel"],
1124
+ required: [
1125
+ "tagId",
1126
+ "label",
1127
+ "color",
1128
+ "goalCount",
1129
+ "activeTaskCount",
1130
+ "completedPoints",
1131
+ "momentumLabel"
1132
+ ],
538
1133
  properties: {
539
1134
  tagId: { type: "string" },
540
1135
  label: { type: "string" },
@@ -561,7 +1156,16 @@ export function buildOpenApiDocument() {
561
1156
  const todayContext = {
562
1157
  type: "object",
563
1158
  additionalProperties: false,
564
- required: ["generatedAt", "directive", "timeline", "dueHabits", "dailyQuests", "milestoneRewards", "recentHabitRewards", "momentum"],
1159
+ required: [
1160
+ "generatedAt",
1161
+ "directive",
1162
+ "timeline",
1163
+ "dueHabits",
1164
+ "dailyQuests",
1165
+ "milestoneRewards",
1166
+ "recentHabitRewards",
1167
+ "momentum"
1168
+ ],
565
1169
  properties: {
566
1170
  generatedAt: { type: "string", format: "date-time" },
567
1171
  directive: {
@@ -580,7 +1184,10 @@ export function buildOpenApiDocument() {
580
1184
  additionalProperties: false,
581
1185
  required: ["id", "label", "tasks"],
582
1186
  properties: {
583
- id: { type: "string", enum: ["completed", "active", "upcoming", "deferred"] },
1187
+ id: {
1188
+ type: "string",
1189
+ enum: ["completed", "active", "upcoming", "deferred"]
1190
+ },
584
1191
  label: { type: "string" },
585
1192
  tasks: arrayOf({ $ref: "#/components/schemas/Task" })
586
1193
  }
@@ -589,7 +1196,14 @@ export function buildOpenApiDocument() {
589
1196
  dailyQuests: arrayOf({
590
1197
  type: "object",
591
1198
  additionalProperties: false,
592
- required: ["id", "title", "summary", "rewardXp", "progressLabel", "completed"],
1199
+ required: [
1200
+ "id",
1201
+ "title",
1202
+ "summary",
1203
+ "rewardXp",
1204
+ "progressLabel",
1205
+ "completed"
1206
+ ],
593
1207
  properties: {
594
1208
  id: { type: "string" },
595
1209
  title: { type: "string" },
@@ -599,8 +1213,12 @@ export function buildOpenApiDocument() {
599
1213
  completed: { type: "boolean" }
600
1214
  }
601
1215
  }),
602
- milestoneRewards: arrayOf({ $ref: "#/components/schemas/MilestoneReward" }),
603
- recentHabitRewards: arrayOf({ $ref: "#/components/schemas/RewardLedgerEvent" }),
1216
+ milestoneRewards: arrayOf({
1217
+ $ref: "#/components/schemas/MilestoneReward"
1218
+ }),
1219
+ recentHabitRewards: arrayOf({
1220
+ $ref: "#/components/schemas/RewardLedgerEvent"
1221
+ }),
604
1222
  momentum: {
605
1223
  type: "object",
606
1224
  additionalProperties: false,
@@ -616,7 +1234,13 @@ export function buildOpenApiDocument() {
616
1234
  const riskContext = {
617
1235
  type: "object",
618
1236
  additionalProperties: false,
619
- required: ["generatedAt", "overdueTasks", "blockedTasks", "neglectedGoals", "summary"],
1237
+ required: [
1238
+ "generatedAt",
1239
+ "overdueTasks",
1240
+ "blockedTasks",
1241
+ "neglectedGoals",
1242
+ "summary"
1243
+ ],
620
1244
  properties: {
621
1245
  generatedAt: { type: "string", format: "date-time" },
622
1246
  overdueTasks: arrayOf({ $ref: "#/components/schemas/Task" }),
@@ -638,7 +1262,21 @@ export function buildOpenApiDocument() {
638
1262
  const forgeSnapshot = {
639
1263
  type: "object",
640
1264
  additionalProperties: false,
641
- required: ["meta", "metrics", "dashboard", "overview", "today", "risk", "goals", "projects", "tags", "tasks", "habits", "activeTaskRuns", "activity"],
1265
+ required: [
1266
+ "meta",
1267
+ "metrics",
1268
+ "dashboard",
1269
+ "overview",
1270
+ "today",
1271
+ "risk",
1272
+ "goals",
1273
+ "projects",
1274
+ "tags",
1275
+ "tasks",
1276
+ "habits",
1277
+ "activeTaskRuns",
1278
+ "activity"
1279
+ ],
642
1280
  properties: {
643
1281
  meta: {
644
1282
  type: "object",
@@ -669,7 +1307,15 @@ export function buildOpenApiDocument() {
669
1307
  const taskContextPayload = {
670
1308
  type: "object",
671
1309
  additionalProperties: false,
672
- required: ["task", "goal", "project", "activeTaskRun", "taskRuns", "activity", "notesSummaryByEntity"],
1310
+ required: [
1311
+ "task",
1312
+ "goal",
1313
+ "project",
1314
+ "activeTaskRun",
1315
+ "taskRuns",
1316
+ "activity",
1317
+ "notesSummaryByEntity"
1318
+ ],
673
1319
  properties: {
674
1320
  task: { $ref: "#/components/schemas/Task" },
675
1321
  goal: nullable({ $ref: "#/components/schemas/Goal" }),
@@ -677,7 +1323,9 @@ export function buildOpenApiDocument() {
677
1323
  activeTaskRun: nullable({ $ref: "#/components/schemas/TaskRun" }),
678
1324
  taskRuns: arrayOf({ $ref: "#/components/schemas/TaskRun" }),
679
1325
  activity: arrayOf({ $ref: "#/components/schemas/ActivityEvent" }),
680
- notesSummaryByEntity: { $ref: "#/components/schemas/NotesSummaryByEntity" }
1326
+ notesSummaryByEntity: {
1327
+ $ref: "#/components/schemas/NotesSummaryByEntity"
1328
+ }
681
1329
  }
682
1330
  };
683
1331
  const projectBoardPayload = {
@@ -689,13 +1337,25 @@ export function buildOpenApiDocument() {
689
1337
  goal: { $ref: "#/components/schemas/Goal" },
690
1338
  tasks: arrayOf({ $ref: "#/components/schemas/Task" }),
691
1339
  activity: arrayOf({ $ref: "#/components/schemas/ActivityEvent" }),
692
- notesSummaryByEntity: { $ref: "#/components/schemas/NotesSummaryByEntity" }
1340
+ notesSummaryByEntity: {
1341
+ $ref: "#/components/schemas/NotesSummaryByEntity"
1342
+ }
693
1343
  }
694
1344
  };
695
1345
  const insightsPayload = {
696
1346
  type: "object",
697
1347
  additionalProperties: false,
698
- required: ["generatedAt", "status", "momentumHeatmap", "executionTrends", "domainBalance", "coaching", "evidenceDigest", "feed", "openCount"],
1348
+ required: [
1349
+ "generatedAt",
1350
+ "status",
1351
+ "momentumHeatmap",
1352
+ "executionTrends",
1353
+ "domainBalance",
1354
+ "coaching",
1355
+ "evidenceDigest",
1356
+ "feed",
1357
+ "openCount"
1358
+ ],
699
1359
  properties: {
700
1360
  generatedAt: { type: "string", format: "date-time" },
701
1361
  status: {
@@ -760,10 +1420,25 @@ export function buildOpenApiDocument() {
760
1420
  const weeklyReviewPayload = {
761
1421
  type: "object",
762
1422
  additionalProperties: false,
763
- required: ["generatedAt", "windowLabel", "momentumSummary", "chart", "wins", "calibration", "reward"],
1423
+ required: [
1424
+ "generatedAt",
1425
+ "windowLabel",
1426
+ "weekKey",
1427
+ "weekStartDate",
1428
+ "weekEndDate",
1429
+ "momentumSummary",
1430
+ "chart",
1431
+ "wins",
1432
+ "calibration",
1433
+ "reward",
1434
+ "completion"
1435
+ ],
764
1436
  properties: {
765
1437
  generatedAt: { type: "string", format: "date-time" },
766
1438
  windowLabel: { type: "string" },
1439
+ weekKey: { type: "string" },
1440
+ weekStartDate: { type: "string" },
1441
+ weekEndDate: { type: "string" },
767
1442
  momentumSummary: {
768
1443
  type: "object",
769
1444
  additionalProperties: false,
@@ -816,13 +1491,39 @@ export function buildOpenApiDocument() {
816
1491
  summary: { type: "string" },
817
1492
  rewardXp: { type: "integer" }
818
1493
  }
1494
+ },
1495
+ completion: {
1496
+ type: "object",
1497
+ additionalProperties: false,
1498
+ required: ["finalized", "finalizedAt", "finalizedBy"],
1499
+ properties: {
1500
+ finalized: { type: "boolean" },
1501
+ finalizedAt: nullable({ type: "string", format: "date-time" }),
1502
+ finalizedBy: nullable({ type: "string" })
1503
+ }
819
1504
  }
820
1505
  }
821
1506
  };
822
1507
  const agentTokenSummary = {
823
1508
  type: "object",
824
1509
  additionalProperties: false,
825
- required: ["id", "label", "tokenPrefix", "scopes", "agentId", "agentLabel", "trustLevel", "autonomyMode", "approvalMode", "description", "lastUsedAt", "revokedAt", "createdAt", "updatedAt", "status"],
1510
+ required: [
1511
+ "id",
1512
+ "label",
1513
+ "tokenPrefix",
1514
+ "scopes",
1515
+ "agentId",
1516
+ "agentLabel",
1517
+ "trustLevel",
1518
+ "autonomyMode",
1519
+ "approvalMode",
1520
+ "description",
1521
+ "lastUsedAt",
1522
+ "revokedAt",
1523
+ "createdAt",
1524
+ "updatedAt",
1525
+ "status"
1526
+ ],
826
1527
  properties: {
827
1528
  id: { type: "string" },
828
1529
  label: { type: "string" },
@@ -830,9 +1531,18 @@ export function buildOpenApiDocument() {
830
1531
  scopes: arrayOf({ type: "string" }),
831
1532
  agentId: nullable({ type: "string" }),
832
1533
  agentLabel: nullable({ type: "string" }),
833
- trustLevel: { type: "string", enum: ["standard", "trusted", "autonomous"] },
834
- autonomyMode: { type: "string", enum: ["approval_required", "scoped_write", "autonomous"] },
835
- approvalMode: { type: "string", enum: ["approval_by_default", "high_impact_only", "none"] },
1534
+ trustLevel: {
1535
+ type: "string",
1536
+ enum: ["standard", "trusted", "autonomous"]
1537
+ },
1538
+ autonomyMode: {
1539
+ type: "string",
1540
+ enum: ["approval_required", "scoped_write", "autonomous"]
1541
+ },
1542
+ approvalMode: {
1543
+ type: "string",
1544
+ enum: ["approval_by_default", "high_impact_only", "none"]
1545
+ },
836
1546
  description: { type: "string" },
837
1547
  lastUsedAt: nullable({ type: "string", format: "date-time" }),
838
1548
  revokedAt: nullable({ type: "string", format: "date-time" }),
@@ -847,7 +1557,10 @@ export function buildOpenApiDocument() {
847
1557
  required: ["maxActiveTasks", "timeAccountingMode"],
848
1558
  properties: {
849
1559
  maxActiveTasks: { type: "integer", minimum: 1, maximum: 8 },
850
- timeAccountingMode: { type: "string", enum: ["split", "parallel", "primary_only"] }
1560
+ timeAccountingMode: {
1561
+ type: "string",
1562
+ enum: ["split", "parallel", "primary_only"]
1563
+ }
851
1564
  }
852
1565
  };
853
1566
  const taskRunClaimInput = {
@@ -856,10 +1569,24 @@ export function buildOpenApiDocument() {
856
1569
  required: ["actor"],
857
1570
  properties: {
858
1571
  actor: { type: "string" },
859
- timerMode: { type: "string", enum: ["planned", "unlimited"], default: "unlimited" },
860
- plannedDurationSeconds: nullable({ type: "integer", minimum: 60, maximum: 86400 }),
1572
+ timerMode: {
1573
+ type: "string",
1574
+ enum: ["planned", "unlimited"],
1575
+ default: "unlimited"
1576
+ },
1577
+ plannedDurationSeconds: nullable({
1578
+ type: "integer",
1579
+ minimum: 60,
1580
+ maximum: 86400
1581
+ }),
1582
+ overrideReason: nullable({ type: "string" }),
861
1583
  isCurrent: { type: "boolean", default: true },
862
- leaseTtlSeconds: { type: "integer", minimum: 1, maximum: 14400, default: 900 },
1584
+ leaseTtlSeconds: {
1585
+ type: "integer",
1586
+ minimum: 1,
1587
+ maximum: 14400,
1588
+ default: 900
1589
+ },
863
1590
  note: { type: "string", default: "" }
864
1591
  }
865
1592
  };
@@ -868,7 +1595,12 @@ export function buildOpenApiDocument() {
868
1595
  additionalProperties: false,
869
1596
  properties: {
870
1597
  actor: { type: "string" },
871
- leaseTtlSeconds: { type: "integer", minimum: 1, maximum: 14400, default: 900 },
1598
+ leaseTtlSeconds: {
1599
+ type: "integer",
1600
+ minimum: 1,
1601
+ maximum: 14400,
1602
+ default: 900
1603
+ },
872
1604
  note: { type: "string" }
873
1605
  }
874
1606
  };
@@ -897,6 +1629,65 @@ export function buildOpenApiDocument() {
897
1629
  actor: { type: "string" }
898
1630
  }
899
1631
  };
1632
+ const workAdjustment = {
1633
+ type: "object",
1634
+ additionalProperties: false,
1635
+ required: [
1636
+ "id",
1637
+ "entityType",
1638
+ "entityId",
1639
+ "requestedDeltaMinutes",
1640
+ "appliedDeltaMinutes",
1641
+ "note",
1642
+ "actor",
1643
+ "source",
1644
+ "createdAt"
1645
+ ],
1646
+ properties: {
1647
+ id: { type: "string" },
1648
+ entityType: { type: "string", enum: ["task", "project"] },
1649
+ entityId: { type: "string" },
1650
+ requestedDeltaMinutes: { type: "integer" },
1651
+ appliedDeltaMinutes: { type: "integer" },
1652
+ note: { type: "string" },
1653
+ actor: nullable({ type: "string" }),
1654
+ source: { type: "string", enum: ["ui", "openclaw", "agent", "system"] },
1655
+ createdAt: { type: "string", format: "date-time" }
1656
+ }
1657
+ };
1658
+ const workAdjustmentTargetSummary = {
1659
+ type: "object",
1660
+ additionalProperties: false,
1661
+ required: ["entityType", "entityId", "title", "time"],
1662
+ properties: {
1663
+ entityType: { type: "string", enum: ["task", "project"] },
1664
+ entityId: { type: "string" },
1665
+ title: { type: "string" },
1666
+ time: { $ref: "#/components/schemas/TaskTimeSummary" }
1667
+ }
1668
+ };
1669
+ const workAdjustmentInput = {
1670
+ type: "object",
1671
+ additionalProperties: false,
1672
+ required: ["entityType", "entityId", "deltaMinutes"],
1673
+ properties: {
1674
+ entityType: { type: "string", enum: ["task", "project"] },
1675
+ entityId: { type: "string" },
1676
+ deltaMinutes: { type: "integer" },
1677
+ note: { type: "string", default: "" }
1678
+ }
1679
+ };
1680
+ const workAdjustmentResult = {
1681
+ type: "object",
1682
+ additionalProperties: false,
1683
+ required: ["adjustment", "target", "reward", "metrics"],
1684
+ properties: {
1685
+ adjustment: { $ref: "#/components/schemas/WorkAdjustment" },
1686
+ target: { $ref: "#/components/schemas/WorkAdjustmentTargetSummary" },
1687
+ reward: nullable({ $ref: "#/components/schemas/RewardLedgerEvent" }),
1688
+ metrics: { $ref: "#/components/schemas/XpMetricsPayload" }
1689
+ }
1690
+ };
900
1691
  const settingsUpdateInput = {
901
1692
  type: "object",
902
1693
  additionalProperties: false,
@@ -924,24 +1715,51 @@ export function buildOpenApiDocument() {
924
1715
  additionalProperties: false,
925
1716
  properties: {
926
1717
  maxActiveTasks: { type: "integer", minimum: 1, maximum: 8 },
927
- timeAccountingMode: { type: "string", enum: ["split", "parallel", "primary_only"] }
1718
+ timeAccountingMode: {
1719
+ type: "string",
1720
+ enum: ["split", "parallel", "primary_only"]
1721
+ }
928
1722
  }
929
1723
  },
930
- themePreference: { type: "string", enum: ["obsidian", "solar", "system"] },
1724
+ themePreference: {
1725
+ type: "string",
1726
+ enum: ["obsidian", "solar", "system"]
1727
+ },
931
1728
  localePreference: { type: "string", enum: ["en", "fr"] }
932
1729
  }
933
1730
  };
934
1731
  const agentIdentity = {
935
1732
  type: "object",
936
1733
  additionalProperties: false,
937
- required: ["id", "label", "agentType", "trustLevel", "autonomyMode", "approvalMode", "description", "tokenCount", "activeTokenCount", "createdAt", "updatedAt"],
1734
+ required: [
1735
+ "id",
1736
+ "label",
1737
+ "agentType",
1738
+ "trustLevel",
1739
+ "autonomyMode",
1740
+ "approvalMode",
1741
+ "description",
1742
+ "tokenCount",
1743
+ "activeTokenCount",
1744
+ "createdAt",
1745
+ "updatedAt"
1746
+ ],
938
1747
  properties: {
939
1748
  id: { type: "string" },
940
1749
  label: { type: "string" },
941
1750
  agentType: { type: "string" },
942
- trustLevel: { type: "string", enum: ["standard", "trusted", "autonomous"] },
943
- autonomyMode: { type: "string", enum: ["approval_required", "scoped_write", "autonomous"] },
944
- approvalMode: { type: "string", enum: ["approval_by_default", "high_impact_only", "none"] },
1751
+ trustLevel: {
1752
+ type: "string",
1753
+ enum: ["standard", "trusted", "autonomous"]
1754
+ },
1755
+ autonomyMode: {
1756
+ type: "string",
1757
+ enum: ["approval_required", "scoped_write", "autonomous"]
1758
+ },
1759
+ approvalMode: {
1760
+ type: "string",
1761
+ enum: ["approval_by_default", "high_impact_only", "none"]
1762
+ },
945
1763
  description: { type: "string" },
946
1764
  tokenCount: { type: "integer" },
947
1765
  activeTokenCount: { type: "integer" },
@@ -952,14 +1770,39 @@ export function buildOpenApiDocument() {
952
1770
  const insight = {
953
1771
  type: "object",
954
1772
  additionalProperties: false,
955
- required: ["id", "originType", "originAgentId", "originLabel", "visibility", "status", "entityType", "entityId", "timeframeLabel", "title", "summary", "recommendation", "rationale", "confidence", "ctaLabel", "evidence", "createdAt", "updatedAt"],
1773
+ required: [
1774
+ "id",
1775
+ "originType",
1776
+ "originAgentId",
1777
+ "originLabel",
1778
+ "visibility",
1779
+ "status",
1780
+ "entityType",
1781
+ "entityId",
1782
+ "timeframeLabel",
1783
+ "title",
1784
+ "summary",
1785
+ "recommendation",
1786
+ "rationale",
1787
+ "confidence",
1788
+ "ctaLabel",
1789
+ "evidence",
1790
+ "createdAt",
1791
+ "updatedAt"
1792
+ ],
956
1793
  properties: {
957
1794
  id: { type: "string" },
958
1795
  originType: { type: "string", enum: ["system", "user", "agent"] },
959
1796
  originAgentId: nullable({ type: "string" }),
960
1797
  originLabel: nullable({ type: "string" }),
961
- visibility: { type: "string", enum: ["visible", "pending_review", "archived"] },
962
- status: { type: "string", enum: ["open", "accepted", "dismissed", "snoozed", "applied", "expired"] },
1798
+ visibility: {
1799
+ type: "string",
1800
+ enum: ["visible", "pending_review", "archived"]
1801
+ },
1802
+ status: {
1803
+ type: "string",
1804
+ enum: ["open", "accepted", "dismissed", "snoozed", "applied", "expired"]
1805
+ },
963
1806
  entityType: nullable({ type: "string" }),
964
1807
  entityId: nullable({ type: "string" }),
965
1808
  timeframeLabel: nullable({ type: "string" }),
@@ -991,7 +1834,10 @@ export function buildOpenApiDocument() {
991
1834
  id: { type: "string" },
992
1835
  insightId: { type: "string" },
993
1836
  actor: nullable({ type: "string" }),
994
- feedbackType: { type: "string", enum: ["accepted", "dismissed", "applied", "snoozed"] },
1837
+ feedbackType: {
1838
+ type: "string",
1839
+ enum: ["accepted", "dismissed", "applied", "snoozed"]
1840
+ },
995
1841
  note: { type: "string" },
996
1842
  createdAt: { type: "string", format: "date-time" }
997
1843
  }
@@ -999,11 +1845,32 @@ export function buildOpenApiDocument() {
999
1845
  const approvalRequest = {
1000
1846
  type: "object",
1001
1847
  additionalProperties: false,
1002
- required: ["id", "actionType", "status", "title", "summary", "entityType", "entityId", "requestedByAgentId", "requestedByTokenId", "requestedPayload", "approvedBy", "approvedAt", "rejectedBy", "rejectedAt", "resolutionNote", "createdAt", "updatedAt"],
1848
+ required: [
1849
+ "id",
1850
+ "actionType",
1851
+ "status",
1852
+ "title",
1853
+ "summary",
1854
+ "entityType",
1855
+ "entityId",
1856
+ "requestedByAgentId",
1857
+ "requestedByTokenId",
1858
+ "requestedPayload",
1859
+ "approvedBy",
1860
+ "approvedAt",
1861
+ "rejectedBy",
1862
+ "rejectedAt",
1863
+ "resolutionNote",
1864
+ "createdAt",
1865
+ "updatedAt"
1866
+ ],
1003
1867
  properties: {
1004
1868
  id: { type: "string" },
1005
1869
  actionType: { type: "string" },
1006
- status: { type: "string", enum: ["pending", "approved", "rejected", "cancelled", "executed"] },
1870
+ status: {
1871
+ type: "string",
1872
+ enum: ["pending", "approved", "rejected", "cancelled", "executed"]
1873
+ },
1007
1874
  title: { type: "string" },
1008
1875
  summary: { type: "string" },
1009
1876
  entityType: nullable({ type: "string" }),
@@ -1023,14 +1890,33 @@ export function buildOpenApiDocument() {
1023
1890
  const agentAction = {
1024
1891
  type: "object",
1025
1892
  additionalProperties: false,
1026
- required: ["id", "agentId", "tokenId", "actionType", "riskLevel", "status", "title", "summary", "payload", "idempotencyKey", "approvalRequestId", "outcome", "createdAt", "updatedAt", "completedAt"],
1893
+ required: [
1894
+ "id",
1895
+ "agentId",
1896
+ "tokenId",
1897
+ "actionType",
1898
+ "riskLevel",
1899
+ "status",
1900
+ "title",
1901
+ "summary",
1902
+ "payload",
1903
+ "idempotencyKey",
1904
+ "approvalRequestId",
1905
+ "outcome",
1906
+ "createdAt",
1907
+ "updatedAt",
1908
+ "completedAt"
1909
+ ],
1027
1910
  properties: {
1028
1911
  id: { type: "string" },
1029
1912
  agentId: nullable({ type: "string" }),
1030
1913
  tokenId: nullable({ type: "string" }),
1031
1914
  actionType: { type: "string" },
1032
1915
  riskLevel: { type: "string", enum: ["low", "medium", "high"] },
1033
- status: { type: "string", enum: ["pending_approval", "approved", "rejected", "executed"] },
1916
+ status: {
1917
+ type: "string",
1918
+ enum: ["pending_approval", "approved", "rejected", "executed"]
1919
+ },
1034
1920
  title: { type: "string" },
1035
1921
  summary: { type: "string" },
1036
1922
  payload: { type: "object", additionalProperties: true },
@@ -1045,10 +1931,30 @@ export function buildOpenApiDocument() {
1045
1931
  const rewardRule = {
1046
1932
  type: "object",
1047
1933
  additionalProperties: false,
1048
- required: ["id", "family", "code", "title", "description", "active", "config", "createdAt", "updatedAt"],
1934
+ required: [
1935
+ "id",
1936
+ "family",
1937
+ "code",
1938
+ "title",
1939
+ "description",
1940
+ "active",
1941
+ "config",
1942
+ "createdAt",
1943
+ "updatedAt"
1944
+ ],
1049
1945
  properties: {
1050
1946
  id: { type: "string" },
1051
- family: { type: "string", enum: ["completion", "consistency", "alignment", "recovery", "collaboration", "ambient"] },
1947
+ family: {
1948
+ type: "string",
1949
+ enum: [
1950
+ "completion",
1951
+ "consistency",
1952
+ "alignment",
1953
+ "recovery",
1954
+ "collaboration",
1955
+ "ambient"
1956
+ ]
1957
+ },
1052
1958
  code: { type: "string" },
1053
1959
  title: { type: "string" },
1054
1960
  description: { type: "string" },
@@ -1061,7 +1967,22 @@ export function buildOpenApiDocument() {
1061
1967
  const rewardLedgerEvent = {
1062
1968
  type: "object",
1063
1969
  additionalProperties: false,
1064
- required: ["id", "ruleId", "eventLogId", "entityType", "entityId", "actor", "source", "deltaXp", "reasonTitle", "reasonSummary", "reversibleGroup", "reversedByRewardId", "metadata", "createdAt"],
1970
+ required: [
1971
+ "id",
1972
+ "ruleId",
1973
+ "eventLogId",
1974
+ "entityType",
1975
+ "entityId",
1976
+ "actor",
1977
+ "source",
1978
+ "deltaXp",
1979
+ "reasonTitle",
1980
+ "reasonSummary",
1981
+ "reversibleGroup",
1982
+ "reversedByRewardId",
1983
+ "metadata",
1984
+ "createdAt"
1985
+ ],
1065
1986
  properties: {
1066
1987
  id: { type: "string" },
1067
1988
  ruleId: nullable({ type: "string" }),
@@ -1082,7 +2003,17 @@ export function buildOpenApiDocument() {
1082
2003
  const eventLogEntry = {
1083
2004
  type: "object",
1084
2005
  additionalProperties: false,
1085
- required: ["id", "eventKind", "entityType", "entityId", "actor", "source", "causedByEventId", "metadata", "createdAt"],
2006
+ required: [
2007
+ "id",
2008
+ "eventKind",
2009
+ "entityType",
2010
+ "entityId",
2011
+ "actor",
2012
+ "source",
2013
+ "causedByEventId",
2014
+ "metadata",
2015
+ "createdAt"
2016
+ ],
1086
2017
  properties: {
1087
2018
  id: { type: "string" },
1088
2019
  eventKind: { type: "string" },
@@ -1098,7 +2029,14 @@ export function buildOpenApiDocument() {
1098
2029
  const xpMomentumPulse = {
1099
2030
  type: "object",
1100
2031
  additionalProperties: false,
1101
- required: ["status", "headline", "detail", "celebrationLabel", "nextMilestoneId", "nextMilestoneLabel"],
2032
+ required: [
2033
+ "status",
2034
+ "headline",
2035
+ "detail",
2036
+ "celebrationLabel",
2037
+ "nextMilestoneId",
2038
+ "nextMilestoneLabel"
2039
+ ],
1102
2040
  properties: {
1103
2041
  status: { type: "string", enum: ["surging", "steady", "recovering"] },
1104
2042
  headline: { type: "string" },
@@ -1111,11 +2049,22 @@ export function buildOpenApiDocument() {
1111
2049
  const xpMetricsPayload = {
1112
2050
  type: "object",
1113
2051
  additionalProperties: false,
1114
- required: ["profile", "achievements", "milestoneRewards", "momentumPulse", "recentLedger", "rules", "dailyAmbientXp", "dailyAmbientCap"],
2052
+ required: [
2053
+ "profile",
2054
+ "achievements",
2055
+ "milestoneRewards",
2056
+ "momentumPulse",
2057
+ "recentLedger",
2058
+ "rules",
2059
+ "dailyAmbientXp",
2060
+ "dailyAmbientCap"
2061
+ ],
1115
2062
  properties: {
1116
2063
  profile: { $ref: "#/components/schemas/GamificationProfile" },
1117
2064
  achievements: arrayOf({ $ref: "#/components/schemas/AchievementSignal" }),
1118
- milestoneRewards: arrayOf({ $ref: "#/components/schemas/MilestoneReward" }),
2065
+ milestoneRewards: arrayOf({
2066
+ $ref: "#/components/schemas/MilestoneReward"
2067
+ }),
1119
2068
  momentumPulse: { $ref: "#/components/schemas/XpMomentumPulse" },
1120
2069
  recentLedger: arrayOf({ $ref: "#/components/schemas/RewardLedgerEvent" }),
1121
2070
  rules: arrayOf({ $ref: "#/components/schemas/RewardRule" }),
@@ -1184,7 +2133,14 @@ export function buildOpenApiDocument() {
1184
2133
  capabilities: {
1185
2134
  type: "object",
1186
2135
  additionalProperties: false,
1187
- required: ["tokenPresent", "scopes", "canReadPsyche", "canWritePsyche", "canManageModes", "canManageRewards"],
2136
+ required: [
2137
+ "tokenPresent",
2138
+ "scopes",
2139
+ "canReadPsyche",
2140
+ "canWritePsyche",
2141
+ "canManageModes",
2142
+ "canManageRewards"
2143
+ ],
1188
2144
  properties: {
1189
2145
  tokenPresent: { type: "boolean" },
1190
2146
  scopes: arrayOf({ type: "string" }),
@@ -1219,7 +2175,16 @@ export function buildOpenApiDocument() {
1219
2175
  const settingsPayload = {
1220
2176
  type: "object",
1221
2177
  additionalProperties: false,
1222
- required: ["profile", "notifications", "execution", "themePreference", "localePreference", "security", "agents", "agentTokens"],
2178
+ required: [
2179
+ "profile",
2180
+ "notifications",
2181
+ "execution",
2182
+ "themePreference",
2183
+ "localePreference",
2184
+ "security",
2185
+ "agents",
2186
+ "agentTokens"
2187
+ ],
1223
2188
  properties: {
1224
2189
  profile: {
1225
2190
  type: "object",
@@ -1234,7 +2199,11 @@ export function buildOpenApiDocument() {
1234
2199
  notifications: {
1235
2200
  type: "object",
1236
2201
  additionalProperties: false,
1237
- required: ["goalDriftAlerts", "dailyQuestReminders", "achievementCelebrations"],
2202
+ required: [
2203
+ "goalDriftAlerts",
2204
+ "dailyQuestReminders",
2205
+ "achievementCelebrations"
2206
+ ],
1238
2207
  properties: {
1239
2208
  goalDriftAlerts: { type: "boolean" },
1240
2209
  dailyQuestReminders: { type: "boolean" },
@@ -1242,12 +2211,21 @@ export function buildOpenApiDocument() {
1242
2211
  }
1243
2212
  },
1244
2213
  execution: { $ref: "#/components/schemas/ExecutionSettings" },
1245
- themePreference: { type: "string", enum: ["obsidian", "solar", "system"] },
2214
+ themePreference: {
2215
+ type: "string",
2216
+ enum: ["obsidian", "solar", "system"]
2217
+ },
1246
2218
  localePreference: { type: "string", enum: ["en", "fr"] },
1247
2219
  security: {
1248
2220
  type: "object",
1249
2221
  additionalProperties: false,
1250
- required: ["integrityScore", "lastAuditAt", "storageMode", "activeSessions", "tokenCount"],
2222
+ required: [
2223
+ "integrityScore",
2224
+ "lastAuditAt",
2225
+ "storageMode",
2226
+ "activeSessions",
2227
+ "tokenCount"
2228
+ ],
1251
2229
  properties: {
1252
2230
  integrityScore: { type: "integer" },
1253
2231
  lastAuditAt: { type: "string", format: "date-time" },
@@ -1302,13 +2280,25 @@ export function buildOpenApiDocument() {
1302
2280
  settingsUrl: { type: "string" },
1303
2281
  tokenCreateUrl: { type: "string" },
1304
2282
  pluginBasePath: { type: "string" },
1305
- defaultConnectionMode: { type: "string", enum: ["operator_session", "managed_token"] },
2283
+ defaultConnectionMode: {
2284
+ type: "string",
2285
+ enum: ["operator_session", "managed_token"]
2286
+ },
1306
2287
  defaultActorLabel: { type: "string" },
1307
2288
  defaultTimeoutMs: { type: "integer" },
1308
2289
  recommendedScopes: arrayOf({ type: "string" }),
1309
- recommendedTrustLevel: { type: "string", enum: ["standard", "trusted", "autonomous"] },
1310
- recommendedAutonomyMode: { type: "string", enum: ["approval_required", "scoped_write", "autonomous"] },
1311
- recommendedApprovalMode: { type: "string", enum: ["approval_by_default", "high_impact_only", "none"] },
2290
+ recommendedTrustLevel: {
2291
+ type: "string",
2292
+ enum: ["standard", "trusted", "autonomous"]
2293
+ },
2294
+ recommendedAutonomyMode: {
2295
+ type: "string",
2296
+ enum: ["approval_required", "scoped_write", "autonomous"]
2297
+ },
2298
+ recommendedApprovalMode: {
2299
+ type: "string",
2300
+ enum: ["approval_by_default", "high_impact_only", "none"]
2301
+ },
1312
2302
  authModes: {
1313
2303
  type: "object",
1314
2304
  additionalProperties: false,
@@ -1340,7 +2330,12 @@ export function buildOpenApiDocument() {
1340
2330
  tokenRecovery: {
1341
2331
  type: "object",
1342
2332
  additionalProperties: false,
1343
- required: ["rawTokenStoredByForge", "recoveryAction", "rotationSummary", "settingsSummary"],
2333
+ required: [
2334
+ "rawTokenStoredByForge",
2335
+ "recoveryAction",
2336
+ "rotationSummary",
2337
+ "settingsSummary"
2338
+ ],
1344
2339
  properties: {
1345
2340
  rawTokenStoredByForge: { type: "boolean" },
1346
2341
  recoveryAction: { type: "string" },
@@ -1361,7 +2356,18 @@ export function buildOpenApiDocument() {
1361
2356
  conceptModel: {
1362
2357
  type: "object",
1363
2358
  additionalProperties: false,
1364
- required: ["goal", "project", "task", "taskRun", "note", "insight", "psyche"],
2359
+ required: [
2360
+ "goal",
2361
+ "project",
2362
+ "task",
2363
+ "taskRun",
2364
+ "note",
2365
+ "insight",
2366
+ "calendar",
2367
+ "workBlock",
2368
+ "taskTimebox",
2369
+ "psyche"
2370
+ ],
1365
2371
  properties: {
1366
2372
  goal: { type: "string" },
1367
2373
  project: { type: "string" },
@@ -1369,6 +2375,9 @@ export function buildOpenApiDocument() {
1369
2375
  taskRun: { type: "string" },
1370
2376
  note: { type: "string" },
1371
2377
  insight: { type: "string" },
2378
+ calendar: { type: "string" },
2379
+ workBlock: { type: "string" },
2380
+ taskTimebox: { type: "string" },
1372
2381
  psyche: { type: "string" }
1373
2382
  }
1374
2383
  },
@@ -1428,7 +2437,14 @@ export function buildOpenApiDocument() {
1428
2437
  entityCatalog: arrayOf({
1429
2438
  type: "object",
1430
2439
  additionalProperties: false,
1431
- required: ["entityType", "purpose", "minimumCreateFields", "relationshipRules", "searchHints", "fieldGuide"],
2440
+ required: [
2441
+ "entityType",
2442
+ "purpose",
2443
+ "minimumCreateFields",
2444
+ "relationshipRules",
2445
+ "searchHints",
2446
+ "fieldGuide"
2447
+ ],
1432
2448
  properties: {
1433
2449
  entityType: { type: "string" },
1434
2450
  purpose: { type: "string" },
@@ -1445,7 +2461,14 @@ export function buildOpenApiDocument() {
1445
2461
  required: { type: "boolean" },
1446
2462
  description: { type: "string" },
1447
2463
  enumValues: arrayOf({ type: "string" }),
1448
- defaultValue: { oneOf: [{ type: "string" }, { type: "number" }, { type: "boolean" }, { type: "null" }] },
2464
+ defaultValue: {
2465
+ oneOf: [
2466
+ { type: "string" },
2467
+ { type: "number" },
2468
+ { type: "boolean" },
2469
+ { type: "null" }
2470
+ ]
2471
+ },
1449
2472
  nullable: { type: "boolean" }
1450
2473
  }
1451
2474
  })
@@ -1454,7 +2477,15 @@ export function buildOpenApiDocument() {
1454
2477
  toolInputCatalog: arrayOf({
1455
2478
  type: "object",
1456
2479
  additionalProperties: false,
1457
- required: ["toolName", "summary", "whenToUse", "inputShape", "requiredFields", "notes", "example"],
2480
+ required: [
2481
+ "toolName",
2482
+ "summary",
2483
+ "whenToUse",
2484
+ "inputShape",
2485
+ "requiredFields",
2486
+ "notes",
2487
+ "example"
2488
+ ],
1458
2489
  properties: {
1459
2490
  toolName: { type: "string" },
1460
2491
  summary: { type: "string" },
@@ -1468,11 +2499,22 @@ export function buildOpenApiDocument() {
1468
2499
  verificationPaths: {
1469
2500
  type: "object",
1470
2501
  additionalProperties: false,
1471
- required: ["context", "xpMetrics", "weeklyReview", "settingsBin", "batchSearch", "psycheSchemaCatalog", "psycheEventTypes", "psycheEmotions"],
2502
+ required: [
2503
+ "context",
2504
+ "xpMetrics",
2505
+ "weeklyReview",
2506
+ "calendarOverview",
2507
+ "settingsBin",
2508
+ "batchSearch",
2509
+ "psycheSchemaCatalog",
2510
+ "psycheEventTypes",
2511
+ "psycheEmotions"
2512
+ ],
1472
2513
  properties: {
1473
2514
  context: { type: "string" },
1474
2515
  xpMetrics: { type: "string" },
1475
2516
  weeklyReview: { type: "string" },
2517
+ calendarOverview: { type: "string" },
1476
2518
  settingsBin: { type: "string" },
1477
2519
  batchSearch: { type: "string" },
1478
2520
  psycheSchemaCatalog: { type: "string" },
@@ -1483,13 +2525,22 @@ export function buildOpenApiDocument() {
1483
2525
  recommendedPluginTools: {
1484
2526
  type: "object",
1485
2527
  additionalProperties: false,
1486
- required: ["bootstrap", "readModels", "uiWorkflow", "entityWorkflow", "workWorkflow", "insightWorkflow"],
2528
+ required: [
2529
+ "bootstrap",
2530
+ "readModels",
2531
+ "uiWorkflow",
2532
+ "entityWorkflow",
2533
+ "workWorkflow",
2534
+ "calendarWorkflow",
2535
+ "insightWorkflow"
2536
+ ],
1487
2537
  properties: {
1488
2538
  bootstrap: arrayOf({ type: "string" }),
1489
2539
  readModels: arrayOf({ type: "string" }),
1490
2540
  uiWorkflow: arrayOf({ type: "string" }),
1491
2541
  entityWorkflow: arrayOf({ type: "string" }),
1492
2542
  workWorkflow: arrayOf({ type: "string" }),
2543
+ calendarWorkflow: arrayOf({ type: "string" }),
1493
2544
  insightWorkflow: arrayOf({ type: "string" })
1494
2545
  }
1495
2546
  },
@@ -1583,7 +2634,10 @@ export function buildOpenApiDocument() {
1583
2634
  properties: {
1584
2635
  generatedAt: { type: "string", format: "date-time" },
1585
2636
  totalCount: { type: "integer" },
1586
- countsByEntityType: { type: "object", additionalProperties: { type: "integer" } },
2637
+ countsByEntityType: {
2638
+ type: "object",
2639
+ additionalProperties: { type: "integer" }
2640
+ },
1587
2641
  records: arrayOf({ $ref: "#/components/schemas/DeletedEntityRecord" })
1588
2642
  }
1589
2643
  };
@@ -1621,7 +2675,16 @@ export function buildOpenApiDocument() {
1621
2675
  const domain = {
1622
2676
  type: "object",
1623
2677
  additionalProperties: false,
1624
- required: ["id", "slug", "title", "description", "themeColor", "sensitive", "createdAt", "updatedAt"],
2678
+ required: [
2679
+ "id",
2680
+ "slug",
2681
+ "title",
2682
+ "description",
2683
+ "themeColor",
2684
+ "sensitive",
2685
+ "createdAt",
2686
+ "updatedAt"
2687
+ ],
1625
2688
  properties: {
1626
2689
  id: { type: "string" },
1627
2690
  slug: { type: "string" },
@@ -1704,7 +2767,16 @@ export function buildOpenApiDocument() {
1704
2767
  const schemaCatalogEntry = {
1705
2768
  type: "object",
1706
2769
  additionalProperties: false,
1707
- required: ["id", "slug", "title", "family", "schemaType", "description", "createdAt", "updatedAt"],
2770
+ required: [
2771
+ "id",
2772
+ "slug",
2773
+ "title",
2774
+ "family",
2775
+ "schemaType",
2776
+ "description",
2777
+ "createdAt",
2778
+ "updatedAt"
2779
+ ],
1708
2780
  properties: {
1709
2781
  id: { type: "string" },
1710
2782
  slug: { type: "string" },
@@ -1719,7 +2791,15 @@ export function buildOpenApiDocument() {
1719
2791
  const eventType = {
1720
2792
  type: "object",
1721
2793
  additionalProperties: false,
1722
- required: ["id", "domainId", "label", "description", "system", "createdAt", "updatedAt"],
2794
+ required: [
2795
+ "id",
2796
+ "domainId",
2797
+ "label",
2798
+ "description",
2799
+ "system",
2800
+ "createdAt",
2801
+ "updatedAt"
2802
+ ],
1723
2803
  properties: {
1724
2804
  id: { type: "string" },
1725
2805
  domainId: { type: "string" },
@@ -1733,7 +2813,16 @@ export function buildOpenApiDocument() {
1733
2813
  const emotionDefinition = {
1734
2814
  type: "object",
1735
2815
  additionalProperties: false,
1736
- required: ["id", "domainId", "label", "description", "category", "system", "createdAt", "updatedAt"],
2816
+ required: [
2817
+ "id",
2818
+ "domainId",
2819
+ "label",
2820
+ "description",
2821
+ "category",
2822
+ "system",
2823
+ "createdAt",
2824
+ "updatedAt"
2825
+ ],
1737
2826
  properties: {
1738
2827
  id: { type: "string" },
1739
2828
  domainId: { type: "string" },
@@ -1854,7 +2943,16 @@ export function buildOpenApiDocument() {
1854
2943
  properties: {
1855
2944
  id: { type: "string" },
1856
2945
  domainId: { type: "string" },
1857
- family: { type: "string", enum: ["coping", "child", "critic_parent", "healthy_adult", "happy_child"] },
2946
+ family: {
2947
+ type: "string",
2948
+ enum: [
2949
+ "coping",
2950
+ "child",
2951
+ "critic_parent",
2952
+ "healthy_adult",
2953
+ "happy_child"
2954
+ ]
2955
+ },
1858
2956
  archetype: { type: "string" },
1859
2957
  title: { type: "string" },
1860
2958
  persona: { type: "string" },
@@ -1894,7 +2992,16 @@ export function buildOpenApiDocument() {
1894
2992
  additionalProperties: false,
1895
2993
  required: ["family", "archetype", "label", "confidence", "reasoning"],
1896
2994
  properties: {
1897
- family: { type: "string", enum: ["coping", "child", "critic_parent", "healthy_adult", "happy_child"] },
2995
+ family: {
2996
+ type: "string",
2997
+ enum: [
2998
+ "coping",
2999
+ "child",
3000
+ "critic_parent",
3001
+ "healthy_adult",
3002
+ "happy_child"
3003
+ ]
3004
+ },
1898
3005
  archetype: { type: "string" },
1899
3006
  label: { type: "string" },
1900
3007
  confidence: { type: "number" },
@@ -1983,7 +3090,12 @@ export function buildOpenApiDocument() {
1983
3090
  consequences: {
1984
3091
  type: "object",
1985
3092
  additionalProperties: false,
1986
- required: ["selfShortTerm", "selfLongTerm", "othersShortTerm", "othersLongTerm"],
3093
+ required: [
3094
+ "selfShortTerm",
3095
+ "selfLongTerm",
3096
+ "othersShortTerm",
3097
+ "othersLongTerm"
3098
+ ],
1987
3099
  properties: {
1988
3100
  selfShortTerm: arrayOf({ type: "string" }),
1989
3101
  selfLongTerm: arrayOf({ type: "string" }),
@@ -2080,6 +3192,16 @@ export function buildOpenApiDocument() {
2080
3192
  Goal: goal,
2081
3193
  DashboardGoal: dashboardGoal,
2082
3194
  Project: project,
3195
+ CalendarSchedulingRules: calendarSchedulingRules,
3196
+ CalendarConnection: calendarConnection,
3197
+ CalendarResource: calendarResource,
3198
+ CalendarEventSource: calendarEventSource,
3199
+ CalendarEventLink: calendarEventLink,
3200
+ CalendarEvent: calendarEvent,
3201
+ WorkBlockTemplate: workBlockTemplate,
3202
+ WorkBlockInstance: workBlockInstance,
3203
+ TaskTimebox: taskTimebox,
3204
+ CalendarOverviewPayload: calendarOverviewPayload,
2083
3205
  TaskTimeSummary: taskTimeSummary,
2084
3206
  ProjectSummary: projectSummary,
2085
3207
  Task: task,
@@ -2106,6 +3228,10 @@ export function buildOpenApiDocument() {
2106
3228
  TaskRunHeartbeatInput: taskRunHeartbeatInput,
2107
3229
  TaskRunFinishInput: taskRunFinishInput,
2108
3230
  TaskRunFocusInput: taskRunFocusInput,
3231
+ WorkAdjustment: workAdjustment,
3232
+ WorkAdjustmentTargetSummary: workAdjustmentTargetSummary,
3233
+ WorkAdjustmentInput: workAdjustmentInput,
3234
+ WorkAdjustmentResult: workAdjustmentResult,
2109
3235
  SettingsUpdateInput: settingsUpdateInput,
2110
3236
  AgentOnboardingPayload: agentOnboardingPayload,
2111
3237
  DeletedEntityRecord: deletedEntityRecord,
@@ -2159,13 +3285,27 @@ export function buildOpenApiDocument() {
2159
3285
  now: { type: "string", format: "date-time" },
2160
3286
  watchdog: {
2161
3287
  type: "object",
2162
- required: ["enabled", "healthy", "state", "reason", "status"],
3288
+ required: [
3289
+ "enabled",
3290
+ "healthy",
3291
+ "state",
3292
+ "reason",
3293
+ "status"
3294
+ ],
2163
3295
  properties: {
2164
3296
  enabled: { type: "boolean" },
2165
3297
  healthy: { type: "boolean" },
2166
- state: { type: "string", enum: ["disabled", "idle", "healthy", "degraded"] },
3298
+ state: {
3299
+ type: "string",
3300
+ enum: ["disabled", "idle", "healthy", "degraded"]
3301
+ },
2167
3302
  reason: { anyOf: [{ type: "string" }, { type: "null" }] },
2168
- status: { anyOf: [{ type: "object", additionalProperties: true }, { type: "null" }] }
3303
+ status: {
3304
+ anyOf: [
3305
+ { type: "object", additionalProperties: true },
3306
+ { type: "null" }
3307
+ ]
3308
+ }
2169
3309
  }
2170
3310
  }
2171
3311
  }
@@ -2190,7 +3330,9 @@ export function buildOpenApiDocument() {
2190
3330
  type: "object",
2191
3331
  required: ["context"],
2192
3332
  properties: {
2193
- context: { $ref: "#/components/schemas/OperatorContextPayload" }
3333
+ context: {
3334
+ $ref: "#/components/schemas/OperatorContextPayload"
3335
+ }
2194
3336
  }
2195
3337
  }, "Operator context")
2196
3338
  }
@@ -2204,7 +3346,9 @@ export function buildOpenApiDocument() {
2204
3346
  type: "object",
2205
3347
  required: ["overview"],
2206
3348
  properties: {
2207
- overview: { $ref: "#/components/schemas/OperatorOverviewPayload" }
3349
+ overview: {
3350
+ $ref: "#/components/schemas/OperatorOverviewPayload"
3351
+ }
2208
3352
  }
2209
3353
  }, "Operator overview")
2210
3354
  }
@@ -2233,7 +3377,9 @@ export function buildOpenApiDocument() {
2233
3377
  type: "object",
2234
3378
  required: ["overview"],
2235
3379
  properties: {
2236
- overview: { $ref: "#/components/schemas/PsycheOverviewPayload" }
3380
+ overview: {
3381
+ $ref: "#/components/schemas/PsycheOverviewPayload"
3382
+ }
2237
3383
  }
2238
3384
  }, "Psyche overview"),
2239
3385
  default: { $ref: "#/components/responses/Error" }
@@ -2244,14 +3390,26 @@ export function buildOpenApiDocument() {
2244
3390
  get: {
2245
3391
  summary: "List ACT-style values",
2246
3392
  responses: {
2247
- "200": jsonResponse({ type: "object", required: ["values"], properties: { values: arrayOf({ $ref: "#/components/schemas/PsycheValue" }) } }, "Psyche value collection"),
3393
+ "200": jsonResponse({
3394
+ type: "object",
3395
+ required: ["values"],
3396
+ properties: {
3397
+ values: arrayOf({ $ref: "#/components/schemas/PsycheValue" })
3398
+ }
3399
+ }, "Psyche value collection"),
2248
3400
  default: { $ref: "#/components/responses/Error" }
2249
3401
  }
2250
3402
  },
2251
3403
  post: {
2252
3404
  summary: "Create a Psyche value",
2253
3405
  responses: {
2254
- "201": jsonResponse({ type: "object", required: ["value"], properties: { value: { $ref: "#/components/schemas/PsycheValue" } } }, "Created value"),
3406
+ "201": jsonResponse({
3407
+ type: "object",
3408
+ required: ["value"],
3409
+ properties: {
3410
+ value: { $ref: "#/components/schemas/PsycheValue" }
3411
+ }
3412
+ }, "Created value"),
2255
3413
  default: { $ref: "#/components/responses/Error" }
2256
3414
  }
2257
3415
  }
@@ -2260,21 +3418,39 @@ export function buildOpenApiDocument() {
2260
3418
  get: {
2261
3419
  summary: "Get a Psyche value",
2262
3420
  responses: {
2263
- "200": jsonResponse({ type: "object", required: ["value"], properties: { value: { $ref: "#/components/schemas/PsycheValue" } } }, "Psyche value"),
3421
+ "200": jsonResponse({
3422
+ type: "object",
3423
+ required: ["value"],
3424
+ properties: {
3425
+ value: { $ref: "#/components/schemas/PsycheValue" }
3426
+ }
3427
+ }, "Psyche value"),
2264
3428
  default: { $ref: "#/components/responses/Error" }
2265
3429
  }
2266
3430
  },
2267
3431
  patch: {
2268
3432
  summary: "Update a Psyche value",
2269
3433
  responses: {
2270
- "200": jsonResponse({ type: "object", required: ["value"], properties: { value: { $ref: "#/components/schemas/PsycheValue" } } }, "Updated value"),
3434
+ "200": jsonResponse({
3435
+ type: "object",
3436
+ required: ["value"],
3437
+ properties: {
3438
+ value: { $ref: "#/components/schemas/PsycheValue" }
3439
+ }
3440
+ }, "Updated value"),
2271
3441
  default: { $ref: "#/components/responses/Error" }
2272
3442
  }
2273
3443
  },
2274
3444
  delete: {
2275
3445
  summary: "Delete a Psyche value",
2276
3446
  responses: {
2277
- "200": jsonResponse({ type: "object", required: ["value"], properties: { value: { $ref: "#/components/schemas/PsycheValue" } } }, "Deleted value"),
3447
+ "200": jsonResponse({
3448
+ type: "object",
3449
+ required: ["value"],
3450
+ properties: {
3451
+ value: { $ref: "#/components/schemas/PsycheValue" }
3452
+ }
3453
+ }, "Deleted value"),
2278
3454
  default: { $ref: "#/components/responses/Error" }
2279
3455
  }
2280
3456
  }
@@ -2283,14 +3459,28 @@ export function buildOpenApiDocument() {
2283
3459
  get: {
2284
3460
  summary: "List behavior patterns",
2285
3461
  responses: {
2286
- "200": jsonResponse({ type: "object", required: ["patterns"], properties: { patterns: arrayOf({ $ref: "#/components/schemas/BehaviorPattern" }) } }, "Behavior pattern collection"),
3462
+ "200": jsonResponse({
3463
+ type: "object",
3464
+ required: ["patterns"],
3465
+ properties: {
3466
+ patterns: arrayOf({
3467
+ $ref: "#/components/schemas/BehaviorPattern"
3468
+ })
3469
+ }
3470
+ }, "Behavior pattern collection"),
2287
3471
  default: { $ref: "#/components/responses/Error" }
2288
3472
  }
2289
3473
  },
2290
3474
  post: {
2291
3475
  summary: "Create a behavior pattern",
2292
3476
  responses: {
2293
- "201": jsonResponse({ type: "object", required: ["pattern"], properties: { pattern: { $ref: "#/components/schemas/BehaviorPattern" } } }, "Created behavior pattern"),
3477
+ "201": jsonResponse({
3478
+ type: "object",
3479
+ required: ["pattern"],
3480
+ properties: {
3481
+ pattern: { $ref: "#/components/schemas/BehaviorPattern" }
3482
+ }
3483
+ }, "Created behavior pattern"),
2294
3484
  default: { $ref: "#/components/responses/Error" }
2295
3485
  }
2296
3486
  }
@@ -2299,21 +3489,39 @@ export function buildOpenApiDocument() {
2299
3489
  get: {
2300
3490
  summary: "Get a behavior pattern",
2301
3491
  responses: {
2302
- "200": jsonResponse({ type: "object", required: ["pattern"], properties: { pattern: { $ref: "#/components/schemas/BehaviorPattern" } } }, "Behavior pattern"),
3492
+ "200": jsonResponse({
3493
+ type: "object",
3494
+ required: ["pattern"],
3495
+ properties: {
3496
+ pattern: { $ref: "#/components/schemas/BehaviorPattern" }
3497
+ }
3498
+ }, "Behavior pattern"),
2303
3499
  default: { $ref: "#/components/responses/Error" }
2304
3500
  }
2305
3501
  },
2306
3502
  patch: {
2307
3503
  summary: "Update a behavior pattern",
2308
3504
  responses: {
2309
- "200": jsonResponse({ type: "object", required: ["pattern"], properties: { pattern: { $ref: "#/components/schemas/BehaviorPattern" } } }, "Updated behavior pattern"),
3505
+ "200": jsonResponse({
3506
+ type: "object",
3507
+ required: ["pattern"],
3508
+ properties: {
3509
+ pattern: { $ref: "#/components/schemas/BehaviorPattern" }
3510
+ }
3511
+ }, "Updated behavior pattern"),
2310
3512
  default: { $ref: "#/components/responses/Error" }
2311
3513
  }
2312
3514
  },
2313
3515
  delete: {
2314
3516
  summary: "Delete a behavior pattern",
2315
3517
  responses: {
2316
- "200": jsonResponse({ type: "object", required: ["pattern"], properties: { pattern: { $ref: "#/components/schemas/BehaviorPattern" } } }, "Deleted behavior pattern"),
3518
+ "200": jsonResponse({
3519
+ type: "object",
3520
+ required: ["pattern"],
3521
+ properties: {
3522
+ pattern: { $ref: "#/components/schemas/BehaviorPattern" }
3523
+ }
3524
+ }, "Deleted behavior pattern"),
2317
3525
  default: { $ref: "#/components/responses/Error" }
2318
3526
  }
2319
3527
  }
@@ -2322,14 +3530,26 @@ export function buildOpenApiDocument() {
2322
3530
  get: {
2323
3531
  summary: "List tracked Psyche behaviors",
2324
3532
  responses: {
2325
- "200": jsonResponse({ type: "object", required: ["behaviors"], properties: { behaviors: arrayOf({ $ref: "#/components/schemas/Behavior" }) } }, "Behavior collection"),
3533
+ "200": jsonResponse({
3534
+ type: "object",
3535
+ required: ["behaviors"],
3536
+ properties: {
3537
+ behaviors: arrayOf({ $ref: "#/components/schemas/Behavior" })
3538
+ }
3539
+ }, "Behavior collection"),
2326
3540
  default: { $ref: "#/components/responses/Error" }
2327
3541
  }
2328
3542
  },
2329
3543
  post: {
2330
3544
  summary: "Create a Psyche behavior",
2331
3545
  responses: {
2332
- "201": jsonResponse({ type: "object", required: ["behavior"], properties: { behavior: { $ref: "#/components/schemas/Behavior" } } }, "Created behavior"),
3546
+ "201": jsonResponse({
3547
+ type: "object",
3548
+ required: ["behavior"],
3549
+ properties: {
3550
+ behavior: { $ref: "#/components/schemas/Behavior" }
3551
+ }
3552
+ }, "Created behavior"),
2333
3553
  default: { $ref: "#/components/responses/Error" }
2334
3554
  }
2335
3555
  }
@@ -2338,21 +3558,39 @@ export function buildOpenApiDocument() {
2338
3558
  get: {
2339
3559
  summary: "Get a Psyche behavior",
2340
3560
  responses: {
2341
- "200": jsonResponse({ type: "object", required: ["behavior"], properties: { behavior: { $ref: "#/components/schemas/Behavior" } } }, "Behavior detail"),
3561
+ "200": jsonResponse({
3562
+ type: "object",
3563
+ required: ["behavior"],
3564
+ properties: {
3565
+ behavior: { $ref: "#/components/schemas/Behavior" }
3566
+ }
3567
+ }, "Behavior detail"),
2342
3568
  default: { $ref: "#/components/responses/Error" }
2343
3569
  }
2344
3570
  },
2345
3571
  patch: {
2346
3572
  summary: "Update a Psyche behavior",
2347
3573
  responses: {
2348
- "200": jsonResponse({ type: "object", required: ["behavior"], properties: { behavior: { $ref: "#/components/schemas/Behavior" } } }, "Updated behavior"),
3574
+ "200": jsonResponse({
3575
+ type: "object",
3576
+ required: ["behavior"],
3577
+ properties: {
3578
+ behavior: { $ref: "#/components/schemas/Behavior" }
3579
+ }
3580
+ }, "Updated behavior"),
2349
3581
  default: { $ref: "#/components/responses/Error" }
2350
3582
  }
2351
3583
  },
2352
3584
  delete: {
2353
3585
  summary: "Delete a Psyche behavior",
2354
3586
  responses: {
2355
- "200": jsonResponse({ type: "object", required: ["behavior"], properties: { behavior: { $ref: "#/components/schemas/Behavior" } } }, "Deleted behavior"),
3587
+ "200": jsonResponse({
3588
+ type: "object",
3589
+ required: ["behavior"],
3590
+ properties: {
3591
+ behavior: { $ref: "#/components/schemas/Behavior" }
3592
+ }
3593
+ }, "Deleted behavior"),
2356
3594
  default: { $ref: "#/components/responses/Error" }
2357
3595
  }
2358
3596
  }
@@ -2361,7 +3599,15 @@ export function buildOpenApiDocument() {
2361
3599
  get: {
2362
3600
  summary: "List the fixed schema-therapy catalog",
2363
3601
  responses: {
2364
- "200": jsonResponse({ type: "object", required: ["schemas"], properties: { schemas: arrayOf({ $ref: "#/components/schemas/SchemaCatalogEntry" }) } }, "Schema catalog"),
3602
+ "200": jsonResponse({
3603
+ type: "object",
3604
+ required: ["schemas"],
3605
+ properties: {
3606
+ schemas: arrayOf({
3607
+ $ref: "#/components/schemas/SchemaCatalogEntry"
3608
+ })
3609
+ }
3610
+ }, "Schema catalog"),
2365
3611
  default: { $ref: "#/components/responses/Error" }
2366
3612
  }
2367
3613
  }
@@ -2370,14 +3616,26 @@ export function buildOpenApiDocument() {
2370
3616
  get: {
2371
3617
  summary: "List belief entries linked to schemas and reports",
2372
3618
  responses: {
2373
- "200": jsonResponse({ type: "object", required: ["beliefs"], properties: { beliefs: arrayOf({ $ref: "#/components/schemas/BeliefEntry" }) } }, "Belief collection"),
3619
+ "200": jsonResponse({
3620
+ type: "object",
3621
+ required: ["beliefs"],
3622
+ properties: {
3623
+ beliefs: arrayOf({ $ref: "#/components/schemas/BeliefEntry" })
3624
+ }
3625
+ }, "Belief collection"),
2374
3626
  default: { $ref: "#/components/responses/Error" }
2375
3627
  }
2376
3628
  },
2377
3629
  post: {
2378
3630
  summary: "Create a belief entry",
2379
3631
  responses: {
2380
- "201": jsonResponse({ type: "object", required: ["belief"], properties: { belief: { $ref: "#/components/schemas/BeliefEntry" } } }, "Created belief"),
3632
+ "201": jsonResponse({
3633
+ type: "object",
3634
+ required: ["belief"],
3635
+ properties: {
3636
+ belief: { $ref: "#/components/schemas/BeliefEntry" }
3637
+ }
3638
+ }, "Created belief"),
2381
3639
  default: { $ref: "#/components/responses/Error" }
2382
3640
  }
2383
3641
  }
@@ -2386,21 +3644,39 @@ export function buildOpenApiDocument() {
2386
3644
  get: {
2387
3645
  summary: "Get a belief entry",
2388
3646
  responses: {
2389
- "200": jsonResponse({ type: "object", required: ["belief"], properties: { belief: { $ref: "#/components/schemas/BeliefEntry" } } }, "Belief detail"),
3647
+ "200": jsonResponse({
3648
+ type: "object",
3649
+ required: ["belief"],
3650
+ properties: {
3651
+ belief: { $ref: "#/components/schemas/BeliefEntry" }
3652
+ }
3653
+ }, "Belief detail"),
2390
3654
  default: { $ref: "#/components/responses/Error" }
2391
3655
  }
2392
3656
  },
2393
3657
  patch: {
2394
3658
  summary: "Update a belief entry",
2395
3659
  responses: {
2396
- "200": jsonResponse({ type: "object", required: ["belief"], properties: { belief: { $ref: "#/components/schemas/BeliefEntry" } } }, "Updated belief"),
3660
+ "200": jsonResponse({
3661
+ type: "object",
3662
+ required: ["belief"],
3663
+ properties: {
3664
+ belief: { $ref: "#/components/schemas/BeliefEntry" }
3665
+ }
3666
+ }, "Updated belief"),
2397
3667
  default: { $ref: "#/components/responses/Error" }
2398
3668
  }
2399
3669
  },
2400
3670
  delete: {
2401
3671
  summary: "Delete a belief entry",
2402
3672
  responses: {
2403
- "200": jsonResponse({ type: "object", required: ["belief"], properties: { belief: { $ref: "#/components/schemas/BeliefEntry" } } }, "Deleted belief"),
3673
+ "200": jsonResponse({
3674
+ type: "object",
3675
+ required: ["belief"],
3676
+ properties: {
3677
+ belief: { $ref: "#/components/schemas/BeliefEntry" }
3678
+ }
3679
+ }, "Deleted belief"),
2404
3680
  default: { $ref: "#/components/responses/Error" }
2405
3681
  }
2406
3682
  }
@@ -2409,14 +3685,26 @@ export function buildOpenApiDocument() {
2409
3685
  get: {
2410
3686
  summary: "List Psyche mode profiles",
2411
3687
  responses: {
2412
- "200": jsonResponse({ type: "object", required: ["modes"], properties: { modes: arrayOf({ $ref: "#/components/schemas/ModeProfile" }) } }, "Mode collection"),
3688
+ "200": jsonResponse({
3689
+ type: "object",
3690
+ required: ["modes"],
3691
+ properties: {
3692
+ modes: arrayOf({ $ref: "#/components/schemas/ModeProfile" })
3693
+ }
3694
+ }, "Mode collection"),
2413
3695
  default: { $ref: "#/components/responses/Error" }
2414
3696
  }
2415
3697
  },
2416
3698
  post: {
2417
3699
  summary: "Create a Psyche mode profile",
2418
3700
  responses: {
2419
- "201": jsonResponse({ type: "object", required: ["mode"], properties: { mode: { $ref: "#/components/schemas/ModeProfile" } } }, "Created mode"),
3701
+ "201": jsonResponse({
3702
+ type: "object",
3703
+ required: ["mode"],
3704
+ properties: {
3705
+ mode: { $ref: "#/components/schemas/ModeProfile" }
3706
+ }
3707
+ }, "Created mode"),
2420
3708
  default: { $ref: "#/components/responses/Error" }
2421
3709
  }
2422
3710
  }
@@ -2425,21 +3713,39 @@ export function buildOpenApiDocument() {
2425
3713
  get: {
2426
3714
  summary: "Get a Psyche mode profile",
2427
3715
  responses: {
2428
- "200": jsonResponse({ type: "object", required: ["mode"], properties: { mode: { $ref: "#/components/schemas/ModeProfile" } } }, "Mode detail"),
3716
+ "200": jsonResponse({
3717
+ type: "object",
3718
+ required: ["mode"],
3719
+ properties: {
3720
+ mode: { $ref: "#/components/schemas/ModeProfile" }
3721
+ }
3722
+ }, "Mode detail"),
2429
3723
  default: { $ref: "#/components/responses/Error" }
2430
3724
  }
2431
3725
  },
2432
3726
  patch: {
2433
3727
  summary: "Update a Psyche mode profile",
2434
3728
  responses: {
2435
- "200": jsonResponse({ type: "object", required: ["mode"], properties: { mode: { $ref: "#/components/schemas/ModeProfile" } } }, "Updated mode"),
3729
+ "200": jsonResponse({
3730
+ type: "object",
3731
+ required: ["mode"],
3732
+ properties: {
3733
+ mode: { $ref: "#/components/schemas/ModeProfile" }
3734
+ }
3735
+ }, "Updated mode"),
2436
3736
  default: { $ref: "#/components/responses/Error" }
2437
3737
  }
2438
3738
  },
2439
3739
  delete: {
2440
3740
  summary: "Delete a Psyche mode profile",
2441
3741
  responses: {
2442
- "200": jsonResponse({ type: "object", required: ["mode"], properties: { mode: { $ref: "#/components/schemas/ModeProfile" } } }, "Deleted mode"),
3742
+ "200": jsonResponse({
3743
+ type: "object",
3744
+ required: ["mode"],
3745
+ properties: {
3746
+ mode: { $ref: "#/components/schemas/ModeProfile" }
3747
+ }
3748
+ }, "Deleted mode"),
2443
3749
  default: { $ref: "#/components/responses/Error" }
2444
3750
  }
2445
3751
  }
@@ -2448,14 +3754,28 @@ export function buildOpenApiDocument() {
2448
3754
  get: {
2449
3755
  summary: "List guided mode-identification sessions",
2450
3756
  responses: {
2451
- "200": jsonResponse({ type: "object", required: ["sessions"], properties: { sessions: arrayOf({ $ref: "#/components/schemas/ModeGuideSession" }) } }, "Mode guide sessions"),
3757
+ "200": jsonResponse({
3758
+ type: "object",
3759
+ required: ["sessions"],
3760
+ properties: {
3761
+ sessions: arrayOf({
3762
+ $ref: "#/components/schemas/ModeGuideSession"
3763
+ })
3764
+ }
3765
+ }, "Mode guide sessions"),
2452
3766
  default: { $ref: "#/components/responses/Error" }
2453
3767
  }
2454
3768
  },
2455
3769
  post: {
2456
3770
  summary: "Create a guided mode-identification session",
2457
3771
  responses: {
2458
- "201": jsonResponse({ type: "object", required: ["session"], properties: { session: { $ref: "#/components/schemas/ModeGuideSession" } } }, "Created mode guide session"),
3772
+ "201": jsonResponse({
3773
+ type: "object",
3774
+ required: ["session"],
3775
+ properties: {
3776
+ session: { $ref: "#/components/schemas/ModeGuideSession" }
3777
+ }
3778
+ }, "Created mode guide session"),
2459
3779
  default: { $ref: "#/components/responses/Error" }
2460
3780
  }
2461
3781
  }
@@ -2464,21 +3784,39 @@ export function buildOpenApiDocument() {
2464
3784
  get: {
2465
3785
  summary: "Get a guided mode-identification session",
2466
3786
  responses: {
2467
- "200": jsonResponse({ type: "object", required: ["session"], properties: { session: { $ref: "#/components/schemas/ModeGuideSession" } } }, "Mode guide detail"),
3787
+ "200": jsonResponse({
3788
+ type: "object",
3789
+ required: ["session"],
3790
+ properties: {
3791
+ session: { $ref: "#/components/schemas/ModeGuideSession" }
3792
+ }
3793
+ }, "Mode guide detail"),
2468
3794
  default: { $ref: "#/components/responses/Error" }
2469
3795
  }
2470
3796
  },
2471
3797
  patch: {
2472
3798
  summary: "Update a guided mode-identification session",
2473
3799
  responses: {
2474
- "200": jsonResponse({ type: "object", required: ["session"], properties: { session: { $ref: "#/components/schemas/ModeGuideSession" } } }, "Updated mode guide session"),
3800
+ "200": jsonResponse({
3801
+ type: "object",
3802
+ required: ["session"],
3803
+ properties: {
3804
+ session: { $ref: "#/components/schemas/ModeGuideSession" }
3805
+ }
3806
+ }, "Updated mode guide session"),
2475
3807
  default: { $ref: "#/components/responses/Error" }
2476
3808
  }
2477
3809
  },
2478
3810
  delete: {
2479
3811
  summary: "Delete a guided mode-identification session",
2480
3812
  responses: {
2481
- "200": jsonResponse({ type: "object", required: ["session"], properties: { session: { $ref: "#/components/schemas/ModeGuideSession" } } }, "Deleted mode guide session"),
3813
+ "200": jsonResponse({
3814
+ type: "object",
3815
+ required: ["session"],
3816
+ properties: {
3817
+ session: { $ref: "#/components/schemas/ModeGuideSession" }
3818
+ }
3819
+ }, "Deleted mode guide session"),
2482
3820
  default: { $ref: "#/components/responses/Error" }
2483
3821
  }
2484
3822
  }
@@ -2487,14 +3825,28 @@ export function buildOpenApiDocument() {
2487
3825
  get: {
2488
3826
  summary: "List seeded and custom Psyche event types",
2489
3827
  responses: {
2490
- "200": jsonResponse({ type: "object", required: ["eventTypes"], properties: { eventTypes: arrayOf({ $ref: "#/components/schemas/EventType" }) } }, "Event type collection"),
3828
+ "200": jsonResponse({
3829
+ type: "object",
3830
+ required: ["eventTypes"],
3831
+ properties: {
3832
+ eventTypes: arrayOf({
3833
+ $ref: "#/components/schemas/EventType"
3834
+ })
3835
+ }
3836
+ }, "Event type collection"),
2491
3837
  default: { $ref: "#/components/responses/Error" }
2492
3838
  }
2493
3839
  },
2494
3840
  post: {
2495
3841
  summary: "Create a custom Psyche event type",
2496
3842
  responses: {
2497
- "201": jsonResponse({ type: "object", required: ["eventType"], properties: { eventType: { $ref: "#/components/schemas/EventType" } } }, "Created event type"),
3843
+ "201": jsonResponse({
3844
+ type: "object",
3845
+ required: ["eventType"],
3846
+ properties: {
3847
+ eventType: { $ref: "#/components/schemas/EventType" }
3848
+ }
3849
+ }, "Created event type"),
2498
3850
  default: { $ref: "#/components/responses/Error" }
2499
3851
  }
2500
3852
  }
@@ -2503,21 +3855,39 @@ export function buildOpenApiDocument() {
2503
3855
  get: {
2504
3856
  summary: "Get a Psyche event type",
2505
3857
  responses: {
2506
- "200": jsonResponse({ type: "object", required: ["eventType"], properties: { eventType: { $ref: "#/components/schemas/EventType" } } }, "Event type detail"),
3858
+ "200": jsonResponse({
3859
+ type: "object",
3860
+ required: ["eventType"],
3861
+ properties: {
3862
+ eventType: { $ref: "#/components/schemas/EventType" }
3863
+ }
3864
+ }, "Event type detail"),
2507
3865
  default: { $ref: "#/components/responses/Error" }
2508
3866
  }
2509
3867
  },
2510
3868
  patch: {
2511
3869
  summary: "Update a custom Psyche event type",
2512
3870
  responses: {
2513
- "200": jsonResponse({ type: "object", required: ["eventType"], properties: { eventType: { $ref: "#/components/schemas/EventType" } } }, "Updated event type"),
3871
+ "200": jsonResponse({
3872
+ type: "object",
3873
+ required: ["eventType"],
3874
+ properties: {
3875
+ eventType: { $ref: "#/components/schemas/EventType" }
3876
+ }
3877
+ }, "Updated event type"),
2514
3878
  default: { $ref: "#/components/responses/Error" }
2515
3879
  }
2516
3880
  },
2517
3881
  delete: {
2518
3882
  summary: "Delete a custom Psyche event type",
2519
3883
  responses: {
2520
- "200": jsonResponse({ type: "object", required: ["eventType"], properties: { eventType: { $ref: "#/components/schemas/EventType" } } }, "Deleted event type"),
3884
+ "200": jsonResponse({
3885
+ type: "object",
3886
+ required: ["eventType"],
3887
+ properties: {
3888
+ eventType: { $ref: "#/components/schemas/EventType" }
3889
+ }
3890
+ }, "Deleted event type"),
2521
3891
  default: { $ref: "#/components/responses/Error" }
2522
3892
  }
2523
3893
  }
@@ -2526,14 +3896,28 @@ export function buildOpenApiDocument() {
2526
3896
  get: {
2527
3897
  summary: "List seeded and custom Psyche emotions",
2528
3898
  responses: {
2529
- "200": jsonResponse({ type: "object", required: ["emotions"], properties: { emotions: arrayOf({ $ref: "#/components/schemas/EmotionDefinition" }) } }, "Emotion collection"),
3899
+ "200": jsonResponse({
3900
+ type: "object",
3901
+ required: ["emotions"],
3902
+ properties: {
3903
+ emotions: arrayOf({
3904
+ $ref: "#/components/schemas/EmotionDefinition"
3905
+ })
3906
+ }
3907
+ }, "Emotion collection"),
2530
3908
  default: { $ref: "#/components/responses/Error" }
2531
3909
  }
2532
3910
  },
2533
3911
  post: {
2534
3912
  summary: "Create a custom Psyche emotion",
2535
3913
  responses: {
2536
- "201": jsonResponse({ type: "object", required: ["emotion"], properties: { emotion: { $ref: "#/components/schemas/EmotionDefinition" } } }, "Created emotion"),
3914
+ "201": jsonResponse({
3915
+ type: "object",
3916
+ required: ["emotion"],
3917
+ properties: {
3918
+ emotion: { $ref: "#/components/schemas/EmotionDefinition" }
3919
+ }
3920
+ }, "Created emotion"),
2537
3921
  default: { $ref: "#/components/responses/Error" }
2538
3922
  }
2539
3923
  }
@@ -2542,21 +3926,39 @@ export function buildOpenApiDocument() {
2542
3926
  get: {
2543
3927
  summary: "Get a Psyche emotion definition",
2544
3928
  responses: {
2545
- "200": jsonResponse({ type: "object", required: ["emotion"], properties: { emotion: { $ref: "#/components/schemas/EmotionDefinition" } } }, "Emotion detail"),
3929
+ "200": jsonResponse({
3930
+ type: "object",
3931
+ required: ["emotion"],
3932
+ properties: {
3933
+ emotion: { $ref: "#/components/schemas/EmotionDefinition" }
3934
+ }
3935
+ }, "Emotion detail"),
2546
3936
  default: { $ref: "#/components/responses/Error" }
2547
3937
  }
2548
3938
  },
2549
3939
  patch: {
2550
3940
  summary: "Update a custom Psyche emotion definition",
2551
3941
  responses: {
2552
- "200": jsonResponse({ type: "object", required: ["emotion"], properties: { emotion: { $ref: "#/components/schemas/EmotionDefinition" } } }, "Updated emotion"),
3942
+ "200": jsonResponse({
3943
+ type: "object",
3944
+ required: ["emotion"],
3945
+ properties: {
3946
+ emotion: { $ref: "#/components/schemas/EmotionDefinition" }
3947
+ }
3948
+ }, "Updated emotion"),
2553
3949
  default: { $ref: "#/components/responses/Error" }
2554
3950
  }
2555
3951
  },
2556
3952
  delete: {
2557
3953
  summary: "Delete a custom Psyche emotion definition",
2558
3954
  responses: {
2559
- "200": jsonResponse({ type: "object", required: ["emotion"], properties: { emotion: { $ref: "#/components/schemas/EmotionDefinition" } } }, "Deleted emotion"),
3955
+ "200": jsonResponse({
3956
+ type: "object",
3957
+ required: ["emotion"],
3958
+ properties: {
3959
+ emotion: { $ref: "#/components/schemas/EmotionDefinition" }
3960
+ }
3961
+ }, "Deleted emotion"),
2560
3962
  default: { $ref: "#/components/responses/Error" }
2561
3963
  }
2562
3964
  }
@@ -2565,14 +3967,28 @@ export function buildOpenApiDocument() {
2565
3967
  get: {
2566
3968
  summary: "List trigger reports",
2567
3969
  responses: {
2568
- "200": jsonResponse({ type: "object", required: ["reports"], properties: { reports: arrayOf({ $ref: "#/components/schemas/TriggerReport" }) } }, "Trigger report collection"),
3970
+ "200": jsonResponse({
3971
+ type: "object",
3972
+ required: ["reports"],
3973
+ properties: {
3974
+ reports: arrayOf({
3975
+ $ref: "#/components/schemas/TriggerReport"
3976
+ })
3977
+ }
3978
+ }, "Trigger report collection"),
2569
3979
  default: { $ref: "#/components/responses/Error" }
2570
3980
  }
2571
3981
  },
2572
3982
  post: {
2573
3983
  summary: "Create a trigger report",
2574
3984
  responses: {
2575
- "201": jsonResponse({ type: "object", required: ["report"], properties: { report: { $ref: "#/components/schemas/TriggerReport" } } }, "Created trigger report"),
3985
+ "201": jsonResponse({
3986
+ type: "object",
3987
+ required: ["report"],
3988
+ properties: {
3989
+ report: { $ref: "#/components/schemas/TriggerReport" }
3990
+ }
3991
+ }, "Created trigger report"),
2576
3992
  default: { $ref: "#/components/responses/Error" }
2577
3993
  }
2578
3994
  }
@@ -2596,14 +4012,26 @@ export function buildOpenApiDocument() {
2596
4012
  patch: {
2597
4013
  summary: "Update a trigger report",
2598
4014
  responses: {
2599
- "200": jsonResponse({ type: "object", required: ["report"], properties: { report: { $ref: "#/components/schemas/TriggerReport" } } }, "Updated trigger report"),
4015
+ "200": jsonResponse({
4016
+ type: "object",
4017
+ required: ["report"],
4018
+ properties: {
4019
+ report: { $ref: "#/components/schemas/TriggerReport" }
4020
+ }
4021
+ }, "Updated trigger report"),
2600
4022
  default: { $ref: "#/components/responses/Error" }
2601
4023
  }
2602
4024
  },
2603
4025
  delete: {
2604
4026
  summary: "Delete a trigger report",
2605
4027
  responses: {
2606
- "200": jsonResponse({ type: "object", required: ["report"], properties: { report: { $ref: "#/components/schemas/TriggerReport" } } }, "Deleted trigger report"),
4028
+ "200": jsonResponse({
4029
+ type: "object",
4030
+ required: ["report"],
4031
+ properties: {
4032
+ report: { $ref: "#/components/schemas/TriggerReport" }
4033
+ }
4034
+ }, "Deleted trigger report"),
2607
4035
  default: { $ref: "#/components/responses/Error" }
2608
4036
  }
2609
4037
  }
@@ -2611,15 +4039,69 @@ export function buildOpenApiDocument() {
2611
4039
  "/api/v1/notes": {
2612
4040
  get: {
2613
4041
  summary: "List notes linked to Forge entities",
4042
+ parameters: [
4043
+ {
4044
+ name: "linkedEntityType",
4045
+ in: "query",
4046
+ schema: { type: "string" }
4047
+ },
4048
+ { name: "linkedEntityId", in: "query", schema: { type: "string" } },
4049
+ {
4050
+ name: "anchorKey",
4051
+ in: "query",
4052
+ schema: { type: "string", nullable: true }
4053
+ },
4054
+ {
4055
+ name: "linkedTo",
4056
+ in: "query",
4057
+ schema: { type: "array", items: { type: "string" } }
4058
+ },
4059
+ {
4060
+ name: "tags",
4061
+ in: "query",
4062
+ schema: { type: "array", items: { type: "string" } }
4063
+ },
4064
+ {
4065
+ name: "textTerms",
4066
+ in: "query",
4067
+ schema: { type: "array", items: { type: "string" } }
4068
+ },
4069
+ { name: "author", in: "query", schema: { type: "string" } },
4070
+ {
4071
+ name: "updatedFrom",
4072
+ in: "query",
4073
+ schema: { type: "string", format: "date" }
4074
+ },
4075
+ {
4076
+ name: "updatedTo",
4077
+ in: "query",
4078
+ schema: { type: "string", format: "date" }
4079
+ },
4080
+ {
4081
+ name: "limit",
4082
+ in: "query",
4083
+ schema: { type: "integer", minimum: 1, maximum: 200 }
4084
+ }
4085
+ ],
2614
4086
  responses: {
2615
- "200": jsonResponse({ type: "object", required: ["notes"], properties: { notes: arrayOf({ $ref: "#/components/schemas/Note" }) } }, "Note collection"),
4087
+ "200": jsonResponse({
4088
+ type: "object",
4089
+ required: ["notes"],
4090
+ properties: {
4091
+ notes: arrayOf({ $ref: "#/components/schemas/Note" })
4092
+ }
4093
+ }, "Note collection"),
2616
4094
  default: { $ref: "#/components/responses/Error" }
2617
4095
  }
2618
4096
  },
2619
4097
  post: {
2620
4098
  summary: "Create a note linked to one or more Forge entities",
2621
4099
  responses: {
2622
- "201": jsonResponse({ type: "object", required: ["note"], properties: { note: { $ref: "#/components/schemas/Note" } } }, "Created note"),
4100
+ "201": jsonResponse({
4101
+ type: "object",
4102
+ required: ["note"],
4103
+ properties: { note: { $ref: "#/components/schemas/Note" } }
4104
+ }, "Created note"),
2623
4105
  default: { $ref: "#/components/responses/Error" }
2624
4106
  }
2625
4107
  }
@@ -2628,21 +4110,33 @@ export function buildOpenApiDocument() {
2628
4110
  get: {
2629
4111
  summary: "Get a note",
2630
4112
  responses: {
2631
- "200": jsonResponse({ type: "object", required: ["note"], properties: { note: { $ref: "#/components/schemas/Note" } } }, "Note"),
4113
+ "200": jsonResponse({
4114
+ type: "object",
4115
+ required: ["note"],
4116
+ properties: { note: { $ref: "#/components/schemas/Note" } }
4117
+ }, "Note"),
2632
4118
  default: { $ref: "#/components/responses/Error" }
2633
4119
  }
2634
4120
  },
2635
4121
  patch: {
2636
4122
  summary: "Update a note",
2637
4123
  responses: {
2638
- "200": jsonResponse({ type: "object", required: ["note"], properties: { note: { $ref: "#/components/schemas/Note" } } }, "Updated note"),
4124
+ "200": jsonResponse({
4125
+ type: "object",
4126
+ required: ["note"],
4127
+ properties: { note: { $ref: "#/components/schemas/Note" } }
4128
+ }, "Updated note"),
2639
4129
  default: { $ref: "#/components/responses/Error" }
2640
4130
  }
2641
4131
  },
2642
4132
  delete: {
2643
4133
  summary: "Delete a note",
2644
4134
  responses: {
2645
- "200": jsonResponse({ type: "object", required: ["note"], properties: { note: { $ref: "#/components/schemas/Note" } } }, "Deleted note"),
4135
+ "200": jsonResponse({
4136
+ type: "object",
4137
+ required: ["note"],
4138
+ properties: { note: { $ref: "#/components/schemas/Note" } }
4139
+ }, "Deleted note"),
2646
4140
  default: { $ref: "#/components/responses/Error" }
2647
4141
  }
2648
4142
  }
@@ -2655,7 +4149,9 @@ export function buildOpenApiDocument() {
2655
4149
  type: "object",
2656
4150
  required: ["projects"],
2657
4151
  properties: {
2658
- projects: arrayOf({ $ref: "#/components/schemas/ProjectSummary" })
4152
+ projects: arrayOf({
4153
+ $ref: "#/components/schemas/ProjectSummary"
4154
+ })
2659
4155
  }
2660
4156
  }, "Project collection"),
2661
4157
  default: { $ref: "#/components/responses/Error" }
@@ -2675,6 +4171,214 @@ export function buildOpenApiDocument() {
2675
4171
  }
2676
4172
  }
2677
4173
  },
4174
+ "/api/v1/calendar/overview": {
4175
+ get: {
4176
+ summary: "Read connected calendars, mirrored events, work blocks, and timeboxes",
4177
+ responses: {
4178
+ "200": jsonResponse({
4179
+ type: "object",
4180
+ required: ["calendar"],
4181
+ properties: {
4182
+ calendar: {
4183
+ $ref: "#/components/schemas/CalendarOverviewPayload"
4184
+ }
4185
+ }
4186
+ }, "Calendar overview"),
4187
+ default: { $ref: "#/components/responses/Error" }
4188
+ }
4189
+ }
4190
+ },
4191
+ "/api/v1/calendar/connections": {
4192
+ get: {
4193
+ summary: "List connected calendar providers",
4194
+ responses: {
4195
+ "200": jsonResponse({
4196
+ type: "object",
4197
+ required: ["providers", "connections"],
4198
+ properties: {
4199
+ providers: arrayOf({
4200
+ type: "object",
4201
+ additionalProperties: false,
4202
+ required: [
4203
+ "provider",
4204
+ "label",
4205
+ "supportsDedicatedForgeCalendar",
4206
+ "connectionHelp"
4207
+ ],
4208
+ properties: {
4209
+ provider: {
4210
+ type: "string",
4211
+ enum: ["google", "apple", "caldav"]
4212
+ },
4213
+ label: { type: "string" },
4214
+ supportsDedicatedForgeCalendar: { type: "boolean" },
4215
+ connectionHelp: { type: "string" }
4216
+ }
4217
+ }),
4218
+ connections: arrayOf({
4219
+ $ref: "#/components/schemas/CalendarConnection"
4220
+ })
4221
+ }
4222
+ }, "Calendar connections"),
4223
+ default: { $ref: "#/components/responses/Error" }
4224
+ }
4225
+ },
4226
+ post: {
4227
+ summary: "Create a Google, Apple, or custom CalDAV calendar connection",
4228
+ description: "Forge first discovers the writable calendars for the account, then stores the chosen mirrored calendars and dedicated Forge write calendar.",
4229
+ responses: {
4230
+ "201": jsonResponse({
4231
+ type: "object",
4232
+ required: ["connection"],
4233
+ properties: {
4234
+ connection: {
4235
+ $ref: "#/components/schemas/CalendarConnection"
4236
+ }
4237
+ }
4238
+ }, "Created calendar connection"),
4239
+ default: { $ref: "#/components/responses/Error" }
4240
+ }
4241
+ }
4242
+ },
4243
+ "/api/v1/calendar/connections/{id}/sync": {
4244
+ post: {
4245
+ summary: "Sync one connected calendar provider",
4246
+ responses: {
4247
+ "200": jsonResponse({
4248
+ type: "object",
4249
+ required: ["connection"],
4250
+ properties: {
4251
+ connection: {
4252
+ $ref: "#/components/schemas/CalendarConnection"
4253
+ }
4254
+ }
4255
+ }, "Synced calendar connection"),
4256
+ default: { $ref: "#/components/responses/Error" }
4257
+ }
4258
+ }
4259
+ },
4260
+ "/api/v1/calendar/work-block-templates": {
4261
+ get: {
4262
+ summary: "List recurring work-block templates",
4263
+ responses: {
4264
+ "200": jsonResponse({
4265
+ type: "object",
4266
+ required: ["templates"],
4267
+ properties: {
4268
+ templates: arrayOf({
4269
+ $ref: "#/components/schemas/WorkBlockTemplate"
4270
+ })
4271
+ }
4272
+ }, "Work-block templates"),
4273
+ default: { $ref: "#/components/responses/Error" }
4274
+ }
4275
+ },
4276
+ post: {
4277
+ summary: "Create a recurring work-block template",
4278
+ responses: {
4279
+ "201": jsonResponse({
4280
+ type: "object",
4281
+ required: ["template"],
4282
+ properties: {
4283
+ template: { $ref: "#/components/schemas/WorkBlockTemplate" }
4284
+ }
4285
+ }, "Created work-block template"),
4286
+ default: { $ref: "#/components/responses/Error" }
4287
+ }
4288
+ }
4289
+ },
4290
+ "/api/v1/calendar/timeboxes": {
4291
+ get: {
4292
+ summary: "List task timeboxes",
4293
+ responses: {
4294
+ "200": jsonResponse({
4295
+ type: "object",
4296
+ required: ["timeboxes"],
4297
+ properties: {
4298
+ timeboxes: arrayOf({
4299
+ $ref: "#/components/schemas/TaskTimebox"
4300
+ })
4301
+ }
4302
+ }, "Task timeboxes"),
4303
+ default: { $ref: "#/components/responses/Error" }
4304
+ }
4305
+ },
4306
+ post: {
4307
+ summary: "Create a planned task timebox",
4308
+ responses: {
4309
+ "201": jsonResponse({
4310
+ type: "object",
4311
+ required: ["timebox"],
4312
+ properties: {
4313
+ timebox: { $ref: "#/components/schemas/TaskTimebox" }
4314
+ }
4315
+ }, "Created task timebox"),
4316
+ default: { $ref: "#/components/responses/Error" }
4317
+ }
4318
+ }
4319
+ },
4320
+ "/api/v1/calendar/timeboxes/recommend": {
4321
+ post: {
4322
+ summary: "Suggest future timeboxes for a task",
4323
+ description: "Recommendations consider provider events, work blocks, scheduling rules, and planned duration.",
4324
+ responses: {
4325
+ "200": jsonResponse({
4326
+ type: "object",
4327
+ required: ["timeboxes"],
4328
+ properties: {
4329
+ timeboxes: arrayOf({
4330
+ $ref: "#/components/schemas/TaskTimebox"
4331
+ })
4332
+ }
4333
+ }, "Suggested task timeboxes"),
4334
+ default: { $ref: "#/components/responses/Error" }
4335
+ }
4336
+ }
4337
+ },
4338
+ "/api/v1/calendar/events": {
4339
+ post: {
4340
+ summary: "Create a native Forge calendar event",
4341
+ description: "Forge stores the event canonically first, then projects it to a connected writable calendar when a preferred calendar is selected.",
4342
+ responses: {
4343
+ "201": jsonResponse({
4344
+ type: "object",
4345
+ required: ["event"],
4346
+ properties: {
4347
+ event: { $ref: "#/components/schemas/CalendarEvent" }
4348
+ }
4349
+ }, "Created calendar event"),
4350
+ default: { $ref: "#/components/responses/Error" }
4351
+ }
4352
+ }
4353
+ },
4354
+ "/api/v1/calendar/events/{id}": {
4355
+ patch: {
4356
+ summary: "Update a Forge calendar event and sync remote projections",
4357
+ responses: {
4358
+ "200": jsonResponse({
4359
+ type: "object",
4360
+ required: ["event"],
4361
+ properties: {
4362
+ event: { $ref: "#/components/schemas/CalendarEvent" }
4363
+ }
4364
+ }, "Updated calendar event"),
4365
+ default: { $ref: "#/components/responses/Error" }
4366
+ }
4367
+ },
4368
+ delete: {
4369
+ summary: "Delete a Forge calendar event and remove projected remote copies",
4370
+ responses: {
4371
+ "200": jsonResponse({
4372
+ type: "object",
4373
+ required: ["event"],
4374
+ properties: {
4375
+ event: { $ref: "#/components/schemas/CalendarEvent" }
4376
+ }
4377
+ }, "Deleted calendar event"),
4378
+ default: { $ref: "#/components/responses/Error" }
4379
+ }
4380
+ }
4381
+ },
2678
4382
  "/api/v1/campaigns": {
2679
4383
  get: {
2680
4384
  deprecated: true,
@@ -2684,7 +4388,9 @@ export function buildOpenApiDocument() {
2684
4388
  type: "object",
2685
4389
  required: ["projects"],
2686
4390
  properties: {
2687
- projects: arrayOf({ $ref: "#/components/schemas/ProjectSummary" })
4391
+ projects: arrayOf({
4392
+ $ref: "#/components/schemas/ProjectSummary"
4393
+ })
2688
4394
  }
2689
4395
  }, "Project collection"),
2690
4396
  default: { $ref: "#/components/responses/Error" }
@@ -2707,6 +4413,7 @@ export function buildOpenApiDocument() {
2707
4413
  },
2708
4414
  patch: {
2709
4415
  summary: "Update a project",
4416
+ description: "Project lifecycle is status-driven. Set status to paused to suspend, completed to finish, or active to restart. Updating a project to completed auto-completes linked unfinished tasks through the normal task completion flow.",
2710
4417
  responses: {
2711
4418
  "200": jsonResponse({
2712
4419
  type: "object",
@@ -2721,6 +4428,7 @@ export function buildOpenApiDocument() {
2721
4428
  },
2722
4429
  delete: {
2723
4430
  summary: "Delete a project",
4431
+ description: "Project DELETE defaults to soft delete. Pass mode=hard only when permanent removal is intended.",
2724
4432
  responses: {
2725
4433
  "200": jsonResponse({
2726
4434
  type: "object",
@@ -3016,6 +4724,23 @@ export function buildOpenApiDocument() {
3016
4724
  }
3017
4725
  }
3018
4726
  },
4727
+ "/api/v1/work-adjustments": {
4728
+ post: {
4729
+ summary: "Add or remove tracked work minutes on an existing task or project and return fresh XP state",
4730
+ requestBody: {
4731
+ required: true,
4732
+ content: {
4733
+ "application/json": {
4734
+ schema: { $ref: "#/components/schemas/WorkAdjustmentInput" }
4735
+ }
4736
+ }
4737
+ },
4738
+ responses: {
4739
+ "201": jsonResponse({ $ref: "#/components/schemas/WorkAdjustmentResult" }, "Created work adjustment and refreshed XP state"),
4740
+ "404": { $ref: "#/components/responses/Error" }
4741
+ }
4742
+ }
4743
+ },
3019
4744
  "/api/v1/tasks/{id}": {
3020
4745
  get: {
3021
4746
  summary: "Get a task",
@@ -3116,9 +4841,20 @@ export function buildOpenApiDocument() {
3116
4841
  summary: "List task timers with optional task and active-state filters",
3117
4842
  parameters: [
3118
4843
  { name: "taskId", in: "query", schema: { type: "string" } },
3119
- { name: "status", in: "query", schema: { type: "string", enum: ["active", "completed", "released", "timed_out"] } },
4844
+ {
4845
+ name: "status",
4846
+ in: "query",
4847
+ schema: {
4848
+ type: "string",
4849
+ enum: ["active", "completed", "released", "timed_out"]
4850
+ }
4851
+ },
3120
4852
  { name: "active", in: "query", schema: { type: "boolean" } },
3121
- { name: "limit", in: "query", schema: { type: "integer", minimum: 1, maximum: 100 } }
4853
+ {
4854
+ name: "limit",
4855
+ in: "query",
4856
+ schema: { type: "integer", minimum: 1, maximum: 100 }
4857
+ }
3122
4858
  ],
3123
4859
  responses: {
3124
4860
  "200": jsonResponse({
@@ -3231,7 +4967,9 @@ export function buildOpenApiDocument() {
3231
4967
  type: "object",
3232
4968
  required: ["activity"],
3233
4969
  properties: {
3234
- activity: arrayOf({ $ref: "#/components/schemas/ActivityEvent" })
4970
+ activity: arrayOf({
4971
+ $ref: "#/components/schemas/ActivityEvent"
4972
+ })
3235
4973
  }
3236
4974
  }, "Activity archive")
3237
4975
  }
@@ -3265,9 +5003,15 @@ export function buildOpenApiDocument() {
3265
5003
  additionalProperties: false,
3266
5004
  required: ["profile", "achievements", "milestoneRewards"],
3267
5005
  properties: {
3268
- profile: { $ref: "#/components/schemas/GamificationProfile" },
3269
- achievements: arrayOf({ $ref: "#/components/schemas/AchievementSignal" }),
3270
- milestoneRewards: arrayOf({ $ref: "#/components/schemas/MilestoneReward" })
5006
+ profile: {
5007
+ $ref: "#/components/schemas/GamificationProfile"
5008
+ },
5009
+ achievements: arrayOf({
5010
+ $ref: "#/components/schemas/AchievementSignal"
5011
+ }),
5012
+ milestoneRewards: arrayOf({
5013
+ $ref: "#/components/schemas/MilestoneReward"
5014
+ })
3271
5015
  }
3272
5016
  }
3273
5017
  }
@@ -3343,7 +5087,11 @@ export function buildOpenApiDocument() {
3343
5087
  delete: {
3344
5088
  summary: "Soft delete or permanently delete a stored insight",
3345
5089
  parameters: [
3346
- { name: "mode", in: "query", schema: { type: "string", enum: ["soft", "hard"] } },
5090
+ {
5091
+ name: "mode",
5092
+ in: "query",
5093
+ schema: { type: "string", enum: ["soft", "hard"] }
5094
+ },
3347
5095
  { name: "reason", in: "query", schema: { type: "string" } }
3348
5096
  ],
3349
5097
  responses: {
@@ -3380,7 +5128,9 @@ export function buildOpenApiDocument() {
3380
5128
  type: "object",
3381
5129
  required: ["approvalRequests"],
3382
5130
  properties: {
3383
- approvalRequests: arrayOf({ $ref: "#/components/schemas/ApprovalRequest" })
5131
+ approvalRequests: arrayOf({
5132
+ $ref: "#/components/schemas/ApprovalRequest"
5133
+ })
3384
5134
  }
3385
5135
  }, "Approval requests")
3386
5136
  }
@@ -3394,7 +5144,9 @@ export function buildOpenApiDocument() {
3394
5144
  type: "object",
3395
5145
  required: ["approvalRequest"],
3396
5146
  properties: {
3397
- approvalRequest: { $ref: "#/components/schemas/ApprovalRequest" }
5147
+ approvalRequest: {
5148
+ $ref: "#/components/schemas/ApprovalRequest"
5149
+ }
3398
5150
  }
3399
5151
  }, "Approved request")
3400
5152
  }
@@ -3408,7 +5160,9 @@ export function buildOpenApiDocument() {
3408
5160
  type: "object",
3409
5161
  required: ["approvalRequest"],
3410
5162
  properties: {
3411
- approvalRequest: { $ref: "#/components/schemas/ApprovalRequest" }
5163
+ approvalRequest: {
5164
+ $ref: "#/components/schemas/ApprovalRequest"
5165
+ }
3412
5166
  }
3413
5167
  }, "Rejected request")
3414
5168
  }
@@ -3422,7 +5176,9 @@ export function buildOpenApiDocument() {
3422
5176
  type: "object",
3423
5177
  required: ["agents"],
3424
5178
  properties: {
3425
- agents: arrayOf({ $ref: "#/components/schemas/AgentIdentity" })
5179
+ agents: arrayOf({
5180
+ $ref: "#/components/schemas/AgentIdentity"
5181
+ })
3426
5182
  }
3427
5183
  }, "Agent identities")
3428
5184
  }
@@ -3436,7 +5192,9 @@ export function buildOpenApiDocument() {
3436
5192
  type: "object",
3437
5193
  required: ["onboarding"],
3438
5194
  properties: {
3439
- onboarding: { $ref: "#/components/schemas/AgentOnboardingPayload" }
5195
+ onboarding: {
5196
+ $ref: "#/components/schemas/AgentOnboardingPayload"
5197
+ }
3440
5198
  }
3441
5199
  }, "Agent onboarding payload")
3442
5200
  }
@@ -3465,7 +5223,9 @@ export function buildOpenApiDocument() {
3465
5223
  required: ["action", "approvalRequest"],
3466
5224
  properties: {
3467
5225
  action: { $ref: "#/components/schemas/AgentAction" },
3468
- approvalRequest: nullable({ $ref: "#/components/schemas/ApprovalRequest" })
5226
+ approvalRequest: nullable({
5227
+ $ref: "#/components/schemas/ApprovalRequest"
5228
+ })
3469
5229
  }
3470
5230
  }, "Executed agent action"),
3471
5231
  "202": jsonResponse({
@@ -3473,7 +5233,9 @@ export function buildOpenApiDocument() {
3473
5233
  required: ["action", "approvalRequest"],
3474
5234
  properties: {
3475
5235
  action: { $ref: "#/components/schemas/AgentAction" },
3476
- approvalRequest: nullable({ $ref: "#/components/schemas/ApprovalRequest" })
5236
+ approvalRequest: nullable({
5237
+ $ref: "#/components/schemas/ApprovalRequest"
5238
+ })
3477
5239
  }
3478
5240
  }, "Pending approval agent action")
3479
5241
  }
@@ -3529,7 +5291,9 @@ export function buildOpenApiDocument() {
3529
5291
  type: "object",
3530
5292
  required: ["ledger"],
3531
5293
  properties: {
3532
- ledger: arrayOf({ $ref: "#/components/schemas/RewardLedgerEvent" })
5294
+ ledger: arrayOf({
5295
+ $ref: "#/components/schemas/RewardLedgerEvent"
5296
+ })
3533
5297
  }
3534
5298
  }, "Reward ledger")
3535
5299
  }
@@ -3558,7 +5322,9 @@ export function buildOpenApiDocument() {
3558
5322
  type: "object",
3559
5323
  required: ["events"],
3560
5324
  properties: {
3561
- events: arrayOf({ $ref: "#/components/schemas/EventLogEntry" })
5325
+ events: arrayOf({
5326
+ $ref: "#/components/schemas/EventLogEntry"
5327
+ })
3562
5328
  }
3563
5329
  }, "Event log")
3564
5330
  }
@@ -3573,7 +5339,9 @@ export function buildOpenApiDocument() {
3573
5339
  required: ["sessionEvent", "rewardEvent"],
3574
5340
  properties: {
3575
5341
  sessionEvent: { type: "object", additionalProperties: true },
3576
- rewardEvent: nullable({ $ref: "#/components/schemas/RewardLedgerEvent" })
5342
+ rewardEvent: nullable({
5343
+ $ref: "#/components/schemas/RewardLedgerEvent"
5344
+ })
3577
5345
  }
3578
5346
  }, "Recorded session event")
3579
5347
  }
@@ -3593,6 +5361,91 @@ export function buildOpenApiDocument() {
3593
5361
  }
3594
5362
  }
3595
5363
  },
5364
+ "/api/v1/reviews/weekly/finalize": {
5365
+ post: {
5366
+ summary: "Finalize the current weekly review cycle",
5367
+ responses: {
5368
+ "200": jsonResponse({
5369
+ type: "object",
5370
+ required: ["review", "closure", "reward", "metrics"],
5371
+ properties: {
5372
+ review: { $ref: "#/components/schemas/WeeklyReviewPayload" },
5373
+ closure: {
5374
+ type: "object",
5375
+ required: [
5376
+ "id",
5377
+ "weekKey",
5378
+ "weekStartDate",
5379
+ "weekEndDate",
5380
+ "windowLabel",
5381
+ "actor",
5382
+ "source",
5383
+ "rewardId",
5384
+ "activityEventId",
5385
+ "createdAt"
5386
+ ],
5387
+ properties: {
5388
+ id: { type: "string" },
5389
+ weekKey: { type: "string" },
5390
+ weekStartDate: { type: "string" },
5391
+ weekEndDate: { type: "string" },
5392
+ windowLabel: { type: "string" },
5393
+ actor: nullable({ type: "string" }),
5394
+ source: {
5395
+ type: "string",
5396
+ enum: ["ui", "openclaw", "agent", "system"]
5397
+ },
5398
+ rewardId: { type: "string" },
5399
+ activityEventId: { type: "string" },
5400
+ createdAt: { type: "string", format: "date-time" }
5401
+ }
5402
+ },
5403
+ reward: { $ref: "#/components/schemas/RewardLedgerEvent" },
5404
+ metrics: { $ref: "#/components/schemas/XpMetricsPayload" }
5405
+ }
5406
+ }, "Existing weekly review closure"),
5407
+ "201": jsonResponse({
5408
+ type: "object",
5409
+ required: ["review", "closure", "reward", "metrics"],
5410
+ properties: {
5411
+ review: { $ref: "#/components/schemas/WeeklyReviewPayload" },
5412
+ closure: {
5413
+ type: "object",
5414
+ required: [
5415
+ "id",
5416
+ "weekKey",
5417
+ "weekStartDate",
5418
+ "weekEndDate",
5419
+ "windowLabel",
5420
+ "actor",
5421
+ "source",
5422
+ "rewardId",
5423
+ "activityEventId",
5424
+ "createdAt"
5425
+ ],
5426
+ properties: {
5427
+ id: { type: "string" },
5428
+ weekKey: { type: "string" },
5429
+ weekStartDate: { type: "string" },
5430
+ weekEndDate: { type: "string" },
5431
+ windowLabel: { type: "string" },
5432
+ actor: nullable({ type: "string" }),
5433
+ source: {
5434
+ type: "string",
5435
+ enum: ["ui", "openclaw", "agent", "system"]
5436
+ },
5437
+ rewardId: { type: "string" },
5438
+ activityEventId: { type: "string" },
5439
+ createdAt: { type: "string", format: "date-time" }
5440
+ }
5441
+ },
5442
+ reward: { $ref: "#/components/schemas/RewardLedgerEvent" },
5443
+ metrics: { $ref: "#/components/schemas/XpMetricsPayload" }
5444
+ }
5445
+ }, "Created weekly review closure")
5446
+ }
5447
+ }
5448
+ },
3596
5449
  "/api/v1/settings": {
3597
5450
  get: {
3598
5451
  summary: "Get local operator settings",
@@ -3649,7 +5502,9 @@ export function buildOpenApiDocument() {
3649
5502
  type: "object",
3650
5503
  required: ["results"],
3651
5504
  properties: {
3652
- results: arrayOf({ $ref: "#/components/schemas/BatchEntityResult" })
5505
+ results: arrayOf({
5506
+ $ref: "#/components/schemas/BatchEntityResult"
5507
+ })
3653
5508
  }
3654
5509
  }, "Batch create results")
3655
5510
  }
@@ -3663,7 +5518,9 @@ export function buildOpenApiDocument() {
3663
5518
  type: "object",
3664
5519
  required: ["results"],
3665
5520
  properties: {
3666
- results: arrayOf({ $ref: "#/components/schemas/BatchEntityResult" })
5521
+ results: arrayOf({
5522
+ $ref: "#/components/schemas/BatchEntityResult"
5523
+ })
3667
5524
  }
3668
5525
  }, "Batch update results")
3669
5526
  }
@@ -3677,7 +5534,9 @@ export function buildOpenApiDocument() {
3677
5534
  type: "object",
3678
5535
  required: ["results"],
3679
5536
  properties: {
3680
- results: arrayOf({ $ref: "#/components/schemas/BatchEntityResult" })
5537
+ results: arrayOf({
5538
+ $ref: "#/components/schemas/BatchEntityResult"
5539
+ })
3681
5540
  }
3682
5541
  }, "Batch delete results")
3683
5542
  }
@@ -3691,7 +5550,9 @@ export function buildOpenApiDocument() {
3691
5550
  type: "object",
3692
5551
  required: ["results"],
3693
5552
  properties: {
3694
- results: arrayOf({ $ref: "#/components/schemas/BatchEntityResult" })
5553
+ results: arrayOf({
5554
+ $ref: "#/components/schemas/BatchEntityResult"
5555
+ })
3695
5556
  }
3696
5557
  }, "Batch restore results")
3697
5558
  }
@@ -3705,7 +5566,9 @@ export function buildOpenApiDocument() {
3705
5566
  type: "object",
3706
5567
  required: ["results"],
3707
5568
  properties: {
3708
- results: arrayOf({ $ref: "#/components/schemas/BatchEntityResult" })
5569
+ results: arrayOf({
5570
+ $ref: "#/components/schemas/BatchEntityResult"
5571
+ })
3709
5572
  }
3710
5573
  }, "Batch search results")
3711
5574
  }
@@ -3719,7 +5582,9 @@ export function buildOpenApiDocument() {
3719
5582
  type: "object",
3720
5583
  required: ["token"],
3721
5584
  properties: {
3722
- token: { $ref: "#/components/schemas/AgentTokenMutationResult" }
5585
+ token: {
5586
+ $ref: "#/components/schemas/AgentTokenMutationResult"
5587
+ }
3723
5588
  }
3724
5589
  }, "Created agent token")
3725
5590
  }