@xopcai/xopc 0.0.227 → 0.0.228

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 (200) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-BevwE16n.js → activity-store-M0nAY5XB.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BggVQrEZ.js → agent-avatar-dicebear-CjGZBs4C.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-B0NI4_NI.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-Bx_BpIt8.js → api-BywYxpaS.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-BtKP9n2r.js → app-management-settings-panel--SjycrXk.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-BoH2NAUX.js → appearance-settings-8G-TVUtg.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-2NiqD-YP.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-DnceUyxm.js → archive-plugin-7_DXaMTP.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-Bh8_9gkr.js → attachment-load-Bx44zSpz.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-ZKeAAVxD.js → automations-page-CrKAHqc0.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-workspace-Q3g9cf0h.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-Cy9er6w-.js → binary-plugins-DjDwnHAQ.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-Cc0wWvNX.js → block-editor-7aMOKoZM.js} +3 -3
  16. package/dist/gateway/static/root/assets/browser-settings-page-DTwPkmAC.js +8 -0
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-BS7rpLLl.js → browser-workflow-inputs-8NC2qDRF.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-BdBVUZXm.js → browser-workflows-page-DVLrWKz_.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-YcP4FbN7.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-D1Lqz0Tt.js → capability-presets-api-o0y9WgAI.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-AcPjHHia.js +3 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-CGuEl-l2.js → channel-recipient-api-C5ABr73b.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-Ca94Q1D-.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-38FsOnR0.js +1 -0
  25. package/dist/gateway/static/root/assets/{chat-terminal-dock-CdX_7aQh.js → chat-terminal-dock-BR-_7KC0.js} +2 -2
  26. package/dist/gateway/static/root/assets/connectors-page-SGxfLTd6.js +2 -0
  27. package/dist/gateway/static/root/assets/{cron-expression-BnSQc4Ek.js → cron-expression-D8-c-Tkw.js} +1 -1
  28. package/dist/gateway/static/root/assets/{date-picker-BbuG7zQ_.js → date-picker-kV-Jyl9J.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dependency-picker-snZeqOmG.js → dependency-picker-CwKcrfGj.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-DJQ8JoR1.js → desktop-pet-D9rnchu3.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-B9txsRtv.js → desktop-pet-settings-CTs5WGzk.js} +1 -1
  32. package/dist/gateway/static/root/assets/{directory-picker-path-field-D7WKWkNB.js → directory-picker-path-field-CCl0aaDm.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-debug-page-D_7cOCj2.js → extension-debug-page-Cau40SvC.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-Bwu47iUb.js → extension-page-BsJXdvIL.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-Dwg4dSZM.js → extension-settings-page-qWqJyF7-.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-config-api-jURUSte_.js → gateway-config-api-BI0SELXm.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-6SQXF1yR.js → gateway-config-swr-BWGjnmDl.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-settings-UklJOMLX.js → gateway-settings-6ZdOIC7F.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-DqWaxyvZ.js → gateway-startup-retry-B_zrtccP.js} +1 -1
  40. package/dist/gateway/static/root/assets/{heartbeat-settings-Djs_nduD.js → heartbeat-settings-KBwhXeFD.js} +1 -1
  41. package/dist/gateway/static/root/assets/home-page-BA2M4CLi.js +1 -0
  42. package/dist/gateway/static/root/assets/{image-generation-api-Bxmt6LEr.js → image-generation-api-YKP2me5Z.js} +1 -1
  43. package/dist/gateway/static/root/assets/index-BX0dz1JK.js +70 -0
  44. package/dist/gateway/static/root/assets/index-D_hrEKXM.css +2 -0
  45. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-ByVsCH3d.js → keyboard-shortcuts-settings-kHtpnyEm.js} +1 -1
  46. package/dist/gateway/static/root/assets/local-app-workbench-page-D2nkn09R.js +2 -0
  47. package/dist/gateway/static/root/assets/{local-apps-page-D19R-xsz.js → local-apps-page-BCXa0oUa.js} +1 -1
  48. package/dist/gateway/static/root/assets/{locale-store-Ci1Qi0Q-.js → locale-store-CXhjfe4q.js} +1 -1
  49. package/dist/gateway/static/root/assets/logs-page-D3sNst0K.js +2 -0
  50. package/dist/gateway/static/root/assets/{management-settings-G0y7zmfY.js → management-settings-tHnlfOAQ.js} +1 -1
  51. package/dist/gateway/static/root/assets/{markdown-split-B69d2HWt.js → markdown-split-BMLqHHr5.js} +1 -1
  52. package/dist/gateway/static/root/assets/{markdown-view-DD_PgVue.css → markdown-view-CLzTdVLW.css} +1 -1
  53. package/dist/gateway/static/root/assets/markdown-view-DvM5PWEH.js +201 -0
  54. package/dist/gateway/static/root/assets/{media-plugins-6TWEQgN_.js → media-plugins-DybwqTgv.js} +1 -1
  55. package/dist/gateway/static/root/assets/messages-BMdD0LWk.js +3 -0
  56. package/dist/gateway/static/root/assets/{notes-api-DLsnnZCS.js → notes-api-BFsOGYkd.js} +1 -1
  57. package/dist/gateway/static/root/assets/{notes-page-CkRJJKDm.js → notes-page-C24SfF6r.js} +1 -1
  58. package/dist/gateway/static/root/assets/notes-workbench-CTdZc3ov.js +4 -0
  59. package/dist/gateway/static/root/assets/{product-open-page-HxArIvoN.js → product-open-page-DBfCVlJq.js} +1 -1
  60. package/dist/gateway/static/root/assets/project-detail-page-COHaEpbA.js +1 -0
  61. package/dist/gateway/static/root/assets/projects-page-lMnST7D_.js +1 -0
  62. package/dist/gateway/static/root/assets/{registry-api-lEar5FOV.js → registry-api-BFZrVYfy.js} +1 -1
  63. package/dist/gateway/static/root/assets/remote-access-hub-BIRKBvO_.js +1 -0
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Bf03UNGD.js → runtime-tools-settings-panel-BPEGTip5.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schema-form-CIXMBgx5.js → schema-form-Dxlu60Td.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-CATO9G3y.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-Cco_W41x.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-DgdB26mE.js → settings-form-section-ChXh3Bwk.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-loading-skeleton-efk5W6lG.js → settings-loading-skeleton-BCAUqIe2.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-BHVf4gEP.js → settings-page-D25W9Okr.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-WK0dGNMv.js → setup-status-panel-DsN7Z4Fl.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-Cod-w2qm.js → share-preview-page-CRFnUaNb.js} +1 -1
  73. package/dist/gateway/static/root/assets/{shares-settings-CUqQ31gt.js → shares-settings-CAX0eNaP.js} +1 -1
  74. package/dist/gateway/static/root/assets/skill-reload-api-Doy1gghe.js +1 -0
  75. package/dist/gateway/static/root/assets/{skills-page-DwCcipqK.js → skills-page-Cl7jjTK7.js} +1 -1
  76. package/dist/gateway/static/root/assets/{skills-page.utils-3WSbtl3S.js → skills-page.utils-BiCl4nb5.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-C5VxqC_s.js → system-settings-panel-BuESR7ZT.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-BRiy8NL3.js +1 -0
  79. package/dist/gateway/static/root/assets/{theme-store-Dd89g_ki.js → theme-store-DOdCjyuw.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-autosave-CeV8VJh2.js → use-autosave-Dg1mgJ_l.js} +1 -1
  81. package/dist/gateway/static/root/assets/user-context-page-CqoADNKu.js +1 -0
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-EmJ-8aZu.js → voice-api-key-field-BDNexlVR.js} +1 -1
  83. package/dist/gateway/static/root/assets/{work-discovery-overlay-zsk6E3Mi.js → work-discovery-overlay-BHTfeaWL.js} +1 -1
  84. package/dist/gateway/static/root/assets/workflow-run-setup-panel-Cf_w-NZy.js +3 -0
  85. package/dist/gateway/static/root/assets/workflows-page-j0P-uECz.js +5 -0
  86. package/dist/gateway/static/root/index.html +12 -12
  87. package/dist/gateway/static/root/notification-sw.js +1 -1
  88. package/dist/package.js +1 -1
  89. package/dist/packages/gateway-contract/src/notifications.js +56 -0
  90. package/dist/packages/gateway-contract/src/turn-outcome.js +114 -0
  91. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +1 -0
  92. package/dist/src/agent/lifecycle/timeout-wrapper.js +7 -6
  93. package/dist/src/agent/mcp/mcp-transport-config.d.ts +1 -1
  94. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  95. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +2 -2
  96. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +4 -4
  97. package/dist/src/agent/tools/create-share-tool.js +14 -1
  98. package/dist/src/agent/tools/exec-command.js +3 -3
  99. package/dist/src/agent/tools/execute-code-tool.js +1 -1
  100. package/dist/src/agent/tools/executor.js +2 -2
  101. package/dist/src/agent/tools/image-generate-tool.js +12 -0
  102. package/dist/src/agent/tools/send-media.js +11 -0
  103. package/dist/src/agent/tools/xopc-use-tool.js +1 -1
  104. package/dist/src/cli/command-loaders.js +1 -0
  105. package/dist/src/cli/command-manifest.js +4 -0
  106. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  107. package/dist/src/cli/commands/history.d.ts +1 -0
  108. package/dist/src/cli/commands/history.js +50 -0
  109. package/dist/src/config/agent-profile.js +1 -1
  110. package/dist/src/gateway/agents-admin.js +1 -1
  111. package/dist/src/gateway/chat-stream/protocol.d.ts +3 -2
  112. package/dist/src/gateway/chat-stream/turn-outcome-collector.d.ts +16 -0
  113. package/dist/src/gateway/chat-stream/turn-outcome-collector.js +111 -0
  114. package/dist/src/gateway/hono/lib/static-ui.js +7 -5
  115. package/dist/src/gateway/hono/routes/index.js +2 -0
  116. package/dist/src/gateway/hono/routes/mobile.js +18 -40
  117. package/dist/src/gateway/hono/routes/notifications.d.ts +3 -0
  118. package/dist/src/gateway/hono/routes/notifications.js +45 -0
  119. package/dist/src/gateway/hono/routes/sessions.js +31 -0
  120. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  121. package/dist/src/gateway/service/agent-runner.js +6 -2
  122. package/dist/src/gateway/service/run-gateway-agent.js +53 -1
  123. package/dist/src/gateway/service/sessions-api.d.ts +6 -0
  124. package/dist/src/gateway/service/sessions-api.js +60 -3
  125. package/dist/src/gateway/service.d.ts +2 -2
  126. package/dist/src/gateway/service.js +8 -7
  127. package/dist/src/history/ctx/exporter.d.ts +14 -0
  128. package/dist/src/history/ctx/exporter.js +99 -0
  129. package/dist/src/history/ctx/format.d.ts +25 -0
  130. package/dist/src/history/ctx/format.js +282 -0
  131. package/dist/src/media/session-references.d.ts +6 -0
  132. package/dist/src/media/session-references.js +24 -3
  133. package/dist/src/notifications/device-store.d.ts +16 -0
  134. package/dist/src/notifications/device-store.js +96 -0
  135. package/dist/src/notifications/planner.d.ts +6 -0
  136. package/dist/src/notifications/planner.js +156 -0
  137. package/dist/src/notifications/service.d.ts +18 -0
  138. package/dist/src/notifications/service.js +184 -0
  139. package/dist/src/notifications/store.d.ts +53 -0
  140. package/dist/src/notifications/store.js +184 -0
  141. package/dist/src/notifications/types.d.ts +29 -0
  142. package/dist/src/notifications/types.js +14 -0
  143. package/dist/src/session/client-history.d.ts +3 -1
  144. package/dist/src/session/client-history.js +13 -0
  145. package/dist/src/session/index.d.ts +1 -1
  146. package/dist/src/session/manager.d.ts +1 -0
  147. package/dist/src/session/manager.js +6 -0
  148. package/dist/src/session/store.d.ts +15 -0
  149. package/dist/src/session/store.js +58 -0
  150. package/dist/src/storage/sqlite/index.d.ts +1 -1
  151. package/dist/src/storage/sqlite/index.js +2 -2
  152. package/dist/src/storage/sqlite/migrations/136_product_notifications.sql +79 -0
  153. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  154. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  155. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  156. package/dist/src/storage/sqlite/schema.js +1 -1
  157. package/dist/src/storage/sqlite/session-input-repository.d.ts +5 -0
  158. package/dist/src/storage/sqlite/session-input-repository.js +9 -1
  159. package/dist/src/tasks/index.js +2 -2
  160. package/dist/src/tasks/task-application-service.js +42 -6
  161. package/dist/src/tasks/task-change-events.d.ts +9 -0
  162. package/dist/src/tasks/task-change-events.js +17 -1
  163. package/dist/src/tasks/task-outbox-dispatcher.js +5 -1
  164. package/dist/src/tasks/task-run-dispatcher.js +4 -2
  165. package/dist/src/tasks/task-run-repository.js +13 -0
  166. package/package.json +2 -2
  167. package/dist/gateway/static/root/assets/agents-TJpjRHnr.js +0 -68
  168. package/dist/gateway/static/root/assets/apps-page-CZ4Da51l.js +0 -1
  169. package/dist/gateway/static/root/assets/automations-workspace-2Y00PvJU.js +0 -6
  170. package/dist/gateway/static/root/assets/browser-settings-page-CbJD27_j.js +0 -8
  171. package/dist/gateway/static/root/assets/capabilities-settings-panel-Dv8y6OuP.js +0 -7
  172. package/dist/gateway/static/root/assets/capability-presets-settings-panel-TZmjzWzt.js +0 -3
  173. package/dist/gateway/static/root/assets/channels-settings-g-68dutA.js +0 -1
  174. package/dist/gateway/static/root/assets/channels-status-swr-D7KsAeWh.js +0 -1
  175. package/dist/gateway/static/root/assets/connectors-page-DXA0rAvQ.js +0 -2
  176. package/dist/gateway/static/root/assets/home-page-i6bXCHdo.js +0 -1
  177. package/dist/gateway/static/root/assets/index-BBBE89vm.css +0 -2
  178. package/dist/gateway/static/root/assets/index-BsD5wygl.js +0 -74
  179. package/dist/gateway/static/root/assets/local-app-workbench-page-BCKEDMlP.js +0 -2
  180. package/dist/gateway/static/root/assets/logs-page-Cy9YQK7j.js +0 -2
  181. package/dist/gateway/static/root/assets/markdown-view-CBM-v2ph.js +0 -69
  182. package/dist/gateway/static/root/assets/mermaid-render-BbqDc_LQ.js +0 -134
  183. package/dist/gateway/static/root/assets/messages-CtOJwGW3.js +0 -3
  184. package/dist/gateway/static/root/assets/notes-workbench-B10T3hGX.js +0 -4
  185. package/dist/gateway/static/root/assets/project-detail-page-DsqRlgsy.js +0 -1
  186. package/dist/gateway/static/root/assets/projects-page-Bu2PN8OK.js +0 -1
  187. package/dist/gateway/static/root/assets/remote-access-hub-CXACdJ2f.js +0 -1
  188. package/dist/gateway/static/root/assets/sessions-page-CS2knWDT.js +0 -1
  189. package/dist/gateway/static/root/assets/settings-advanced-gate-ByFGk0q_.js +0 -1
  190. package/dist/gateway/static/root/assets/skill-reload-api-DweAPjI8.js +0 -1
  191. package/dist/gateway/static/root/assets/task-detail-page-DEj-BFMP.js +0 -1
  192. package/dist/gateway/static/root/assets/user-context-page-f7yh7aD5.js +0 -1
  193. package/dist/gateway/static/root/assets/workflow-run-setup-panel-CBAYvm3G.js +0 -3
  194. package/dist/gateway/static/root/assets/workflows-page-BN0JmHrG.js +0 -5
  195. package/dist/src/mobile/notification-service.d.ts +0 -9
  196. package/dist/src/mobile/notification-service.js +0 -156
  197. package/dist/src/mobile/notification-store.d.ts +0 -28
  198. package/dist/src/mobile/notification-store.js +0 -132
  199. package/dist/src/mobile/notification-types.d.ts +0 -37
  200. package/dist/src/mobile/notification-types.js +0 -9
@@ -0,0 +1,114 @@
1
+ import { z } from "zod";
2
+ const TurnOutcomeDeliverableKindSchema = z.enum([
3
+ "document",
4
+ "spreadsheet",
5
+ "presentation",
6
+ "pdf",
7
+ "image",
8
+ "video",
9
+ "audio",
10
+ "site",
11
+ "archive",
12
+ "file"
13
+ ]);
14
+ const TurnOutcomeArtifactLocationSchema = z.enum([
15
+ "workspace",
16
+ "external_host",
17
+ "worktree",
18
+ "remote_runtime",
19
+ "artifact_store"
20
+ ]);
21
+ const TurnOutcomeArtifactAvailabilitySchema = z.enum([
22
+ "materializing",
23
+ "available",
24
+ "expired",
25
+ "missing",
26
+ "failed"
27
+ ]);
28
+ const TurnOutcomeArtifactCapabilitySchema = z.enum([
29
+ "preview",
30
+ "download",
31
+ "open",
32
+ "import",
33
+ "share",
34
+ "regenerate"
35
+ ]);
36
+ const TurnOutcomeDeliverableSchema = z.object({
37
+ artifactId: z.string().min(1),
38
+ title: z.string().min(1),
39
+ kind: TurnOutcomeDeliverableKindSchema,
40
+ mimeType: z.string().optional(),
41
+ sizeBytes: z.number().nonnegative().optional(),
42
+ availability: TurnOutcomeArtifactAvailabilitySchema,
43
+ location: TurnOutcomeArtifactLocationSchema,
44
+ capabilities: z.array(TurnOutcomeArtifactCapabilitySchema),
45
+ uri: z.string().optional(),
46
+ workspaceRelativePath: z.string().optional(),
47
+ shareUrl: z.string().url().optional(),
48
+ thumbnailUrl: z.string().optional(),
49
+ expiresAt: z.string().optional()
50
+ });
51
+ const TurnOutcomeChangedFileSchema = z.object({
52
+ path: z.string().min(1),
53
+ status: z.enum([
54
+ "added",
55
+ "modified",
56
+ "deleted",
57
+ "renamed"
58
+ ]).optional(),
59
+ added: z.number().nonnegative().optional(),
60
+ removed: z.number().nonnegative().optional()
61
+ });
62
+ const TurnOutcomeChangeSetSchema = z.object({
63
+ changeSetId: z.string().min(1),
64
+ files: z.array(TurnOutcomeChangedFileSchema),
65
+ added: z.number().nonnegative(),
66
+ removed: z.number().nonnegative(),
67
+ diff: z.string(),
68
+ diffTruncated: z.boolean().optional(),
69
+ environment: z.enum([
70
+ "workspace",
71
+ "worktree",
72
+ "remote_runtime"
73
+ ])
74
+ });
75
+ const TurnOutcomeEvidenceSchema = z.object({
76
+ evidenceId: z.string().min(1),
77
+ kind: z.enum([
78
+ "check",
79
+ "screenshot",
80
+ "video",
81
+ "log"
82
+ ]),
83
+ label: z.string().min(1),
84
+ status: z.enum([
85
+ "passed",
86
+ "failed",
87
+ "warning"
88
+ ]),
89
+ durationMs: z.number().nonnegative().optional(),
90
+ command: z.string().optional(),
91
+ artifactId: z.string().optional()
92
+ });
93
+ const TurnOutcomeSchema = z.object({
94
+ version: z.literal(1),
95
+ outcomeId: z.string().min(1),
96
+ runId: z.string().min(1),
97
+ turnId: z.string().min(1),
98
+ status: z.enum([
99
+ "succeeded",
100
+ "partial",
101
+ "failed"
102
+ ]),
103
+ summary: z.string().optional(),
104
+ deliverables: z.array(TurnOutcomeDeliverableSchema),
105
+ changeSet: TurnOutcomeChangeSetSchema.optional(),
106
+ evidence: z.array(TurnOutcomeEvidenceSchema),
107
+ createdAt: z.string()
108
+ });
109
+ function parseTurnOutcome(value) {
110
+ const parsed = TurnOutcomeSchema.safeParse(value);
111
+ return parsed.success ? parsed.data : null;
112
+ }
113
+ //#endregion
114
+ export { TurnOutcomeDeliverableSchema, parseTurnOutcome };
@@ -14,6 +14,7 @@ export interface TimeoutConfig {
14
14
  networkTimeoutMs: number;
15
15
  gracefulShutdownMs: number;
16
16
  }
17
+ export declare const DEFAULT_TOOL_EXECUTION_TIMEOUT_MS: number;
17
18
  declare const DEFAULT_CONFIG: TimeoutConfig;
18
19
  export interface TimeoutResult<T> {
19
20
  success: boolean;
@@ -3,12 +3,13 @@ import { init_logger } from "../../utils/logger.js";
3
3
  //#region src/agent/lifecycle/timeout-wrapper.ts
4
4
  init_logger();
5
5
  const log = createLogger("TimeoutWrapper");
6
+ const DEFAULT_TOOL_EXECUTION_TIMEOUT_MS = 1800 * 1e3;
6
7
  const DEFAULT_CONFIG = {
7
- defaultTimeoutMs: 300 * 1e3,
8
- shellTimeoutMs: 300 * 1e3,
9
- readTimeoutMs: 30 * 1e3,
10
- writeTimeoutMs: 60 * 1e3,
11
- networkTimeoutMs: 60 * 1e3,
8
+ defaultTimeoutMs: DEFAULT_TOOL_EXECUTION_TIMEOUT_MS,
9
+ shellTimeoutMs: DEFAULT_TOOL_EXECUTION_TIMEOUT_MS,
10
+ readTimeoutMs: DEFAULT_TOOL_EXECUTION_TIMEOUT_MS,
11
+ writeTimeoutMs: DEFAULT_TOOL_EXECUTION_TIMEOUT_MS,
12
+ networkTimeoutMs: DEFAULT_TOOL_EXECUTION_TIMEOUT_MS,
12
13
  gracefulShutdownMs: 5e3
13
14
  };
14
15
  /**
@@ -254,4 +255,4 @@ var TimeoutManager = class {
254
255
  }
255
256
  };
256
257
  //#endregion
257
- export { DEFAULT_CONFIG as DEFAULT_TIMEOUT_CONFIG, TimeoutError, TimeoutManager, executeWithTimeout, executeWithTimeoutResult, withTimeout };
258
+ export { DEFAULT_CONFIG as DEFAULT_TIMEOUT_CONFIG, DEFAULT_TOOL_EXECUTION_TIMEOUT_MS, TimeoutError, TimeoutManager, executeWithTimeout, executeWithTimeoutResult, withTimeout };
@@ -23,6 +23,6 @@ export type ResolvedHttpMcpTransportConfig = ResolvedBaseMcpTransportConfig & {
23
23
  };
24
24
  };
25
25
  export type ResolvedMcpTransportConfig = ResolvedStdioMcpTransportConfig | ResolvedHttpMcpTransportConfig;
26
- export declare const DEFAULT_MCP_REQUEST_TIMEOUT_MS = 60000;
26
+ export declare const DEFAULT_MCP_REQUEST_TIMEOUT_MS: number;
27
27
  export declare function resolveMcpTransportConfig(serverName: string, rawServer: unknown): ResolvedMcpTransportConfig | null;
28
28
  export {};
@@ -10,7 +10,7 @@ init_logger();
10
10
  init_string_coerce();
11
11
  const log = createLogger("Mcp:Bundle");
12
12
  const DEFAULT_CONNECTION_TIMEOUT_MS = 3e4;
13
- const DEFAULT_MCP_REQUEST_TIMEOUT_MS = 6e4;
13
+ const DEFAULT_MCP_REQUEST_TIMEOUT_MS = 1800 * 1e3;
14
14
  function getConnectionTimeoutMs(rawServer) {
15
15
  if (rawServer && typeof rawServer === "object" && typeof rawServer.connectionTimeoutMs === "number" && rawServer.connectionTimeoutMs > 0) return rawServer.connectionTimeoutMs;
16
16
  return DEFAULT_CONNECTION_TIMEOUT_MS;
@@ -6,9 +6,9 @@ import type { Agent } from '@earendil-works/pi-agent-core';
6
6
  import type { Config } from '../../config/schema.js';
7
7
  /** Minimum per-turn timeout (1 minute). */
8
8
  export declare const MIN_AGENT_TURN_TIMEOUT_MS = 60000;
9
- /** Maximum per-turn timeout (4 hours), aligned with `maxTaskDurationMs` schema cap. */
9
+ /** Maximum configurable per-turn timeout (24 hours). */
10
10
  export declare const MAX_AGENT_TURN_TIMEOUT_MS: number;
11
- /** Default per-turn timeout (30 minutes). */
11
+ /** Default per-turn timeout (4 hours). */
12
12
  export declare const DEFAULT_AGENT_TURN_TIMEOUT_MS: number;
13
13
  export declare const DEFAULT_AGENT_ABORT_GRACE_MS = 5000;
14
14
  export declare class AgentTurnUnsettledError extends Error {
@@ -2,10 +2,10 @@ import { resolveEffectiveAgentManifestForSession } from "../../config/agent-prof
2
2
  //#region src/agent/orchestration/run-agent-turn-with-timeout.ts
3
3
  /** Minimum per-turn timeout (1 minute). */
4
4
  const MIN_AGENT_TURN_TIMEOUT_MS = 6e4;
5
- /** Maximum per-turn timeout (4 hours), aligned with `maxTaskDurationMs` schema cap. */
6
- const MAX_AGENT_TURN_TIMEOUT_MS = 14400 * 1e3;
7
- /** Default per-turn timeout (30 minutes). */
8
- const DEFAULT_AGENT_TURN_TIMEOUT_MS = 1800 * 1e3;
5
+ /** Maximum configurable per-turn timeout (24 hours). */
6
+ const MAX_AGENT_TURN_TIMEOUT_MS = 1440 * 60 * 1e3;
7
+ /** Default per-turn timeout (4 hours). */
8
+ const DEFAULT_AGENT_TURN_TIMEOUT_MS = 14400 * 1e3;
9
9
  const DEFAULT_AGENT_ABORT_GRACE_MS = 5e3;
10
10
  var AgentTurnUnsettledError = class extends Error {
11
11
  constructor(timeoutMs, abortGraceMs) {
@@ -226,7 +226,20 @@ function successResult(locale, payload) {
226
226
  isPublic: payload.reachability === "public"
227
227
  }).filter(Boolean).join("\n")
228
228
  }],
229
- details: payload
229
+ details: {
230
+ ...payload,
231
+ artifacts: [{
232
+ artifactId: `share:${String(payload.shareUrl ?? "")}`,
233
+ title: String(payload.title ?? "Shared result"),
234
+ kind: payload.kind === "site" ? "site" : payload.kind === "zip" ? "archive" : "file",
235
+ availability: "available",
236
+ location: "artifact_store",
237
+ capabilities: payload.kind === "site" ? ["preview", "share"] : ["download", "share"],
238
+ shareUrl: String(payload.shareUrl ?? ""),
239
+ ...typeof payload.thumbnailUrl === "string" ? { thumbnailUrl: payload.thumbnailUrl } : {},
240
+ ...typeof payload.expiresAt === "string" ? { expiresAt: payload.expiresAt } : {}
241
+ }]
242
+ }
230
243
  };
231
244
  }
232
245
  function errorResult(locale, message) {
@@ -4,14 +4,14 @@ import { resolve } from "node:path";
4
4
  import { spawn } from "node:child_process";
5
5
  import { Type } from "@sinclair/typebox";
6
6
  //#region src/agent/tools/exec-command.ts
7
- const MAX_COMMAND_TIMEOUT_MS = 3e5;
8
- const DEFAULT_TIMEOUT_MS = 12e4;
7
+ const MAX_COMMAND_TIMEOUT_MS = 14400 * 1e3;
8
+ const DEFAULT_TIMEOUT_MS = 1800 * 1e3;
9
9
  const DEFAULT_MAX_OUTPUT_CHARS = 5e4;
10
10
  const STREAM_DELTA_MAX_CHARS = 16e3;
11
11
  const ExecCommandSchema = Type.Object({
12
12
  cmd: Type.String({ description: "Shell command to execute." }),
13
13
  cwd: Type.Optional(Type.String({ description: "Working directory. Relative paths are resolved under the agent workspace." })),
14
- timeoutMs: Type.Optional(Type.Number({ description: "Command timeout in milliseconds. Defaults to 120000 and is capped at 300000." })),
14
+ timeoutMs: Type.Optional(Type.Number({ description: "Command timeout in milliseconds. Defaults to 1800000 (30m) and is capped at 14400000 (4h)." })),
15
15
  maxOutputChars: Type.Optional(Type.Number({ description: "Maximum characters returned to the model. UI streaming still receives output deltas." }))
16
16
  });
17
17
  function clampTimeoutMs(raw) {
@@ -12,7 +12,7 @@ const MAX_TIMEOUT_SEC = 14400;
12
12
  const ExecuteCodeSchema = Type.Object({
13
13
  code: Type.String({ description: "JavaScript to run. Exposed as `tools` (async functions) and `console`:\n await tools.web_search(query, count?)\n await tools.web_fetch(url, maxChars?)\n await tools.read_file(path, limit?)\n await tools.write_file(path, content)\n await tools.grep(pattern, { path?, glob?, ignoreCase?, literal?, context?, limit? })\n await tools.find(pattern, { path?, limit? })\n await tools.exec_command(cmd, cwd?)\n\nUse console.log() for output; combined stdout/stderr is returned." }),
14
14
  timeout: Type.Optional(Type.Number({
15
- description: "Execution timeout in seconds (default: 3600 = 60m, max: 14400 = 4h)",
15
+ description: "Execution timeout in seconds (default: 1800 = 30m, max: 14400 = 4h)",
16
16
  default: DEFAULT_TIMEOUT_SEC
17
17
  }))
18
18
  });
@@ -1,13 +1,13 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
- import { TimeoutError, executeWithTimeout } from "../lifecycle/timeout-wrapper.js";
3
+ import { DEFAULT_TOOL_EXECUTION_TIMEOUT_MS, TimeoutError, executeWithTimeout } from "../lifecycle/timeout-wrapper.js";
4
4
  import { withRetry } from "../../infra/retry.js";
5
5
  import { ToolConcurrencyController, resolveToolLockMode } from "./concurrency.js";
6
6
  //#region src/agent/tools/executor.ts
7
7
  init_logger();
8
8
  const log = createLogger("ToolExecutor");
9
9
  const DEFAULT_CONFIG = {
10
- defaultTimeoutMs: 300 * 1e3,
10
+ defaultTimeoutMs: DEFAULT_TOOL_EXECUTION_TIMEOUT_MS,
11
11
  maxRetries: 2,
12
12
  retryDelayMs: 1e3,
13
13
  enableTimeout: true,
@@ -296,6 +296,18 @@ function createImageGenerateTool(options) {
296
296
  paths,
297
297
  workspaceRelativePaths,
298
298
  media,
299
+ artifacts: media.map((item, index) => ({
300
+ artifactId: item.id,
301
+ title: item.name,
302
+ kind: "image",
303
+ mimeType: item.mimeType,
304
+ sizeBytes: item.size,
305
+ availability: "available",
306
+ location: "artifact_store",
307
+ capabilities: ["preview", "download"],
308
+ uri: item.uri,
309
+ workspaceRelativePath: workspaceRelativePaths[index]
310
+ })),
299
311
  attempts: result.attempts,
300
312
  ...result.normalization ? { normalization: result.normalization } : {},
301
313
  ...result.ignoredOverrides.length > 0 ? { ignoredOverrides: result.ignoredOverrides } : {},
@@ -64,6 +64,17 @@ function createSendMediaTool(workspace, bus, getContext) {
64
64
  }],
65
65
  details: {
66
66
  media: [media],
67
+ artifacts: [{
68
+ artifactId: media.id,
69
+ title: media.name,
70
+ kind: media.type === "photo" ? "image" : media.type === "video" ? "video" : media.type === "audio" ? "audio" : media.mimeType === "application/pdf" ? "pdf" : "file",
71
+ mimeType: media.mimeType,
72
+ sizeBytes: media.size,
73
+ availability: "available",
74
+ location: "artifact_store",
75
+ capabilities: ["preview", "download"],
76
+ uri: media.uri
77
+ }],
67
78
  ...p.caption ? { caption: p.caption } : {}
68
79
  }
69
80
  };
@@ -6,6 +6,7 @@ import { ObjectLinkService } from "../../activity/service.js";
6
6
  import "../../activity/index.js";
7
7
  import { getDefaultAgentId, init_resolve_route } from "../../routing/resolve-route.js";
8
8
  import { TaskRepository } from "../../tasks/task-repository.js";
9
+ import { enqueueTaskChangedEvent } from "../../tasks/task-change-events.js";
9
10
  import { TaskRunRepository } from "../../tasks/task-run-repository.js";
10
11
  import { TaskReadModelProjector } from "../../tasks/task-read-model-projector.js";
11
12
  import { TaskCommandSchema, TaskContextInputSchema } from "../../../packages/gateway-contract/src/tasks.js";
@@ -15,7 +16,6 @@ import "../../automations/index.js";
15
16
  import { isValidProjectAgentId, normalizeProjectAgentId, resolveProjectAgentId } from "../../projects/project-agent.js";
16
17
  import "../../projects/index.js";
17
18
  import { TaskContextRepository } from "../../tasks/task-context-repository.js";
18
- import { enqueueTaskChangedEvent } from "../../tasks/task-change-events.js";
19
19
  import { TaskDependencyError, TaskDependencyService } from "../../tasks/task-dependency-service.js";
20
20
  import { TaskApplicationService } from "../../tasks/task-application-service.js";
21
21
  import { defineTaskContract } from "../../tasks/task-contract-definition.js";
@@ -11,6 +11,7 @@ const REGISTRY_COMMAND_MODULES = {
11
11
  tui: () => import("./commands/tui.js"),
12
12
  resume: () => import("./commands/resume.js"),
13
13
  gateway: () => import("./commands/gateway.js"),
14
+ history: () => import("./commands/history.js"),
14
15
  session: () => import("./commands/session.js"),
15
16
  project: () => import("./commands/project.js"),
16
17
  config: () => import("./commands/config.js"),
@@ -67,6 +67,10 @@ const ROOT_HELP_COMMANDS = [
67
67
  name: "gateway [options]",
68
68
  description: "Start the xopc gateway server"
69
69
  },
70
+ {
71
+ name: "history",
72
+ description: "Export XOPC session history for external tools"
73
+ },
70
74
  {
71
75
  name: "session",
72
76
  description: "Session management commands"
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
52
52
  id: "database-schema",
53
53
  label: "Database schema",
54
54
  status: "pass",
55
- message: `SQLite schema v${status.dbVersion} (current release v135).`,
55
+ message: `SQLite schema v${status.dbVersion} (current release v136).`,
56
56
  hints: []
57
57
  };
58
58
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,50 @@
1
+ import { requireXopcDatabase } from "../../storage/sqlite/connection.js";
2
+ import "../../storage/sqlite/index.js";
3
+ import { formatExamples, register } from "../registry.js";
4
+ import { exportCtxHistory } from "../../history/ctx/exporter.js";
5
+ import { Command } from "commander";
6
+ //#region src/cli/commands/history.ts
7
+ async function runCtxExport(options) {
8
+ try {
9
+ const { db } = requireXopcDatabase();
10
+ const result = await exportCtxHistory(db, { outputDir: options.outputDir });
11
+ const importCommand = `ctx import --history-source-manifest ${result.manifestPath}`;
12
+ if (options.json) {
13
+ console.log(JSON.stringify({
14
+ ...result,
15
+ importCommand
16
+ }, null, 2));
17
+ return;
18
+ }
19
+ const action = result.changed ? "Exported" : "Already up to date";
20
+ console.log(`${action}: ${result.sessionCount} sessions, ${result.eventCount} events`);
21
+ console.log(`History: ${result.historyPath}`);
22
+ console.log(`Manifest: ${result.manifestPath}`);
23
+ console.log(`\nRegister or refresh it in ctx:\n ${importCommand}`);
24
+ } catch (error) {
25
+ const message = error instanceof Error ? error.message : String(error);
26
+ console.error(`Failed to export history for ctx: ${message}`);
27
+ process.exit(1);
28
+ }
29
+ }
30
+ function createHistoryCommand(_ctx) {
31
+ const command = new Command("history").description("Export XOPC session history for external tools").addHelpText("after", formatExamples([
32
+ "xopc history export ctx",
33
+ "xopc history export ctx --output-dir ./xopc-ctx-history",
34
+ "xopc history export ctx --json"
35
+ ]));
36
+ command.command("export").description("Export session history").command("ctx").description("Export a provider-owned ctx-history-jsonl-v2 source").option("--output-dir <path>", "Output directory (default: <xopc-state>/exports/ctx)").option("--json", "Output the result as JSON").action(runCtxExport);
37
+ return command;
38
+ }
39
+ register({
40
+ id: "history",
41
+ name: "history",
42
+ description: "Export XOPC session history for external tools",
43
+ factory: createHistoryCommand,
44
+ metadata: {
45
+ category: "utility",
46
+ examples: ["xopc history export ctx"]
47
+ }
48
+ });
49
+ //#endregion
50
+ export {};
@@ -1,6 +1,6 @@
1
+ import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
1
2
  import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
2
3
  import "../agent-manifest/index.js";
3
- import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
4
4
  import { init_session_key, parseSessionKey } from "../routing/session-key.js";
5
5
  import { agentExists, getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
6
6
  //#region src/config/agent-profile.ts
@@ -1,5 +1,5 @@
1
- import { resolveCapabilityPresetLayer, resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
2
1
  import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
2
+ import { resolveCapabilityPresetLayer, resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
3
3
  import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
4
4
  import { WORKSPACE_FILES, init_paths } from "../config/paths.js";
5
5
  import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET } from "../agent/context/workspace.js";
@@ -1,4 +1,4 @@
1
- import type { ToolActivity } from '@xopcai/gateway-contract';
1
+ import type { ToolActivity, TurnOutcome } from '@xopcai/gateway-contract';
2
2
  export type ChatStreamStatus = 'success' | 'error' | 'cancelled';
3
3
  export type PetFeedbackTaskState = 'working' | 'waiting' | 'success' | 'error';
4
4
  export type PetFeedbackSensitivity = 'public' | 'private';
@@ -142,6 +142,7 @@ export type TurnDiffEvent = ChatStreamEnvelope<'turn_diff', {
142
142
  added: number;
143
143
  removed: number;
144
144
  }>;
145
+ export type TurnOutcomeEvent = ChatStreamEnvelope<'turn_outcome', TurnOutcome>;
145
146
  export type ReviewStartEvent = ChatStreamEnvelope<'review_start', {
146
147
  messageId: string;
147
148
  reviewId: string;
@@ -237,4 +238,4 @@ export type StreamErrorEvent = ChatStreamEnvelope<'error', {
237
238
  recoverable?: boolean;
238
239
  petFeedback: PetFeedback;
239
240
  }>;
240
- export type ChatStreamEvent = RunStartEvent | UserMessageEvent | UserTranscriptEvent | AssistantMessageStartEvent | AssistantDeltaEvent | ThinkingDeltaEvent | ThinkingEndEvent | ToolStartEvent | ToolUpdateEvent | ToolEndEvent | CommandStartedEvent | CommandOutputDeltaEvent | CommandCompletedEvent | PatchAppliedEvent | TurnPlanUpdatedEvent | TaskPlanUpdatedEvent | TurnDiffEvent | ReviewStartEvent | ReviewDeltaEvent | ReviewEndEvent | ReviewEvent | AssistantMessageEndEvent | ProgressEvent | CompactionEvent | TtsAudioEvent | ClarifyRequestEvent | MemoryConsentRequiredEvent | MemoryCapturedEvent | MemoryCandidateEvent | RunEndEvent | StreamErrorEvent;
241
+ export type ChatStreamEvent = RunStartEvent | UserMessageEvent | UserTranscriptEvent | AssistantMessageStartEvent | AssistantDeltaEvent | ThinkingDeltaEvent | ThinkingEndEvent | ToolStartEvent | ToolUpdateEvent | ToolEndEvent | CommandStartedEvent | CommandOutputDeltaEvent | CommandCompletedEvent | PatchAppliedEvent | TurnPlanUpdatedEvent | TaskPlanUpdatedEvent | TurnDiffEvent | TurnOutcomeEvent | ReviewStartEvent | ReviewDeltaEvent | ReviewEndEvent | ReviewEvent | AssistantMessageEndEvent | ProgressEvent | CompactionEvent | TtsAudioEvent | ClarifyRequestEvent | MemoryConsentRequiredEvent | MemoryCapturedEvent | MemoryCandidateEvent | RunEndEvent | StreamErrorEvent;
@@ -0,0 +1,16 @@
1
+ import type { AgentStreamRunStatus, TurnOutcome } from '@xopcai/gateway-contract';
2
+ import type { ChatStreamEvent } from './protocol.js';
3
+ export declare class TurnOutcomeCollector {
4
+ private readonly runId;
5
+ private readonly environment;
6
+ private readonly deliverables;
7
+ private readonly evidence;
8
+ private readonly files;
9
+ private readonly diffs;
10
+ private added;
11
+ private removed;
12
+ private failedToolCount;
13
+ constructor(runId: string, environment?: 'workspace' | 'worktree' | 'remote_runtime');
14
+ capture(event: ChatStreamEvent): void;
15
+ finalize(status: AgentStreamRunStatus, summary?: string): TurnOutcome;
16
+ }
@@ -0,0 +1,111 @@
1
+ import { TurnOutcomeDeliverableSchema } from "../../../packages/gateway-contract/src/turn-outcome.js";
2
+ //#region src/gateway/chat-stream/turn-outcome-collector.ts
3
+ const VERIFICATION_COMMAND = /(^|[\s:/_-])(test|vitest|jest|pytest|lint|typecheck|type-check|build)([\s:/_-]|$)/i;
4
+ const MAX_OUTCOME_DIFF_CHARS = 2e5;
5
+ function asRecord(value) {
6
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
7
+ }
8
+ function optionalString(value) {
9
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
10
+ }
11
+ function fileStatus(kind) {
12
+ if (kind === "add") return "added";
13
+ if (kind === "delete") return "deleted";
14
+ if (kind === "move") return "renamed";
15
+ if (kind === "update") return "modified";
16
+ }
17
+ function changedFiles(changes) {
18
+ return changes.flatMap((value) => {
19
+ const row = asRecord(value);
20
+ const path = optionalString(row?.moveTo) ?? optionalString(row?.path);
21
+ if (!path) return [];
22
+ return [{
23
+ path,
24
+ ...fileStatus(row?.kind) ? { status: fileStatus(row?.kind) } : {},
25
+ ...typeof row?.added === "number" ? { added: Math.max(0, row.added) } : {},
26
+ ...typeof row?.removed === "number" ? { removed: Math.max(0, row.removed) } : {}
27
+ }];
28
+ });
29
+ }
30
+ function structuredDeliverables(details) {
31
+ if (!Array.isArray(details.artifacts)) return [];
32
+ return details.artifacts.flatMap((value) => {
33
+ const parsed = TurnOutcomeDeliverableSchema.safeParse(value);
34
+ return parsed.success ? [parsed.data] : [];
35
+ });
36
+ }
37
+ var TurnOutcomeCollector = class {
38
+ deliverables = /* @__PURE__ */ new Map();
39
+ evidence = /* @__PURE__ */ new Map();
40
+ files = /* @__PURE__ */ new Map();
41
+ diffs = [];
42
+ added = 0;
43
+ removed = 0;
44
+ failedToolCount = 0;
45
+ constructor(runId, environment = "workspace") {
46
+ this.runId = runId;
47
+ this.environment = environment;
48
+ }
49
+ capture(event) {
50
+ if (event.type === "tool_end") {
51
+ if (event.payload.status !== "success") {
52
+ this.failedToolCount += 1;
53
+ return;
54
+ }
55
+ const details = asRecord(event.payload.result?.details);
56
+ if (!details) return;
57
+ for (const artifact of structuredDeliverables(details)) this.deliverables.set(artifact.artifactId, artifact);
58
+ return;
59
+ }
60
+ if (event.type === "patch_applied") {
61
+ for (const file of changedFiles(event.payload.changes)) this.files.set(file.path, file);
62
+ return;
63
+ }
64
+ if (event.type === "turn_diff") {
65
+ for (const path of event.payload.files) if (!this.files.has(path)) this.files.set(path, { path });
66
+ if (event.payload.diff.trim()) this.diffs.push(event.payload.diff);
67
+ this.added += Math.max(0, event.payload.added);
68
+ this.removed += Math.max(0, event.payload.removed);
69
+ return;
70
+ }
71
+ if (event.type === "command_completed" && VERIFICATION_COMMAND.test(event.payload.command)) {
72
+ const status = event.payload.exitCode === 0 && !event.payload.timedOut ? "passed" : "failed";
73
+ this.evidence.set(event.payload.toolCallId, {
74
+ evidenceId: `${this.runId}:${event.payload.toolCallId}:check`,
75
+ kind: "check",
76
+ label: event.payload.command,
77
+ status,
78
+ command: event.payload.command,
79
+ ...event.payload.durationMs !== void 0 ? { durationMs: event.payload.durationMs } : {}
80
+ });
81
+ }
82
+ }
83
+ finalize(status, summary) {
84
+ const evidence = [...this.evidence.values()];
85
+ const partial = this.failedToolCount > 0 || evidence.some((item) => item.status === "failed");
86
+ const fullDiff = this.diffs.join("\n");
87
+ const diffTruncated = fullDiff.length > MAX_OUTCOME_DIFF_CHARS;
88
+ return {
89
+ version: 1,
90
+ outcomeId: `${this.runId}:outcome`,
91
+ runId: this.runId,
92
+ turnId: this.runId,
93
+ status: status === "error" ? "failed" : status === "cancelled" || partial ? "partial" : "succeeded",
94
+ ...summary?.trim() ? { summary: summary.trim() } : {},
95
+ deliverables: [...this.deliverables.values()],
96
+ ...this.files.size > 0 || this.diffs.length > 0 ? { changeSet: {
97
+ changeSetId: `${this.runId}:changes`,
98
+ files: [...this.files.values()],
99
+ added: this.added,
100
+ removed: this.removed,
101
+ diff: diffTruncated ? fullDiff.slice(0, MAX_OUTCOME_DIFF_CHARS) : fullDiff,
102
+ ...diffTruncated ? { diffTruncated: true } : {},
103
+ environment: this.environment
104
+ } } : {},
105
+ evidence,
106
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
107
+ };
108
+ }
109
+ };
110
+ //#endregion
111
+ export { TurnOutcomeCollector };
@@ -52,7 +52,7 @@ function resolveCacheControl(relativePath) {
52
52
  function resolveContentType(relativePath) {
53
53
  return MIME_TYPES[relativePath.split(".").pop()?.toLowerCase() || ""] || "application/octet-stream";
54
54
  }
55
- function loadIntoCache(relativePath) {
55
+ function readStaticFile(relativePath, cache) {
56
56
  const filePath = resolve(UI_STATIC_ROOT, relativePath);
57
57
  try {
58
58
  const content = readFileSync(filePath);
@@ -62,8 +62,10 @@ function loadIntoCache(relativePath) {
62
62
  etag: computeEtag(content),
63
63
  cacheControl: resolveCacheControl(relativePath)
64
64
  };
65
- fileCache.set(relativePath, cached);
66
- stats.entries = fileCache.size;
65
+ if (cache) {
66
+ fileCache.set(relativePath, cached);
67
+ stats.entries = fileCache.size;
68
+ }
67
69
  stats.misses += 1;
68
70
  return cached;
69
71
  } catch {
@@ -71,12 +73,13 @@ function loadIntoCache(relativePath) {
71
73
  }
72
74
  }
73
75
  function getCachedFile(relativePath) {
76
+ if (relativePath === "index.html") return readStaticFile(relativePath, false);
74
77
  const cached = fileCache.get(relativePath);
75
78
  if (cached) {
76
79
  stats.hits += 1;
77
80
  return cached;
78
81
  }
79
- return loadIntoCache(relativePath);
82
+ return readStaticFile(relativePath, true);
80
83
  }
81
84
  function getStaticUiCacheStats() {
82
85
  return { ...stats };
@@ -92,7 +95,6 @@ function resolveStaticUiRootForTests() {
92
95
  return UI_STATIC_ROOT;
93
96
  }
94
97
  const DEFAULT_PREWARM_PATHS = [
95
- "index.html",
96
98
  "favicon.ico",
97
99
  "logo.svg",
98
100
  "logo-dark.svg"
@@ -8,6 +8,7 @@ import { registerProjectsRoutes } from "./projects.js";
8
8
  import { registerProjectSkillRoutes } from "./project-skills.js";
9
9
  import { registerSearchRoutes } from "./search.js";
10
10
  import { registerMobileRoutes } from "./mobile.js";
11
+ import { registerNotificationRoutes } from "./notifications.js";
11
12
  import { registerInteractionStateRoutes } from "./interaction-state.js";
12
13
  import { registerComposerHistoryRoutes } from "./composer-history.js";
13
14
  import { registerEndpointToolRoutes } from "./endpoint-tools.js";
@@ -35,6 +36,7 @@ function registerCoreAuthenticatedRoutes(authenticated, deps) {
35
36
  registerProactiveRoutes(authenticated, deps);
36
37
  registerSearchRoutes(authenticated, deps);
37
38
  registerMobileRoutes(authenticated, deps);
39
+ registerNotificationRoutes(authenticated, deps);
38
40
  registerInteractionStateRoutes(authenticated, deps);
39
41
  registerComposerHistoryRoutes(authenticated, deps);
40
42
  registerEndpointToolRoutes(authenticated, deps);