@orion-agents/orion-code 0.3.0 → 0.3.2

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 (172) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +45 -18
  3. package/README.zh-CN.md +39 -18
  4. package/dist/commands/model-command-handlers.d.ts.map +1 -1
  5. package/dist/commands/model-command-handlers.js +59 -14
  6. package/dist/commands/model-command-handlers.js.map +1 -1
  7. package/dist/commands/types.d.ts +6 -0
  8. package/dist/commands/types.d.ts.map +1 -1
  9. package/dist/commands/types.js.map +1 -1
  10. package/dist/commands/workflow-command-handlers.d.ts +1 -1
  11. package/dist/commands/workflow-command-handlers.d.ts.map +1 -1
  12. package/dist/commands/workflow-command-handlers.js +42 -3
  13. package/dist/commands/workflow-command-handlers.js.map +1 -1
  14. package/dist/commands/workflow-commands.d.ts.map +1 -1
  15. package/dist/commands/workflow-commands.js +2 -2
  16. package/dist/commands/workflow-commands.js.map +1 -1
  17. package/dist/core/tool-artifacts.d.ts +2 -0
  18. package/dist/core/tool-artifacts.d.ts.map +1 -1
  19. package/dist/core/tool-artifacts.js +27 -1
  20. package/dist/core/tool-artifacts.js.map +1 -1
  21. package/dist/runtime/agent-runtime-controller.d.ts +16 -2
  22. package/dist/runtime/agent-runtime-controller.d.ts.map +1 -1
  23. package/dist/runtime/agent-runtime-controller.js +116 -8
  24. package/dist/runtime/agent-runtime-controller.js.map +1 -1
  25. package/dist/runtime/agent-runtime-protocol.d.ts +7 -0
  26. package/dist/runtime/agent-runtime-protocol.d.ts.map +1 -1
  27. package/dist/runtime/agent-runtime-protocol.js.map +1 -1
  28. package/dist/runtime/agent-runtime-runner.d.ts +8 -0
  29. package/dist/runtime/agent-runtime-runner.d.ts.map +1 -1
  30. package/dist/runtime/durable-tool-receipt-reader.d.ts +32 -0
  31. package/dist/runtime/durable-tool-receipt-reader.d.ts.map +1 -0
  32. package/dist/runtime/durable-tool-receipt-reader.js +130 -0
  33. package/dist/runtime/durable-tool-receipt-reader.js.map +1 -0
  34. package/dist/runtime/legacy-thread-materializer.d.ts +14 -1
  35. package/dist/runtime/legacy-thread-materializer.d.ts.map +1 -1
  36. package/dist/runtime/legacy-thread-materializer.js +44 -5
  37. package/dist/runtime/legacy-thread-materializer.js.map +1 -1
  38. package/dist/runtime/orion-session-runner.d.ts +4 -0
  39. package/dist/runtime/orion-session-runner.d.ts.map +1 -1
  40. package/dist/runtime/orion-session-runner.js +15 -0
  41. package/dist/runtime/orion-session-runner.js.map +1 -1
  42. package/dist/runtime/plan-review.d.ts +38 -0
  43. package/dist/runtime/plan-review.d.ts.map +1 -0
  44. package/dist/runtime/plan-review.js +173 -0
  45. package/dist/runtime/plan-review.js.map +1 -0
  46. package/dist/runtime/product-bootstrap.d.ts.map +1 -1
  47. package/dist/runtime/product-bootstrap.js +28 -6
  48. package/dist/runtime/product-bootstrap.js.map +1 -1
  49. package/dist/runtime/product-orion-runtime.d.ts.map +1 -1
  50. package/dist/runtime/product-orion-runtime.js +14 -35
  51. package/dist/runtime/product-orion-runtime.js.map +1 -1
  52. package/dist/runtime/protocol/runtime-protocol-v1.d.ts +73 -0
  53. package/dist/runtime/protocol/runtime-protocol-v1.d.ts.map +1 -1
  54. package/dist/runtime/protocol/runtime-protocol-v1.js +37 -0
  55. package/dist/runtime/protocol/runtime-protocol-v1.js.map +1 -1
  56. package/dist/runtime/release-receipts.d.ts +8 -3
  57. package/dist/runtime/release-receipts.d.ts.map +1 -1
  58. package/dist/runtime/release-receipts.js +88 -4
  59. package/dist/runtime/release-receipts.js.map +1 -1
  60. package/dist/runtime/session-composer-control.d.ts +136 -0
  61. package/dist/runtime/session-composer-control.d.ts.map +1 -0
  62. package/dist/runtime/session-composer-control.js +532 -0
  63. package/dist/runtime/session-composer-control.js.map +1 -0
  64. package/dist/runtime/thread-event-store.d.ts +62 -9
  65. package/dist/runtime/thread-event-store.d.ts.map +1 -1
  66. package/dist/runtime/thread-event-store.js +363 -31
  67. package/dist/runtime/thread-event-store.js.map +1 -1
  68. package/dist/runtime/thread-projection.d.ts +17 -0
  69. package/dist/runtime/thread-projection.d.ts.map +1 -1
  70. package/dist/runtime/thread-projection.js +87 -0
  71. package/dist/runtime/thread-projection.js.map +1 -1
  72. package/dist/runtime/thread-session-index.d.ts +84 -0
  73. package/dist/runtime/thread-session-index.d.ts.map +1 -0
  74. package/dist/runtime/thread-session-index.js +503 -0
  75. package/dist/runtime/thread-session-index.js.map +1 -0
  76. package/dist/runtime/thread-session-view.d.ts +31 -13
  77. package/dist/runtime/thread-session-view.d.ts.map +1 -1
  78. package/dist/runtime/thread-session-view.js +116 -61
  79. package/dist/runtime/thread-session-view.js.map +1 -1
  80. package/dist/runtime/thread-ui-adapter.d.ts.map +1 -1
  81. package/dist/runtime/thread-ui-adapter.js +18 -58
  82. package/dist/runtime/thread-ui-adapter.js.map +1 -1
  83. package/dist/runtime/tool-detail-repository.d.ts.map +1 -1
  84. package/dist/runtime/tool-detail-repository.js +23 -19
  85. package/dist/runtime/tool-detail-repository.js.map +1 -1
  86. package/dist/runtime/tool-receipt-validator.d.ts +21 -0
  87. package/dist/runtime/tool-receipt-validator.d.ts.map +1 -0
  88. package/dist/runtime/tool-receipt-validator.js +157 -0
  89. package/dist/runtime/tool-receipt-validator.js.map +1 -0
  90. package/dist/runtime/ui-events.d.ts +6 -1
  91. package/dist/runtime/ui-events.d.ts.map +1 -1
  92. package/dist/runtime/ui-events.js.map +1 -1
  93. package/dist/services/redaction.d.ts +4 -0
  94. package/dist/services/redaction.d.ts.map +1 -1
  95. package/dist/services/redaction.js +63 -0
  96. package/dist/services/redaction.js.map +1 -1
  97. package/dist/services/session-index.d.ts +16 -0
  98. package/dist/services/session-index.d.ts.map +1 -1
  99. package/dist/services/session-index.js +45 -36
  100. package/dist/services/session-index.js.map +1 -1
  101. package/dist/services/session-storage.d.ts +36 -0
  102. package/dist/services/session-storage.d.ts.map +1 -1
  103. package/dist/services/session-storage.js +80 -7
  104. package/dist/services/session-storage.js.map +1 -1
  105. package/dist/services/workspace-registry.d.ts +42 -0
  106. package/dist/services/workspace-registry.d.ts.map +1 -0
  107. package/dist/services/workspace-registry.js +222 -0
  108. package/dist/services/workspace-registry.js.map +1 -0
  109. package/dist/web/errors.d.ts +6 -0
  110. package/dist/web/errors.d.ts.map +1 -0
  111. package/dist/web/errors.js +13 -0
  112. package/dist/web/errors.js.map +1 -0
  113. package/dist/web/event-hub.d.ts +4 -0
  114. package/dist/web/event-hub.d.ts.map +1 -1
  115. package/dist/web/event-hub.js +81 -11
  116. package/dist/web/event-hub.js.map +1 -1
  117. package/dist/web/file-read-service.d.ts +64 -0
  118. package/dist/web/file-read-service.d.ts.map +1 -0
  119. package/dist/web/file-read-service.js +409 -0
  120. package/dist/web/file-read-service.js.map +1 -0
  121. package/dist/web/git-read-model-service.d.ts +85 -0
  122. package/dist/web/git-read-model-service.d.ts.map +1 -0
  123. package/dist/web/git-read-model-service.js +657 -0
  124. package/dist/web/git-read-model-service.js.map +1 -0
  125. package/dist/web/protocol.d.ts +205 -1
  126. package/dist/web/protocol.d.ts.map +1 -1
  127. package/dist/web/protocol.js +229 -1
  128. package/dist/web/protocol.js.map +1 -1
  129. package/dist/web/review-service.d.ts +38 -0
  130. package/dist/web/review-service.d.ts.map +1 -0
  131. package/dist/web/review-service.js +74 -0
  132. package/dist/web/review-service.js.map +1 -0
  133. package/dist/web/server.d.ts.map +1 -1
  134. package/dist/web/server.js +312 -29
  135. package/dist/web/server.js.map +1 -1
  136. package/dist/web/terminal-manager.d.ts +156 -0
  137. package/dist/web/terminal-manager.d.ts.map +1 -0
  138. package/dist/web/terminal-manager.js +760 -0
  139. package/dist/web/terminal-manager.js.map +1 -0
  140. package/dist/web/terminal-server.d.ts +8 -0
  141. package/dist/web/terminal-server.d.ts.map +1 -0
  142. package/dist/web/terminal-server.js +275 -0
  143. package/dist/web/terminal-server.js.map +1 -0
  144. package/dist/web/workbench-controller.d.ts +71 -18
  145. package/dist/web/workbench-controller.d.ts.map +1 -1
  146. package/dist/web/workbench-controller.js +1187 -178
  147. package/dist/web/workbench-controller.js.map +1 -1
  148. package/dist/web-client/assets/DiffViewer-eaQNsnCh.js +5 -0
  149. package/dist/web-client/assets/FilesPanel-DYs1MhoM.js +2 -0
  150. package/dist/web-client/assets/GitPanel-CnU4XVr7.js +1 -0
  151. package/dist/web-client/assets/ReviewPanel-BDxG670T.js +1 -0
  152. package/dist/web-client/assets/TerminalPanel-DLuoa74B.css +1 -0
  153. package/dist/web-client/assets/TerminalPanel-Q5mSSsoK.js +23 -0
  154. package/dist/web-client/assets/index-BWV5sIvw.css +1 -0
  155. package/dist/web-client/assets/index-VVUKj6FE.js +17 -0
  156. package/dist/web-client/index.html +2 -2
  157. package/docs/architecture/agent-mode-permission-contract.md +87 -0
  158. package/docs/architecture/v0.3.0-web-api.yaml +44 -13
  159. package/docs/architecture/v0.3.1-web-api.yaml +2338 -0
  160. package/docs/architecture/v0.3.2-web-api.yaml +3029 -0
  161. package/docs/migration/v0.3.0-to-v0.3.1.md +88 -0
  162. package/docs/migration/v0.3.1-to-v0.3.2.md +94 -0
  163. package/docs/plan/v0.3.0-web-workbench-plan.md +58 -7
  164. package/docs/plan/v0.3.1-web-workbench-professional-shell-plan.md +848 -0
  165. package/docs/plan/v0.3.2-web-workbench-layout-and-composer-plan.md +869 -0
  166. package/docs/readme.md +20 -0
  167. package/docs/test/v0.3.1-web-workbench-e2e-plan.md +140 -0
  168. package/docs/test/v0.3.2-web-workbench-e2e-plan.md +100 -0
  169. package/npm-shrinkwrap.json +185 -354
  170. package/package.json +21 -4
  171. package/dist/web-client/assets/index-BAEO71Gp.css +0 -1
  172. package/dist/web-client/assets/index-DSkFy7gM.js +0 -13
@@ -0,0 +1,2338 @@
1
+ openapi: 3.1.0
2
+ info:
3
+ title: Orion Code Local Web API
4
+ version: 0.3.1
5
+ description: >-
6
+ Same-origin loopback API for the Orion Code v0.3.1 Web Workbench. Unary resources use bounded
7
+ JSON HTTP; commands use POST; runtime invalidations use one replayable Server-Sent Events
8
+ downlink. Terminal bytes are intentionally isolated on a ticket-authenticated, same-origin
9
+ WebSocket and never enter SSE, snapshots, diagnostics, evidence logs, or durable transcripts.
10
+ servers:
11
+ - url: /api/v1
12
+ paths:
13
+ /health:
14
+ get:
15
+ operationId: getHealth
16
+ responses:
17
+ '200':
18
+ description: Process health without secret or workspace data.
19
+ content:
20
+ application/json:
21
+ schema:
22
+ $ref: '#/components/schemas/HealthResponse'
23
+ /bootstrap:
24
+ get:
25
+ operationId: getBootstrap
26
+ responses:
27
+ '200':
28
+ description: Secret-free workbench bootstrap state.
29
+ content:
30
+ application/json:
31
+ schema:
32
+ $ref: '#/components/schemas/BootstrapResponse'
33
+ /workspaces:
34
+ get:
35
+ operationId: listWorkspaces
36
+ description: Cursor-paged canonical workspaces known to the local Orion installation.
37
+ parameters:
38
+ - $ref: '#/components/parameters/ContextWorkspaceId'
39
+ - $ref: '#/components/parameters/ExpectedContextRevision'
40
+ - $ref: '#/components/parameters/CollectionCursor'
41
+ - $ref: '#/components/parameters/PageSize'
42
+ responses:
43
+ '200':
44
+ description: One bounded workspace page.
45
+ content:
46
+ application/json:
47
+ schema:
48
+ $ref: '#/components/schemas/WorkspacePage'
49
+ '400': { $ref: '#/components/responses/Problem' }
50
+ '409': { $ref: '#/components/responses/Problem' }
51
+ /workspaces/{workspaceId}/sessions:
52
+ get:
53
+ operationId: listWorkspaceSessions
54
+ description: >-
55
+ Read one revision-bound Session page for a registered project, including an inactive
56
+ project, without activating or constructing its Runtime.
57
+ parameters:
58
+ - $ref: '#/components/parameters/WorkspaceId'
59
+ - $ref: '#/components/parameters/ContextWorkspaceId'
60
+ - $ref: '#/components/parameters/ExpectedContextRevision'
61
+ - $ref: '#/components/parameters/CollectionCursor'
62
+ - $ref: '#/components/parameters/PageSize'
63
+ responses:
64
+ '200':
65
+ description: One bounded Session page for the named workspace.
66
+ content:
67
+ application/json:
68
+ schema: { $ref: '#/components/schemas/SessionPage' }
69
+ '400': { $ref: '#/components/responses/Problem' }
70
+ '404': { $ref: '#/components/responses/Problem' }
71
+ '409': { $ref: '#/components/responses/Problem' }
72
+ /workspaces/{workspaceId}/summary:
73
+ get:
74
+ operationId: getWorkspaceSummary
75
+ description: Return a bounded Git/project summary without activating the workspace Runtime.
76
+ parameters:
77
+ - $ref: '#/components/parameters/WorkspaceId'
78
+ - $ref: '#/components/parameters/ContextWorkspaceId'
79
+ - $ref: '#/components/parameters/ExpectedContextRevision'
80
+ responses:
81
+ '200':
82
+ description: Repository facts for one registered workspace.
83
+ content:
84
+ application/json:
85
+ schema: { $ref: '#/components/schemas/WorkspaceProjectSummary' }
86
+ '400': { $ref: '#/components/responses/Problem' }
87
+ '404': { $ref: '#/components/responses/Problem' }
88
+ '409': { $ref: '#/components/responses/ContextConflict' }
89
+ /workspaces/{workspaceId}/pin:
90
+ post:
91
+ operationId: setWorkspacePinned
92
+ description: Pin or unpin a registered workspace through the process idempotency ledger.
93
+ security: [{ webNonce: [] }]
94
+ parameters:
95
+ - $ref: '#/components/parameters/WorkspaceId'
96
+ requestBody:
97
+ required: true
98
+ content:
99
+ application/json:
100
+ schema: { $ref: '#/components/schemas/WorkspacePinRequest' }
101
+ responses:
102
+ '200':
103
+ description: Updated workspace summary, or an exact requestId replay.
104
+ content:
105
+ application/json:
106
+ schema: { $ref: '#/components/schemas/WorkspacePinResult' }
107
+ '400': { $ref: '#/components/responses/Problem' }
108
+ '403': { $ref: '#/components/responses/Problem' }
109
+ '404': { $ref: '#/components/responses/Problem' }
110
+ '409': { $ref: '#/components/responses/Problem' }
111
+ /workspaces/{workspaceId}:
112
+ delete:
113
+ operationId: removeWorkspace
114
+ description: >-
115
+ Remove an inactive registry entry. Session/Thread data and files are not deleted; the
116
+ active workspace cannot be removed.
117
+ security: [{ webNonce: [] }]
118
+ parameters:
119
+ - $ref: '#/components/parameters/WorkspaceId'
120
+ requestBody:
121
+ required: true
122
+ content:
123
+ application/json:
124
+ schema: { $ref: '#/components/schemas/WorkspaceRemoveRequest' }
125
+ responses:
126
+ '200':
127
+ description: Registry entry removed, or an exact requestId replay.
128
+ content:
129
+ application/json:
130
+ schema: { $ref: '#/components/schemas/WorkspaceRemoveResult' }
131
+ '400': { $ref: '#/components/responses/Problem' }
132
+ '403': { $ref: '#/components/responses/Problem' }
133
+ '404': { $ref: '#/components/responses/Problem' }
134
+ '409': { $ref: '#/components/responses/Problem' }
135
+ /context/activate:
136
+ post:
137
+ operationId: activateContext
138
+ description: >-
139
+ Atomically switch workspace and optional Session under expectedContextRevision. Failure
140
+ leaves the previous context authoritative; success returns a complete bootstrap.
141
+ security: [{ webNonce: [] }]
142
+ requestBody:
143
+ required: true
144
+ content:
145
+ application/json:
146
+ schema: { $ref: '#/components/schemas/ContextActivateRequest' }
147
+ responses:
148
+ '200':
149
+ description: New atomic context, or an exact requestId replay.
150
+ content:
151
+ application/json:
152
+ schema: { $ref: '#/components/schemas/ContextMutationResult' }
153
+ '400': { $ref: '#/components/responses/Problem' }
154
+ '403': { $ref: '#/components/responses/Problem' }
155
+ '404': { $ref: '#/components/responses/Problem' }
156
+ '409': { $ref: '#/components/responses/Problem' }
157
+ /workspaces/activate:
158
+ post:
159
+ operationId: activateWorkspace
160
+ description: Select a canonical workspace after draining the previous runtime owner.
161
+ security: [{ webNonce: [] }]
162
+ requestBody:
163
+ required: true
164
+ content:
165
+ application/json:
166
+ schema:
167
+ $ref: '#/components/schemas/ActivateWorkspaceRequest'
168
+ responses:
169
+ '200':
170
+ description: Workspace selected, or an exact requestId retry replayed.
171
+ content:
172
+ application/json:
173
+ schema:
174
+ $ref: '#/components/schemas/WorkspaceMutationResult'
175
+ '400': { $ref: '#/components/responses/Problem' }
176
+ '403': { $ref: '#/components/responses/Problem' }
177
+ '409': { $ref: '#/components/responses/Problem' }
178
+ /sessions:
179
+ get:
180
+ operationId: listSessions
181
+ description: Cursor-paged sessions whose canonical project is the active workspace.
182
+ parameters:
183
+ - $ref: '#/components/parameters/ContextWorkspaceId'
184
+ - $ref: '#/components/parameters/ExpectedContextRevision'
185
+ - $ref: '#/components/parameters/CollectionCursor'
186
+ - $ref: '#/components/parameters/PageSize'
187
+ responses:
188
+ '200':
189
+ description: One bounded session page.
190
+ content:
191
+ application/json:
192
+ schema:
193
+ $ref: '#/components/schemas/SessionPage'
194
+ '400': { $ref: '#/components/responses/Problem' }
195
+ '409': { $ref: '#/components/responses/Problem' }
196
+ post:
197
+ operationId: createSession
198
+ security: [{ webNonce: [] }]
199
+ requestBody:
200
+ required: true
201
+ content:
202
+ application/json:
203
+ schema:
204
+ $ref: '#/components/schemas/CreateSessionRequest'
205
+ responses:
206
+ '201':
207
+ description: New active session, or an exact requestId retry replayed.
208
+ content:
209
+ application/json:
210
+ schema:
211
+ $ref: '#/components/schemas/SessionMutationResult'
212
+ '400': { $ref: '#/components/responses/Problem' }
213
+ '403': { $ref: '#/components/responses/Problem' }
214
+ '409': { $ref: '#/components/responses/Problem' }
215
+ /sessions/{sessionId}:
216
+ patch:
217
+ operationId: renameSession
218
+ security: [{ webNonce: [] }]
219
+ parameters:
220
+ - $ref: '#/components/parameters/SessionId'
221
+ requestBody:
222
+ required: true
223
+ content:
224
+ application/json:
225
+ schema:
226
+ $ref: '#/components/schemas/RenameSessionRequest'
227
+ responses:
228
+ '200':
229
+ description: Updated session, or an exact requestId retry replayed.
230
+ content:
231
+ application/json:
232
+ schema:
233
+ $ref: '#/components/schemas/SessionMutationResult'
234
+ '400': { $ref: '#/components/responses/Problem' }
235
+ '403': { $ref: '#/components/responses/Problem' }
236
+ '404': { $ref: '#/components/responses/Problem' }
237
+ '409': { $ref: '#/components/responses/Problem' }
238
+ /sessions/{sessionId}/activate:
239
+ post:
240
+ operationId: activateSession
241
+ description: Select and restore a session after draining the previous runtime owner.
242
+ security: [{ webNonce: [] }]
243
+ parameters:
244
+ - $ref: '#/components/parameters/SessionId'
245
+ requestBody:
246
+ required: true
247
+ content:
248
+ application/json:
249
+ schema:
250
+ $ref: '#/components/schemas/ContextGuardRequest'
251
+ responses:
252
+ '200':
253
+ description: Session selected, or an exact requestId retry replayed.
254
+ content:
255
+ application/json:
256
+ schema:
257
+ $ref: '#/components/schemas/CommandResult'
258
+ '400': { $ref: '#/components/responses/Problem' }
259
+ '403': { $ref: '#/components/responses/Problem' }
260
+ '404': { $ref: '#/components/responses/Problem' }
261
+ '409': { $ref: '#/components/responses/Problem' }
262
+ /sessions/{sessionId}/snapshot:
263
+ get:
264
+ operationId: getSessionSnapshot
265
+ description: >-
266
+ Recovery snapshot for one session. Transcript items are cursor-paged; `threadCursor`
267
+ identifies the durable Thread projection edge and the independent `eventCursor` resumes
268
+ `/events`. Pending approvals are projected here and remain pending across refresh, network
269
+ loss and tab closure.
270
+ parameters:
271
+ - $ref: '#/components/parameters/SessionId'
272
+ - $ref: '#/components/parameters/ContextWorkspaceId'
273
+ - $ref: '#/components/parameters/ExpectedContextRevision'
274
+ - $ref: '#/components/parameters/TranscriptCursor'
275
+ - $ref: '#/components/parameters/PageSize'
276
+ responses:
277
+ '200':
278
+ description: Sanitized recovery state from durable runtime sources.
279
+ content:
280
+ application/json:
281
+ schema:
282
+ $ref: '#/components/schemas/SessionSnapshot'
283
+ '400': { $ref: '#/components/responses/Problem' }
284
+ '404': { $ref: '#/components/responses/Problem' }
285
+ '409': { $ref: '#/components/responses/Problem' }
286
+ /files:
287
+ get:
288
+ operationId: listFiles
289
+ description: >-
290
+ Lazily list one active-workspace directory by opaque node id. The cursor binds the parent
291
+ id and file revision; paths outside the canonical workspace and symlink escapes fail closed.
292
+ parameters:
293
+ - $ref: '#/components/parameters/ContextWorkspaceId'
294
+ - $ref: '#/components/parameters/ExpectedContextRevision'
295
+ - $ref: '#/components/parameters/ParentFileId'
296
+ - $ref: '#/components/parameters/ResourceCursor'
297
+ - $ref: '#/components/parameters/PageSize'
298
+ responses:
299
+ '200':
300
+ description: One bounded directory page with no absolute filesystem paths.
301
+ content:
302
+ application/json:
303
+ schema: { $ref: '#/components/schemas/FileTreePage' }
304
+ '400': { $ref: '#/components/responses/Problem' }
305
+ '403': { $ref: '#/components/responses/Problem' }
306
+ '404': { $ref: '#/components/responses/Problem' }
307
+ '409': { $ref: '#/components/responses/Problem' }
308
+ /files/{fileId}/content:
309
+ get:
310
+ operationId: getFileContent
311
+ description: >-
312
+ Read one bounded UTF-8 page from a non-sensitive regular file. Binary files return metadata
313
+ only. The continuation is bound to the file revision and byte boundary.
314
+ parameters:
315
+ - $ref: '#/components/parameters/FileId'
316
+ - $ref: '#/components/parameters/ContextWorkspaceId'
317
+ - $ref: '#/components/parameters/ExpectedContextRevision'
318
+ - $ref: '#/components/parameters/ResourceCursor'
319
+ - $ref: '#/components/parameters/FileLimitBytes'
320
+ responses:
321
+ '200':
322
+ description: One redacted text page or binary metadata.
323
+ content:
324
+ application/json:
325
+ schema: { $ref: '#/components/schemas/FileContentPage' }
326
+ '400': { $ref: '#/components/responses/Problem' }
327
+ '403': { $ref: '#/components/responses/Problem' }
328
+ '404': { $ref: '#/components/responses/Problem' }
329
+ '409': { $ref: '#/components/responses/Problem' }
330
+ '415': { $ref: '#/components/responses/Problem' }
331
+ /git/status:
332
+ get:
333
+ operationId: getGitStatus
334
+ description: >-
335
+ Return bounded, argv-only Git facts for the active workspace. The opaque cursor binds the
336
+ repository revision and record offset; it never carries credentials or raw .git content.
337
+ parameters:
338
+ - $ref: '#/components/parameters/ContextWorkspaceId'
339
+ - $ref: '#/components/parameters/ExpectedContextRevision'
340
+ - $ref: '#/components/parameters/ResourceCursor'
341
+ - $ref: '#/components/parameters/GitStatusPageSize'
342
+ responses:
343
+ '200':
344
+ description: Grouped clean/staged/unstaged/untracked/conflicted repository state.
345
+ content:
346
+ application/json:
347
+ schema: { $ref: '#/components/schemas/GitStatus' }
348
+ '400': { $ref: '#/components/responses/Problem' }
349
+ '409': { $ref: '#/components/responses/Problem' }
350
+ '503': { $ref: '#/components/responses/Problem' }
351
+ /git/log:
352
+ get:
353
+ operationId: getGitLog
354
+ description: Return one sanitized commit page bound to the current repository revision.
355
+ parameters:
356
+ - $ref: '#/components/parameters/ContextWorkspaceId'
357
+ - $ref: '#/components/parameters/ExpectedContextRevision'
358
+ - $ref: '#/components/parameters/ResourceCursor'
359
+ - $ref: '#/components/parameters/GitLogPageSize'
360
+ responses:
361
+ '200':
362
+ description: One bounded Git history page.
363
+ content:
364
+ application/json:
365
+ schema: { $ref: '#/components/schemas/GitLogPage' }
366
+ '400': { $ref: '#/components/responses/Problem' }
367
+ '409': { $ref: '#/components/responses/Problem' }
368
+ '503': { $ref: '#/components/responses/Problem' }
369
+ /git/diff/{fileId}:
370
+ get:
371
+ operationId: getGitDiff
372
+ description: >-
373
+ Return bounded redacted diff lines for an opaque file id. Continuations bind file identity,
374
+ repository revision and page boundary; binary data is never emitted.
375
+ parameters:
376
+ - $ref: '#/components/parameters/FileId'
377
+ - $ref: '#/components/parameters/ContextWorkspaceId'
378
+ - $ref: '#/components/parameters/ExpectedContextRevision'
379
+ - $ref: '#/components/parameters/ResourceCursor'
380
+ - $ref: '#/components/parameters/DiffLineLimit'
381
+ - $ref: '#/components/parameters/DiffByteLimit'
382
+ responses:
383
+ '200':
384
+ description: One revision-bound diff page.
385
+ content:
386
+ application/json:
387
+ schema: { $ref: '#/components/schemas/GitDiffPage' }
388
+ '400': { $ref: '#/components/responses/Problem' }
389
+ '404': { $ref: '#/components/responses/Problem' }
390
+ '409': { $ref: '#/components/responses/Problem' }
391
+ '503': { $ref: '#/components/responses/Problem' }
392
+ /review:
393
+ get:
394
+ operationId: getReview
395
+ description: >-
396
+ Compose a read-only review summary from Git facts and durable tool-detail metadata. Sending
397
+ selected diff text to Composer is a client action; this endpoint never edits files.
398
+ parameters:
399
+ - $ref: '#/components/parameters/ContextWorkspaceId'
400
+ - $ref: '#/components/parameters/ExpectedContextRevision'
401
+ responses:
402
+ '200':
403
+ description: Revisioned change-set and verification metadata.
404
+ content:
405
+ application/json:
406
+ schema: { $ref: '#/components/schemas/ReviewSnapshot' }
407
+ '409': { $ref: '#/components/responses/Problem' }
408
+ '503': { $ref: '#/components/responses/Problem' }
409
+ /terminals:
410
+ get:
411
+ operationId: listTerminals
412
+ description: List only ephemeral terminals owned by the active workspace.
413
+ parameters:
414
+ - $ref: '#/components/parameters/ContextWorkspaceId'
415
+ - $ref: '#/components/parameters/ExpectedContextRevision'
416
+ - $ref: '#/components/parameters/CollectionCursor'
417
+ - $ref: '#/components/parameters/PageSize'
418
+ responses:
419
+ '200':
420
+ description: One bounded terminal metadata page; no terminal output is included.
421
+ content:
422
+ application/json:
423
+ schema: { $ref: '#/components/schemas/TerminalPage' }
424
+ '400': { $ref: '#/components/responses/Problem' }
425
+ '409': { $ref: '#/components/responses/Problem' }
426
+ post:
427
+ operationId: createTerminal
428
+ description: >-
429
+ Create a real PTY only after an explicit user gesture. The single-use attach ticket is
430
+ short-lived and must never be logged, persisted, placed in a URL, or sent on SSE.
431
+ security: [{ webNonce: [], terminalUserGesture: [] }]
432
+ requestBody:
433
+ required: true
434
+ content:
435
+ application/json:
436
+ schema: { $ref: '#/components/schemas/TerminalCreateRequest' }
437
+ responses:
438
+ '201':
439
+ description: Terminal metadata plus one short-lived single-use ticket.
440
+ content:
441
+ application/json:
442
+ schema: { $ref: '#/components/schemas/TerminalCreateMutationResult' }
443
+ '400': { $ref: '#/components/responses/Problem' }
444
+ '403': { $ref: '#/components/responses/Problem' }
445
+ '409': { $ref: '#/components/responses/Problem' }
446
+ '503': { $ref: '#/components/responses/Problem' }
447
+ /terminals/{terminalId}/attach-ticket:
448
+ post:
449
+ operationId: issueTerminalAttachTicket
450
+ description: Replace any unused ticket with a new single-use, short-lived attach ticket.
451
+ security: [{ webNonce: [] }]
452
+ parameters:
453
+ - $ref: '#/components/parameters/TerminalId'
454
+ requestBody:
455
+ required: true
456
+ content:
457
+ application/json:
458
+ schema: { $ref: '#/components/schemas/ContextGuardRequest' }
459
+ responses:
460
+ '200':
461
+ description: Fresh attach ticket, or an exact requestId replay.
462
+ content:
463
+ application/json:
464
+ schema: { $ref: '#/components/schemas/TerminalTicketMutationResult' }
465
+ '400': { $ref: '#/components/responses/Problem' }
466
+ '403': { $ref: '#/components/responses/Problem' }
467
+ '404': { $ref: '#/components/responses/Problem' }
468
+ '409': { $ref: '#/components/responses/Problem' }
469
+ /terminals/{terminalId}:
470
+ delete:
471
+ operationId: closeTerminal
472
+ description: Terminate the PTY process tree and invalidate outstanding attach tickets.
473
+ security: [{ webNonce: [] }]
474
+ parameters:
475
+ - $ref: '#/components/parameters/TerminalId'
476
+ requestBody:
477
+ required: true
478
+ content:
479
+ application/json:
480
+ schema: { $ref: '#/components/schemas/ContextGuardRequest' }
481
+ responses:
482
+ '200':
483
+ description: Closed terminal metadata, or an exact requestId replay.
484
+ content:
485
+ application/json:
486
+ schema: { $ref: '#/components/schemas/TerminalCloseMutationResult' }
487
+ '400': { $ref: '#/components/responses/Problem' }
488
+ '403': { $ref: '#/components/responses/Problem' }
489
+ '404': { $ref: '#/components/responses/Problem' }
490
+ '409': { $ref: '#/components/responses/Problem' }
491
+ /terminals/{terminalId}/stream:
492
+ get:
493
+ operationId: streamTerminal
494
+ description: >-
495
+ WebSocket upgrade only; HTTP success bodies are not used. The client offers subprotocol
496
+ `orion-terminal-v1`, then sends Authenticate as its first JSON message within five seconds.
497
+ The ticket stays in the message body, never in the URL. Terminal output is non-durable and
498
+ isolated from the Workbench SSE cursor.
499
+ parameters:
500
+ - $ref: '#/components/parameters/TerminalId'
501
+ x-orion-websocket:
502
+ subprotocol: orion-terminal-v1
503
+ firstClientMessage: '#/components/schemas/TerminalAuthenticateMessage'
504
+ clientMessages: '#/components/schemas/TerminalClientMessage'
505
+ serverMessages: '#/components/schemas/TerminalServerMessage'
506
+ closeCodes: [1000, 1001, 4400, 4401, 4403, 4409, 4413]
507
+ responses:
508
+ '101':
509
+ description: Switching Protocols to the terminal WebSocket.
510
+ '400': { $ref: '#/components/responses/Problem' }
511
+ '403': { $ref: '#/components/responses/Problem' }
512
+ '404': { $ref: '#/components/responses/Problem' }
513
+ /tool-details:
514
+ get:
515
+ operationId: listToolDetails
516
+ description: >-
517
+ Cursor-paged safe summaries from the active workspace's project artifact repository.
518
+ Current artifact metadata has no session identity, so this route is deliberately
519
+ workspace/project-scoped and must not be presented as proof that an artifact belongs to a
520
+ particular session.
521
+ parameters:
522
+ - $ref: '#/components/parameters/ContextWorkspaceId'
523
+ - $ref: '#/components/parameters/ExpectedContextRevision'
524
+ - $ref: '#/components/parameters/CollectionCursor'
525
+ - $ref: '#/components/parameters/PageSize'
526
+ responses:
527
+ '200':
528
+ description: One bounded tool-detail summary page.
529
+ content:
530
+ application/json:
531
+ schema:
532
+ $ref: '#/components/schemas/ToolDetailSummaryPage'
533
+ '400': { $ref: '#/components/responses/Problem' }
534
+ '404': { $ref: '#/components/responses/Problem' }
535
+ '409': { $ref: '#/components/responses/Problem' }
536
+ /tool-details/{callId}:
537
+ get:
538
+ operationId: getToolDetail
539
+ description: >-
540
+ Byte-paged output from a pre-sanitized derivative resolved only from the active workspace's
541
+ artifact list. `offsetBytes` addresses derivative bytes, never raw tool-output bytes, so a
542
+ caller cannot bypass redaction by choosing a sensitive-field boundary. The current artifact
543
+ metadata cannot prove session ownership; the host returns no artifact filesystem path and
544
+ makes no session-attribution claim.
545
+ parameters:
546
+ - $ref: '#/components/parameters/CallId'
547
+ - $ref: '#/components/parameters/ContextWorkspaceId'
548
+ - $ref: '#/components/parameters/ExpectedContextRevision'
549
+ - $ref: '#/components/parameters/OffsetBytes'
550
+ - $ref: '#/components/parameters/LimitBytes'
551
+ responses:
552
+ '200':
553
+ description: One UTF-8-safe redacted output page.
554
+ content:
555
+ application/json:
556
+ schema:
557
+ $ref: '#/components/schemas/ToolDetailPage'
558
+ '400': { $ref: '#/components/responses/Problem' }
559
+ '404': { $ref: '#/components/responses/Problem' }
560
+ '409': { $ref: '#/components/responses/ContextConflict' }
561
+ /skills:
562
+ get:
563
+ operationId: listSkills
564
+ description: >-
565
+ Cursor-paged safe Skill descriptors. Bodies, resource paths and trigger implementations are
566
+ excluded.
567
+ parameters:
568
+ - $ref: '#/components/parameters/ContextWorkspaceId'
569
+ - $ref: '#/components/parameters/ExpectedContextRevision'
570
+ - $ref: '#/components/parameters/CollectionCursor'
571
+ - $ref: '#/components/parameters/PageSize'
572
+ responses:
573
+ '200':
574
+ description: One bounded Skill descriptor page.
575
+ content:
576
+ application/json:
577
+ schema:
578
+ $ref: '#/components/schemas/SkillPage'
579
+ '400': { $ref: '#/components/responses/Problem' }
580
+ '409': { $ref: '#/components/responses/Problem' }
581
+ /mcp:
582
+ get:
583
+ operationId: listMcpServers
584
+ description: >-
585
+ Cursor-paged safe MCP catalog/runtime summaries. Commands, endpoints, headers and
586
+ credentials are excluded and this read never activates a dormant server.
587
+ parameters:
588
+ - $ref: '#/components/parameters/ContextWorkspaceId'
589
+ - $ref: '#/components/parameters/ExpectedContextRevision'
590
+ - $ref: '#/components/parameters/CollectionCursor'
591
+ - $ref: '#/components/parameters/PageSize'
592
+ responses:
593
+ '200':
594
+ description: One bounded MCP summary page.
595
+ content:
596
+ application/json:
597
+ schema:
598
+ $ref: '#/components/schemas/McpPage'
599
+ '400': { $ref: '#/components/responses/Problem' }
600
+ '409': { $ref: '#/components/responses/Problem' }
601
+ /commands:
602
+ post:
603
+ operationId: dispatchCommand
604
+ description: >-
605
+ Dispatch a renderer-neutral runtime mutation. Approval decisions allow only once, project
606
+ or global scope. Interrupt and shutdown paths deny affected unresolved approvals and fail
607
+ their waiting tool calls closed.
608
+ security: [{ webNonce: [] }]
609
+ requestBody:
610
+ required: true
611
+ content:
612
+ application/json:
613
+ schema:
614
+ $ref: '#/components/schemas/WebCommand'
615
+ responses:
616
+ '202':
617
+ description: Accepted command, or an exact requestId retry replayed.
618
+ content:
619
+ application/json:
620
+ schema:
621
+ $ref: '#/components/schemas/CommandResult'
622
+ '400': { $ref: '#/components/responses/Problem' }
623
+ '403': { $ref: '#/components/responses/Problem' }
624
+ '409': { $ref: '#/components/responses/Problem' }
625
+ /events:
626
+ get:
627
+ operationId: streamEvents
628
+ description: >-
629
+ One Server-Sent Events downlink. `cursor` or `Last-Event-ID` is the last delivered durable
630
+ sequence; the query value wins when both are present. Each SSE `id` is the decimal cursor,
631
+ while the JSON envelope also carries a UUID `eventId`. Disconnecting this stream does not
632
+ resolve or deny pending approvals.
633
+ parameters:
634
+ - $ref: '#/components/parameters/EventCursor'
635
+ - $ref: '#/components/parameters/LastEventId'
636
+ responses:
637
+ '200':
638
+ description: text/event-stream of discriminated WebEventEnvelope values.
639
+ content:
640
+ text/event-stream:
641
+ schema:
642
+ $ref: '#/components/schemas/WebEventEnvelope'
643
+ '400': { $ref: '#/components/responses/Problem' }
644
+ '409': { $ref: '#/components/responses/Problem' }
645
+ /diagnostics:
646
+ get:
647
+ operationId: getDiagnostics
648
+ parameters:
649
+ - $ref: '#/components/parameters/ContextWorkspaceId'
650
+ - $ref: '#/components/parameters/ExpectedContextRevision'
651
+ responses:
652
+ '200':
653
+ description: Sanitized runtime and harness diagnostics.
654
+ content:
655
+ application/json:
656
+ schema:
657
+ type: object
658
+ properties:
659
+ performance: { $ref: '#/components/schemas/WebPerformanceCounters' }
660
+ additionalProperties: true
661
+ '409': { $ref: '#/components/responses/ContextConflict' }
662
+ /settings:
663
+ get:
664
+ operationId: getSettings
665
+ responses:
666
+ '200':
667
+ description: Current secret-free, source-aware Settings document and durable revision.
668
+ content:
669
+ application/json:
670
+ schema:
671
+ $ref: '#/components/schemas/SettingsDocument'
672
+ patch:
673
+ operationId: updateSettings
674
+ description: >-
675
+ Atomically apply one bounded batch only when `expectedRevision` equals the keyed revision of
676
+ the exact current orion.json bytes. Duplicate keys and partial commits are rejected.
677
+ security: [{ webNonce: [] }]
678
+ requestBody:
679
+ required: true
680
+ content:
681
+ application/json:
682
+ schema:
683
+ $ref: '#/components/schemas/UpdateSettingsRequest'
684
+ responses:
685
+ '200':
686
+ description: Updated settings, or an exact requestId retry replayed.
687
+ content:
688
+ application/json:
689
+ schema:
690
+ $ref: '#/components/schemas/SettingsMutationResult'
691
+ '400': { $ref: '#/components/responses/Problem' }
692
+ '403': { $ref: '#/components/responses/Problem' }
693
+ '409':
694
+ description: requestId/body conflict, stale expectedRevision, or busy Runtime; no field was applied.
695
+ content:
696
+ application/problem+json:
697
+ schema:
698
+ $ref: '#/components/schemas/Problem'
699
+ '422': { $ref: '#/components/responses/Problem' }
700
+ '503': { $ref: '#/components/responses/Problem' }
701
+ /settings/open-document:
702
+ post:
703
+ operationId: openSettingsDocument
704
+ description: >-
705
+ Open the Host-resolved orion.json in the native text editor. This loopback-only action accepts
706
+ no path and never returns the resolved filesystem path.
707
+ security: [{ webNonce: [] }]
708
+ requestBody:
709
+ required: true
710
+ content:
711
+ application/json:
712
+ schema:
713
+ type: object
714
+ additionalProperties: false
715
+ required: [requestId]
716
+ properties:
717
+ requestId: { $ref: '#/components/schemas/RequestId' }
718
+ responses:
719
+ '200':
720
+ description: The pathless open request was accepted or replayed idempotently.
721
+ content:
722
+ application/json:
723
+ schema:
724
+ type: object
725
+ additionalProperties: false
726
+ required: [requestId, opened]
727
+ properties:
728
+ requestId: { $ref: '#/components/schemas/RequestId' }
729
+ opened: { type: boolean, const: true }
730
+ '400': { $ref: '#/components/responses/Problem' }
731
+ '403': { $ref: '#/components/responses/Problem' }
732
+ '409': { $ref: '#/components/responses/Problem' }
733
+ '503': { $ref: '#/components/responses/Problem' }
734
+ components:
735
+ securitySchemes:
736
+ webNonce:
737
+ type: apiKey
738
+ in: header
739
+ name: X-Orion-Web-Nonce
740
+ description: Per-process secret returned only by same-origin bootstrap and required on mutations.
741
+ terminalUserGesture:
742
+ type: apiKey
743
+ in: header
744
+ name: X-Orion-User-Gesture
745
+ description: Terminal creation requires the exact value terminal-create-v1 from a user gesture.
746
+ parameters:
747
+ ContextWorkspaceId:
748
+ in: query
749
+ name: workspaceId
750
+ required: true
751
+ description: >-
752
+ UUID of the active workspace observed with expectedContextRevision. A mismatch returns 409
753
+ context_revision_conflict and the Host performs no activation, read, spawn, or mutation.
754
+ schema: { type: string, format: uuid }
755
+ ExpectedContextRevision:
756
+ in: query
757
+ name: expectedContextRevision
758
+ required: true
759
+ description: >-
760
+ ContextRevision from bootstrap or the last successful atomic activation. A stale value
761
+ returns 409 context_revision_conflict with zero side effects.
762
+ schema: { $ref: '#/components/schemas/ContextRevision' }
763
+ WorkspaceId:
764
+ in: path
765
+ name: workspaceId
766
+ required: true
767
+ schema: { type: string, format: uuid }
768
+ SessionId:
769
+ in: path
770
+ name: sessionId
771
+ required: true
772
+ schema: { type: string, minLength: 1, maxLength: 256 }
773
+ FileId:
774
+ in: path
775
+ name: fileId
776
+ required: true
777
+ description: Opaque active-workspace file identity; never a client-supplied path.
778
+ schema: { type: string, minLength: 1, maxLength: 256 }
779
+ ParentFileId:
780
+ in: query
781
+ name: parentId
782
+ required: false
783
+ description: Opaque directory identity; omission selects the active-workspace root.
784
+ schema: { type: string, minLength: 1, maxLength: 256 }
785
+ TerminalId:
786
+ in: path
787
+ name: terminalId
788
+ required: true
789
+ schema: { type: string, format: uuid }
790
+ CallId:
791
+ in: path
792
+ name: callId
793
+ required: true
794
+ description: >-
795
+ Opaque identifier returned by the active workspace's tool-detail summary. The current file
796
+ repository aliases callId to its project artifact identifier.
797
+ schema: { type: string, minLength: 1, maxLength: 256 }
798
+ CollectionCursor:
799
+ in: query
800
+ name: cursor
801
+ required: false
802
+ description: >-
803
+ Opaque continuation returned by the preceding page. It binds the route scope, the complete
804
+ ordered collection revision and the last stable item key. Any insertion, deletion or
805
+ reorder makes it stale; the Host returns 409 collection_cursor_stale and the client restarts
806
+ from the first page.
807
+ schema: { type: string, minLength: 1, maxLength: 512 }
808
+ TranscriptCursor:
809
+ in: query
810
+ name: cursor
811
+ required: false
812
+ description: >-
813
+ Opaque backward-page continuation bound to the Session's Thread identity, immutable
814
+ transcript-manifest revision and page boundary. A newer Thread revision returns 409
815
+ transcript_cursor_stale; the client must recover a fresh tail snapshot before paging again.
816
+ schema: { type: string, minLength: 1, maxLength: 512 }
817
+ ResourceCursor:
818
+ in: query
819
+ name: cursor
820
+ required: false
821
+ description: >-
822
+ Opaque continuation bound to the active workspace, resource identity, resource revision and
823
+ page boundary. A stale or cross-resource value returns 409 and must be restarted from the
824
+ first page; the value is not an encoded filesystem path.
825
+ schema: { type: string, minLength: 1, maxLength: 4096 }
826
+ PageSize:
827
+ in: query
828
+ name: pageSize
829
+ required: false
830
+ schema: { type: integer, minimum: 1, maximum: 100, default: 50 }
831
+ OffsetBytes:
832
+ in: query
833
+ name: offsetBytes
834
+ required: false
835
+ schema: { type: integer, minimum: 0, default: 0 }
836
+ LimitBytes:
837
+ in: query
838
+ name: limitBytes
839
+ required: false
840
+ schema: { type: integer, minimum: 1, maximum: 1048576, default: 65536 }
841
+ FileLimitBytes:
842
+ in: query
843
+ name: limitBytes
844
+ required: false
845
+ schema: { type: integer, minimum: 1, maximum: 262144, default: 65536 }
846
+ GitStatusPageSize:
847
+ in: query
848
+ name: pageSize
849
+ required: false
850
+ schema: { type: integer, minimum: 1, maximum: 2000, default: 200 }
851
+ GitLogPageSize:
852
+ in: query
853
+ name: pageSize
854
+ required: false
855
+ schema: { type: integer, minimum: 1, maximum: 100, default: 30 }
856
+ DiffLineLimit:
857
+ in: query
858
+ name: lineLimit
859
+ required: false
860
+ schema: { type: integer, minimum: 1, maximum: 500, default: 240 }
861
+ DiffByteLimit:
862
+ in: query
863
+ name: byteLimit
864
+ required: false
865
+ schema: { type: integer, minimum: 1024, maximum: 1048576, default: 262144 }
866
+ EventCursor:
867
+ in: query
868
+ name: cursor
869
+ required: false
870
+ description: Last durable Web event cursor accepted by the client.
871
+ schema: { type: integer, minimum: 0, default: 0 }
872
+ LastEventId:
873
+ in: header
874
+ name: Last-Event-ID
875
+ required: false
876
+ description: Browser-provided fallback for the last durable Web event cursor.
877
+ schema: { type: string, pattern: '^[0-9]+$' }
878
+ responses:
879
+ Problem:
880
+ description: Safe structured error with no secret-bearing data.
881
+ content:
882
+ application/problem+json:
883
+ schema:
884
+ $ref: '#/components/schemas/Problem'
885
+ ContextConflict:
886
+ description: >-
887
+ workspaceId or expectedContextRevision is stale. The Host returns
888
+ context_revision_conflict and performs zero reads from another workspace and zero side
889
+ effects.
890
+ content:
891
+ application/problem+json:
892
+ schema: { $ref: '#/components/schemas/Problem' }
893
+ example:
894
+ type: https://orioncode.dev/problems/context_revision_conflict
895
+ title: State conflict
896
+ status: 409
897
+ code: context_revision_conflict
898
+ detail: The active Context changed before the request was admitted.
899
+ schemas:
900
+ WebPerformanceCounters:
901
+ type: object
902
+ additionalProperties: false
903
+ required: [files, git]
904
+ properties:
905
+ files:
906
+ type: object
907
+ additionalProperties: false
908
+ required: [readOperations, bytesRead, itemsParsed]
909
+ properties:
910
+ readOperations: { type: integer, minimum: 0 }
911
+ bytesRead: { type: integer, minimum: 0 }
912
+ itemsParsed: { type: integer, minimum: 0 }
913
+ git:
914
+ type: object
915
+ additionalProperties: false
916
+ required: [processCount, bytesRead, itemsParsed]
917
+ properties:
918
+ processCount: { type: integer, minimum: 0 }
919
+ bytesRead: { type: integer, minimum: 0 }
920
+ itemsParsed: { type: integer, minimum: 0 }
921
+ HealthResponse:
922
+ type: object
923
+ additionalProperties: false
924
+ required: [ok, version]
925
+ properties:
926
+ ok: { type: boolean, const: true }
927
+ version: { type: string }
928
+ BootstrapResponse:
929
+ type: object
930
+ additionalProperties: false
931
+ required:
932
+ - apiVersion
933
+ - productVersion
934
+ - nonce
935
+ - contextRevision
936
+ - workspaceId
937
+ - workspace
938
+ - configured
939
+ - activeSessionId
940
+ - settings
941
+ - capabilities
942
+ properties:
943
+ apiVersion: { type: integer, const: 1 }
944
+ productVersion: { type: string }
945
+ nonce: { type: string, minLength: 32 }
946
+ contextRevision: { type: string, format: uuid }
947
+ workspaceId: { type: string, format: uuid }
948
+ workspace: { type: string }
949
+ configured: { type: boolean }
950
+ activeSessionId: { type: [string, 'null'] }
951
+ settings: { $ref: '#/components/schemas/SettingsDocument' }
952
+ capabilities:
953
+ type: object
954
+ additionalProperties: false
955
+ required: [goal, plan, skills, mcp, diagnostics, review, files, git, terminal]
956
+ properties:
957
+ goal: { type: boolean }
958
+ plan: { type: boolean }
959
+ skills: { type: boolean }
960
+ mcp: { type: boolean }
961
+ diagnostics: { type: boolean }
962
+ review: { type: boolean, const: true }
963
+ files: { type: boolean, const: true }
964
+ git: { type: boolean, const: true }
965
+ terminal: { type: boolean }
966
+ MutationRequest:
967
+ type: object
968
+ additionalProperties: false
969
+ required: [requestId]
970
+ properties:
971
+ requestId: { $ref: '#/components/schemas/RequestId' }
972
+ RequestId:
973
+ type: string
974
+ format: uuid
975
+ description: >-
976
+ Client-generated idempotency key. Reuse is valid only for a byte-equivalent normalized
977
+ mutation body.
978
+ ContextRevision:
979
+ type: string
980
+ format: uuid
981
+ description: Compare-and-swap identity for the single active Workspace/Session context.
982
+ ContextActivateRequest:
983
+ type: object
984
+ additionalProperties: false
985
+ required: [requestId, expectedContextRevision, workspaceId, sessionId]
986
+ properties:
987
+ requestId: { $ref: '#/components/schemas/RequestId' }
988
+ expectedContextRevision: { $ref: '#/components/schemas/ContextRevision' }
989
+ workspaceId: { type: string, format: uuid }
990
+ sessionId: { type: [string, 'null'] }
991
+ ContextMutationResult:
992
+ type: object
993
+ additionalProperties: false
994
+ required: [requestId, contextRevision, bootstrap]
995
+ properties:
996
+ requestId: { $ref: '#/components/schemas/RequestId' }
997
+ contextRevision: { $ref: '#/components/schemas/ContextRevision' }
998
+ bootstrap: { $ref: '#/components/schemas/BootstrapResponse' }
999
+ ActivateWorkspaceRequest:
1000
+ type: object
1001
+ additionalProperties: false
1002
+ required: [requestId, expectedContextRevision, path]
1003
+ properties:
1004
+ requestId: { $ref: '#/components/schemas/RequestId' }
1005
+ expectedContextRevision: { $ref: '#/components/schemas/ContextRevision' }
1006
+ path: { type: string, minLength: 1, maxLength: 4096 }
1007
+ CreateSessionRequest:
1008
+ type: object
1009
+ additionalProperties: false
1010
+ required: [requestId, expectedContextRevision, workspaceId]
1011
+ properties:
1012
+ requestId: { $ref: '#/components/schemas/RequestId' }
1013
+ expectedContextRevision: { $ref: '#/components/schemas/ContextRevision' }
1014
+ workspaceId: { type: string, format: uuid }
1015
+ name: { type: string, minLength: 1, maxLength: 120 }
1016
+ RenameSessionRequest:
1017
+ type: object
1018
+ additionalProperties: false
1019
+ required: [requestId, expectedContextRevision, workspaceId, name]
1020
+ properties:
1021
+ requestId: { $ref: '#/components/schemas/RequestId' }
1022
+ expectedContextRevision: { $ref: '#/components/schemas/ContextRevision' }
1023
+ workspaceId: { type: string, format: uuid }
1024
+ name: { type: string, minLength: 1, maxLength: 120 }
1025
+ WorkspaceSummary:
1026
+ type: object
1027
+ additionalProperties: false
1028
+ required: [id, path, label, active, available, sessionCount, lastActivatedAt]
1029
+ properties:
1030
+ id: { type: string, format: uuid }
1031
+ path: { type: string }
1032
+ label: { type: string }
1033
+ active: { type: boolean }
1034
+ available: { type: boolean }
1035
+ sessionCount: { type: integer, minimum: 0 }
1036
+ lastActivatedAt: { type: string, format: date-time }
1037
+ pinnedOrder: { type: integer, minimum: 0 }
1038
+ WorkspacePage:
1039
+ type: object
1040
+ additionalProperties: false
1041
+ required: [items, nextCursor]
1042
+ properties:
1043
+ items:
1044
+ type: array
1045
+ maxItems: 100
1046
+ items: { $ref: '#/components/schemas/WorkspaceSummary' }
1047
+ nextCursor: { type: [string, 'null'] }
1048
+ WorkspaceMutationResult:
1049
+ type: object
1050
+ additionalProperties: false
1051
+ required: [requestId, active, page]
1052
+ properties:
1053
+ requestId: { $ref: '#/components/schemas/RequestId' }
1054
+ active: { type: string }
1055
+ page: { $ref: '#/components/schemas/WorkspacePage' }
1056
+ WorkspaceProjectSummary:
1057
+ type: object
1058
+ additionalProperties: false
1059
+ required:
1060
+ - workspaceId
1061
+ - repositoryRevision
1062
+ - isRepository
1063
+ - branch
1064
+ - detached
1065
+ - head
1066
+ - dirtyCount
1067
+ - conflictCount
1068
+ properties:
1069
+ workspaceId: { type: string, format: uuid }
1070
+ repositoryRevision: { type: string, minLength: 1 }
1071
+ isRepository: { type: boolean }
1072
+ branch: { type: [string, 'null'] }
1073
+ detached: { type: boolean }
1074
+ head: { type: [string, 'null'] }
1075
+ dirtyCount: { type: integer, minimum: 0 }
1076
+ conflictCount: { type: integer, minimum: 0 }
1077
+ WorkspacePinRequest:
1078
+ type: object
1079
+ additionalProperties: false
1080
+ required: [requestId, expectedContextRevision, pinned]
1081
+ properties:
1082
+ requestId: { $ref: '#/components/schemas/RequestId' }
1083
+ expectedContextRevision: { $ref: '#/components/schemas/ContextRevision' }
1084
+ pinned: { type: boolean }
1085
+ WorkspacePinResult:
1086
+ type: object
1087
+ additionalProperties: false
1088
+ required: [requestId, workspace]
1089
+ properties:
1090
+ requestId: { $ref: '#/components/schemas/RequestId' }
1091
+ workspace: { $ref: '#/components/schemas/WorkspaceSummary' }
1092
+ WorkspaceRemoveRequest:
1093
+ type: object
1094
+ additionalProperties: false
1095
+ required: [requestId, expectedContextRevision]
1096
+ properties:
1097
+ requestId: { $ref: '#/components/schemas/RequestId' }
1098
+ expectedContextRevision: { $ref: '#/components/schemas/ContextRevision' }
1099
+ WorkspaceRemoveResult:
1100
+ type: object
1101
+ additionalProperties: false
1102
+ required: [requestId, removed]
1103
+ properties:
1104
+ requestId: { $ref: '#/components/schemas/RequestId' }
1105
+ removed: { type: boolean, const: true }
1106
+ SessionSummary:
1107
+ type: object
1108
+ additionalProperties: false
1109
+ required: [id, projectPath, model, createdAt, updatedAt, messageCount]
1110
+ properties:
1111
+ id: { type: string }
1112
+ projectPath: { type: string }
1113
+ name: { type: string }
1114
+ model: { type: string }
1115
+ createdAt: { type: string, format: date-time }
1116
+ updatedAt: { type: string, format: date-time }
1117
+ messageCount: { type: integer, minimum: 0 }
1118
+ taskSummary: { type: string }
1119
+ activeGoalId: { type: string }
1120
+ activeGoalObjective: { type: string }
1121
+ SessionPage:
1122
+ type: object
1123
+ additionalProperties: false
1124
+ required: [items, nextCursor]
1125
+ properties:
1126
+ items:
1127
+ type: array
1128
+ maxItems: 100
1129
+ items: { $ref: '#/components/schemas/SessionSummary' }
1130
+ nextCursor: { type: [string, 'null'] }
1131
+ SessionMutationResult:
1132
+ type: object
1133
+ additionalProperties: false
1134
+ required: [requestId, session]
1135
+ properties:
1136
+ requestId: { $ref: '#/components/schemas/RequestId' }
1137
+ session: { $ref: '#/components/schemas/SessionSummary' }
1138
+ FileNode:
1139
+ type: object
1140
+ additionalProperties: false
1141
+ required: [id, name, displayPath, kind, modifiedAt, sensitive, readable]
1142
+ properties:
1143
+ id: { type: string, minLength: 1 }
1144
+ name: { type: string, minLength: 1 }
1145
+ displayPath:
1146
+ type: string
1147
+ minLength: 1
1148
+ description: Sanitized workspace-relative display metadata; requests still use opaque id.
1149
+ kind: { type: string, enum: [file, directory, symlink] }
1150
+ sizeBytes: { type: integer, minimum: 0 }
1151
+ modifiedAt: { type: string, format: date-time }
1152
+ sensitive: { type: boolean }
1153
+ readable: { type: boolean }
1154
+ FileTreePage:
1155
+ type: object
1156
+ additionalProperties: false
1157
+ required: [parentId, revision, items, nextCursor]
1158
+ properties:
1159
+ parentId: { type: string, minLength: 1 }
1160
+ revision: { type: string, minLength: 1 }
1161
+ items:
1162
+ type: array
1163
+ maxItems: 100
1164
+ items: { $ref: '#/components/schemas/FileNode' }
1165
+ nextCursor: { type: [string, 'null'] }
1166
+ FileContentPage:
1167
+ type: object
1168
+ additionalProperties: false
1169
+ required:
1170
+ - fileId
1171
+ - name
1172
+ - revision
1173
+ - sizeBytes
1174
+ - binary
1175
+ - sensitive
1176
+ - mediaType
1177
+ - offsetBytes
1178
+ - nextCursor
1179
+ properties:
1180
+ fileId: { type: string, minLength: 1 }
1181
+ name: { type: string, minLength: 1 }
1182
+ revision: { type: string, minLength: 1 }
1183
+ sizeBytes: { type: integer, minimum: 0 }
1184
+ binary: { type: boolean }
1185
+ sensitive: { type: boolean, const: false }
1186
+ mediaType: { type: string, enum: [text/plain, application/octet-stream] }
1187
+ offsetBytes: { type: integer, minimum: 0 }
1188
+ content:
1189
+ type: string
1190
+ description: Present only for redacted UTF-8 text; omitted for binary metadata.
1191
+ nextCursor: { type: [string, 'null'] }
1192
+ GitFile:
1193
+ type: object
1194
+ additionalProperties: false
1195
+ required: [fileId, path, indexStatus, worktreeStatus]
1196
+ properties:
1197
+ fileId: { type: string, minLength: 1 }
1198
+ path:
1199
+ type: string
1200
+ description: Sanitized workspace-relative display path; requests still use fileId.
1201
+ indexStatus: { type: string, minLength: 1, maxLength: 1 }
1202
+ worktreeStatus: { type: string, minLength: 1, maxLength: 1 }
1203
+ renamedFrom: { type: string }
1204
+ GitFileList:
1205
+ type: array
1206
+ maxItems: 2000
1207
+ items: { $ref: '#/components/schemas/GitFile' }
1208
+ GitStatus:
1209
+ type: object
1210
+ additionalProperties: false
1211
+ required:
1212
+ - isRepository
1213
+ - repositoryRevision
1214
+ - branch
1215
+ - detached
1216
+ - head
1217
+ - upstream
1218
+ - ahead
1219
+ - behind
1220
+ - clean
1221
+ - staged
1222
+ - unstaged
1223
+ - untracked
1224
+ - conflicted
1225
+ - totalFiles
1226
+ - truncated
1227
+ - nextCursor
1228
+ properties:
1229
+ isRepository: { type: boolean }
1230
+ repositoryRevision: { type: string, minLength: 1 }
1231
+ rootLabel: { type: string }
1232
+ branch: { type: [string, 'null'] }
1233
+ detached: { type: boolean }
1234
+ head: { type: [string, 'null'] }
1235
+ upstream: { type: [string, 'null'] }
1236
+ ahead: { type: integer, minimum: 0 }
1237
+ behind: { type: integer, minimum: 0 }
1238
+ clean: { type: boolean }
1239
+ staged: { $ref: '#/components/schemas/GitFileList' }
1240
+ unstaged: { $ref: '#/components/schemas/GitFileList' }
1241
+ untracked: { $ref: '#/components/schemas/GitFileList' }
1242
+ conflicted: { $ref: '#/components/schemas/GitFileList' }
1243
+ totalFiles: { type: integer, minimum: 0 }
1244
+ truncated: { type: boolean }
1245
+ nextCursor: { type: [string, 'null'] }
1246
+ GitCommit:
1247
+ type: object
1248
+ additionalProperties: false
1249
+ required: [id, shortId, authoredAt, authorName, subject]
1250
+ properties:
1251
+ id: { type: string, pattern: '^[a-f0-9]{40,64}$' }
1252
+ shortId: { type: string, pattern: '^[a-f0-9]{7,16}$' }
1253
+ authoredAt: { type: string, format: date-time }
1254
+ authorName: { type: string }
1255
+ subject: { type: string }
1256
+ GitLogPage:
1257
+ type: object
1258
+ additionalProperties: false
1259
+ required: [repositoryRevision, items, nextCursor]
1260
+ properties:
1261
+ repositoryRevision: { type: string, minLength: 1 }
1262
+ items:
1263
+ type: array
1264
+ maxItems: 100
1265
+ items: { $ref: '#/components/schemas/GitCommit' }
1266
+ nextCursor: { type: [string, 'null'] }
1267
+ GitDiffPage:
1268
+ type: object
1269
+ additionalProperties: false
1270
+ required:
1271
+ - fileId
1272
+ - path
1273
+ - repositoryRevision
1274
+ - binary
1275
+ - lines
1276
+ - nextCursor
1277
+ - truncated
1278
+ properties:
1279
+ fileId: { type: string, minLength: 1 }
1280
+ path: { type: string }
1281
+ repositoryRevision: { type: string, minLength: 1 }
1282
+ binary: { type: boolean }
1283
+ lines:
1284
+ type: array
1285
+ maxItems: 500
1286
+ items: { type: string }
1287
+ nextCursor: { type: [string, 'null'] }
1288
+ truncated: { type: boolean }
1289
+ ReviewVerification:
1290
+ type: object
1291
+ additionalProperties: false
1292
+ required:
1293
+ - callId
1294
+ - sessionId
1295
+ - threadId
1296
+ - sequence
1297
+ - toolName
1298
+ - state
1299
+ - terminal
1300
+ - success
1301
+ - outputBytes
1302
+ - hasArtifact
1303
+ - executionPolicyDigest
1304
+ - receiptDigest
1305
+ properties:
1306
+ callId: { type: string, minLength: 1 }
1307
+ sessionId: { type: string, minLength: 1 }
1308
+ threadId: { type: string, minLength: 1 }
1309
+ sequence: { type: integer, minimum: 1 }
1310
+ toolName: { type: string, minLength: 1 }
1311
+ state: { type: string, enum: [success, error, skipped] }
1312
+ terminal: { type: string, enum: [completed, failed, interrupted, indeterminate] }
1313
+ success: { type: boolean }
1314
+ outputBytes: { type: integer, minimum: 0 }
1315
+ hasArtifact: { type: boolean }
1316
+ executionPolicyDigest: { type: string, pattern: '^[a-f0-9]{64}$' }
1317
+ receiptDigest: { type: string, pattern: '^[a-f0-9]{64}$' }
1318
+ ReviewSnapshot:
1319
+ type: object
1320
+ additionalProperties: false
1321
+ required:
1322
+ - revision
1323
+ - repositoryRevision
1324
+ - isRepository
1325
+ - clean
1326
+ - changedFiles
1327
+ - stagedCount
1328
+ - unstagedCount
1329
+ - untrackedCount
1330
+ - conflictCount
1331
+ - truncated
1332
+ - verification
1333
+ properties:
1334
+ revision: { type: string, minLength: 1 }
1335
+ repositoryRevision: { type: string, minLength: 1 }
1336
+ isRepository: { type: boolean }
1337
+ clean: { type: boolean }
1338
+ changedFiles: { $ref: '#/components/schemas/GitFileList' }
1339
+ stagedCount: { type: integer, minimum: 0 }
1340
+ unstagedCount: { type: integer, minimum: 0 }
1341
+ untrackedCount: { type: integer, minimum: 0 }
1342
+ conflictCount: { type: integer, minimum: 0 }
1343
+ truncated: { type: boolean }
1344
+ verification:
1345
+ type: array
1346
+ maxItems: 100
1347
+ items: { $ref: '#/components/schemas/ReviewVerification' }
1348
+ ContextGuardRequest:
1349
+ type: object
1350
+ additionalProperties: false
1351
+ required: [requestId, expectedContextRevision, workspaceId]
1352
+ properties:
1353
+ requestId: { $ref: '#/components/schemas/RequestId' }
1354
+ expectedContextRevision: { $ref: '#/components/schemas/ContextRevision' }
1355
+ workspaceId: { type: string, format: uuid }
1356
+ TerminalCreateRequest:
1357
+ type: object
1358
+ additionalProperties: false
1359
+ required: [requestId, expectedContextRevision, workspaceId]
1360
+ properties:
1361
+ requestId: { $ref: '#/components/schemas/RequestId' }
1362
+ expectedContextRevision: { $ref: '#/components/schemas/ContextRevision' }
1363
+ workspaceId: { type: string, format: uuid }
1364
+ cols: { type: integer, minimum: 2, maximum: 400, default: 100 }
1365
+ rows: { type: integer, minimum: 1, maximum: 200, default: 30 }
1366
+ TerminalMetadata:
1367
+ type: object
1368
+ additionalProperties: false
1369
+ required:
1370
+ - id
1371
+ - workspaceId
1372
+ - title
1373
+ - shell
1374
+ - state
1375
+ - cols
1376
+ - rows
1377
+ - connected
1378
+ - createdAt
1379
+ - lastActiveAt
1380
+ - earliestSequence
1381
+ - lastSequence
1382
+ properties:
1383
+ id: { type: string, format: uuid }
1384
+ workspaceId: { type: string, format: uuid }
1385
+ title: { type: string }
1386
+ shell: { type: string, description: Display basename only; no shell argv or environment. }
1387
+ state: { type: string, enum: [running, exited, closing] }
1388
+ cols: { type: integer, minimum: 2, maximum: 400 }
1389
+ rows: { type: integer, minimum: 1, maximum: 200 }
1390
+ connected: { type: boolean }
1391
+ createdAt: { type: string, format: date-time }
1392
+ lastActiveAt: { type: string, format: date-time }
1393
+ earliestSequence: { type: integer, minimum: 1 }
1394
+ lastSequence: { type: integer, minimum: 0 }
1395
+ exitCode: { type: integer }
1396
+ signal: { type: integer }
1397
+ TerminalPage:
1398
+ type: object
1399
+ additionalProperties: false
1400
+ required: [items, nextCursor]
1401
+ properties:
1402
+ items:
1403
+ type: array
1404
+ maxItems: 100
1405
+ items: { $ref: '#/components/schemas/TerminalMetadata' }
1406
+ nextCursor: { type: [string, 'null'] }
1407
+ TerminalTicket:
1408
+ type: object
1409
+ additionalProperties: false
1410
+ required: [ticket, ticketExpiresAt]
1411
+ properties:
1412
+ ticket:
1413
+ type: string
1414
+ minLength: 32
1415
+ maxLength: 128
1416
+ writeOnly: true
1417
+ description: Single-use bearer delivered only in this JSON body and first WS message.
1418
+ ticketExpiresAt: { type: string, format: date-time }
1419
+ TerminalCreateMutationResult:
1420
+ type: object
1421
+ additionalProperties: false
1422
+ required: [requestId, terminal, ticket, ticketExpiresAt]
1423
+ properties:
1424
+ requestId: { $ref: '#/components/schemas/RequestId' }
1425
+ terminal: { $ref: '#/components/schemas/TerminalMetadata' }
1426
+ ticket: { type: string, minLength: 32, maxLength: 128, writeOnly: true }
1427
+ ticketExpiresAt: { type: string, format: date-time }
1428
+ TerminalTicketMutationResult:
1429
+ type: object
1430
+ additionalProperties: false
1431
+ required: [requestId, ticket, ticketExpiresAt]
1432
+ properties:
1433
+ requestId: { $ref: '#/components/schemas/RequestId' }
1434
+ ticket: { type: string, minLength: 32, maxLength: 128, writeOnly: true }
1435
+ ticketExpiresAt: { type: string, format: date-time }
1436
+ TerminalCloseMutationResult:
1437
+ type: object
1438
+ additionalProperties: false
1439
+ required: [requestId, terminal]
1440
+ properties:
1441
+ requestId: { $ref: '#/components/schemas/RequestId' }
1442
+ terminal: { $ref: '#/components/schemas/TerminalMetadata' }
1443
+ TerminalAuthenticateMessage:
1444
+ type: object
1445
+ additionalProperties: false
1446
+ required: [type, ticket, afterSequence]
1447
+ properties:
1448
+ type: { type: string, const: authenticate }
1449
+ ticket: { type: string, minLength: 32, maxLength: 128, writeOnly: true }
1450
+ afterSequence: { type: integer, minimum: 0 }
1451
+ TerminalInputMessage:
1452
+ type: object
1453
+ additionalProperties: false
1454
+ required: [type, data]
1455
+ properties:
1456
+ type: { type: string, const: input }
1457
+ data: { type: string, maxLength: 65536 }
1458
+ TerminalResizeMessage:
1459
+ type: object
1460
+ additionalProperties: false
1461
+ required: [type, cols, rows]
1462
+ properties:
1463
+ type: { type: string, const: resize }
1464
+ cols: { type: integer, minimum: 2, maximum: 400 }
1465
+ rows: { type: integer, minimum: 1, maximum: 200 }
1466
+ TerminalPingMessage:
1467
+ type: object
1468
+ additionalProperties: false
1469
+ required: [type, timestamp]
1470
+ properties:
1471
+ type: { type: string, const: ping }
1472
+ timestamp: { type: number }
1473
+ TerminalClientMessage:
1474
+ oneOf:
1475
+ - $ref: '#/components/schemas/TerminalInputMessage'
1476
+ - $ref: '#/components/schemas/TerminalResizeMessage'
1477
+ - $ref: '#/components/schemas/TerminalPingMessage'
1478
+ discriminator: { propertyName: type }
1479
+ TerminalReadyMessage:
1480
+ type: object
1481
+ additionalProperties: false
1482
+ required: [type, terminal]
1483
+ properties:
1484
+ type: { type: string, const: ready }
1485
+ terminal: { $ref: '#/components/schemas/TerminalMetadata' }
1486
+ TerminalOutputMessage:
1487
+ type: object
1488
+ additionalProperties: false
1489
+ required: [type, sequence, data]
1490
+ properties:
1491
+ type: { type: string, const: output }
1492
+ sequence: { type: integer, minimum: 1 }
1493
+ data: { type: string, maxLength: 8000 }
1494
+ TerminalGapMessage:
1495
+ type: object
1496
+ additionalProperties: false
1497
+ required: [type, earliestSequence, latestSequence]
1498
+ properties:
1499
+ type: { type: string, const: gap }
1500
+ earliestSequence: { type: integer, minimum: 1 }
1501
+ latestSequence: { type: integer, minimum: 0 }
1502
+ TerminalExitMessage:
1503
+ type: object
1504
+ additionalProperties: false
1505
+ required: [type, exitCode]
1506
+ properties:
1507
+ type: { type: string, const: exit }
1508
+ exitCode: { type: integer }
1509
+ signal: { type: integer }
1510
+ TerminalPongMessage:
1511
+ type: object
1512
+ additionalProperties: false
1513
+ required: [type, timestamp]
1514
+ properties:
1515
+ type: { type: string, const: pong }
1516
+ timestamp: { type: number }
1517
+ TerminalErrorMessage:
1518
+ type: object
1519
+ additionalProperties: false
1520
+ required: [type, code]
1521
+ properties:
1522
+ type: { type: string, const: error }
1523
+ code: { type: string, minLength: 1 }
1524
+ TerminalServerMessage:
1525
+ oneOf:
1526
+ - $ref: '#/components/schemas/TerminalReadyMessage'
1527
+ - $ref: '#/components/schemas/TerminalOutputMessage'
1528
+ - $ref: '#/components/schemas/TerminalGapMessage'
1529
+ - $ref: '#/components/schemas/TerminalExitMessage'
1530
+ - $ref: '#/components/schemas/TerminalPongMessage'
1531
+ - $ref: '#/components/schemas/TerminalErrorMessage'
1532
+ discriminator: { propertyName: type }
1533
+ TranscriptMessage:
1534
+ type: object
1535
+ additionalProperties: false
1536
+ required: [id, role, content, timestamp]
1537
+ properties:
1538
+ id: { type: string }
1539
+ role:
1540
+ type: string
1541
+ enum: [system, user, assistant, tool]
1542
+ content: { type: string }
1543
+ timestamp: { type: number, minimum: 0 }
1544
+ modelVisibleContent: { type: string }
1545
+ toolCallId: { type: string }
1546
+ tool_calls:
1547
+ type: array
1548
+ items: {}
1549
+ appliedSkills:
1550
+ type: array
1551
+ items: { type: string }
1552
+ TranscriptPage:
1553
+ type: object
1554
+ additionalProperties: false
1555
+ required: [items, nextCursor]
1556
+ properties:
1557
+ items:
1558
+ type: array
1559
+ maxItems: 100
1560
+ items: { $ref: '#/components/schemas/TranscriptMessage' }
1561
+ nextCursor: { type: [string, 'null'] }
1562
+ GoalView:
1563
+ type: object
1564
+ additionalProperties: false
1565
+ description: >-
1566
+ Goal projection from the latest valid TurnCommitV1. A legacy Goal sidecar is eligible only
1567
+ as a one-time migration seed and is never a competing read authority.
1568
+ required: [authority, digest, state]
1569
+ properties:
1570
+ authority: { type: string, const: turn_commit }
1571
+ digest: { type: string, minLength: 1 }
1572
+ state:
1573
+ description: >-
1574
+ Opaque JSON value parsed from TurnCommitV1.goalState. The v0.3.0 wire type is unknown;
1575
+ this contract does not invent required Goal fields or status/revision enums.
1576
+ PlanView:
1577
+ type: object
1578
+ additionalProperties: false
1579
+ description: >-
1580
+ Exact safe projection of the PlanReceipt bound into TurnCommitV1. There is no Web review,
1581
+ approval, status or step model. After the planning turn commits, Orion restores returnMode
1582
+ and automatically schedules a separate execution request.
1583
+ required: [body, returnMode, digest]
1584
+ properties:
1585
+ body: { type: string, minLength: 1 }
1586
+ returnMode: { type: string, enum: [build, auto] }
1587
+ digest: { type: string, minLength: 1 }
1588
+ PendingApproval:
1589
+ type: object
1590
+ additionalProperties: false
1591
+ description: Runtime-owned approval that survives browser disconnect and tab closure.
1592
+ required: [id, toolName, sanitizedArguments, allowedScopes]
1593
+ properties:
1594
+ id: { type: string }
1595
+ toolName: { type: string }
1596
+ reason: { type: string }
1597
+ sanitizedArguments: { type: object, additionalProperties: true }
1598
+ allowedScopes:
1599
+ type: array
1600
+ const: [once, project, global]
1601
+ items: { type: string, enum: [once, project, global] }
1602
+ FollowupItem:
1603
+ type: object
1604
+ additionalProperties: false
1605
+ required: [id, text, queuedAt]
1606
+ properties:
1607
+ id: { type: string }
1608
+ text: { type: string }
1609
+ queuedAt: { type: number, minimum: 0 }
1610
+ SessionRuntimeSnapshot:
1611
+ type: object
1612
+ additionalProperties: false
1613
+ required:
1614
+ - active
1615
+ - processing
1616
+ - agentMode
1617
+ - permissionMode
1618
+ - status
1619
+ - followups
1620
+ - followupLimit
1621
+ - contextUsage
1622
+ - tokenUsage
1623
+ properties:
1624
+ active: { type: boolean }
1625
+ processing: { type: boolean }
1626
+ agentMode: { type: string }
1627
+ permissionMode: { type: string }
1628
+ status: { type: string }
1629
+ followups:
1630
+ type: array
1631
+ items: { $ref: '#/components/schemas/FollowupItem' }
1632
+ followupLimit: { type: integer, minimum: 0 }
1633
+ contextUsage:
1634
+ description: Runtime context-usage projection or null; the wire type is currently unknown.
1635
+ tokenUsage:
1636
+ description: Runtime token-usage projection or null; the wire type is currently unknown.
1637
+ SessionSnapshot:
1638
+ type: object
1639
+ additionalProperties: false
1640
+ required:
1641
+ - apiVersion
1642
+ - session
1643
+ - threadId
1644
+ - threadCursor
1645
+ - eventCursor
1646
+ - threadStatus
1647
+ - transcript
1648
+ - runtime
1649
+ - pendingApprovals
1650
+ - goal
1651
+ - plan
1652
+ - recoveryDiagnostics
1653
+ properties:
1654
+ apiVersion: { type: integer, const: 1 }
1655
+ session: { $ref: '#/components/schemas/SessionSummary' }
1656
+ threadId:
1657
+ type: [string, 'null']
1658
+ description: Null for a legacy session that has no materialized Thread identity.
1659
+ threadCursor:
1660
+ type: integer
1661
+ minimum: 0
1662
+ description: Latest projected durable Thread sequence; independent of eventCursor.
1663
+ eventCursor: { type: integer, minimum: 0 }
1664
+ projectionDigest: { type: string }
1665
+ threadStatus: { type: string, enum: [new, active, idle, legacy] }
1666
+ activeTurnId: { type: string }
1667
+ transcript: { $ref: '#/components/schemas/TranscriptPage' }
1668
+ runtime: { $ref: '#/components/schemas/SessionRuntimeSnapshot' }
1669
+ pendingApprovals:
1670
+ type: array
1671
+ items: { $ref: '#/components/schemas/PendingApproval' }
1672
+ goal:
1673
+ oneOf:
1674
+ - $ref: '#/components/schemas/GoalView'
1675
+ - type: 'null'
1676
+ plan:
1677
+ oneOf:
1678
+ - $ref: '#/components/schemas/PlanView'
1679
+ - type: 'null'
1680
+ recoveryDiagnostics:
1681
+ type: array
1682
+ items: {}
1683
+ SkillSummary:
1684
+ type: object
1685
+ additionalProperties: false
1686
+ required:
1687
+ - id
1688
+ - name
1689
+ - description
1690
+ - providerId
1691
+ - sourceScope
1692
+ - modelInvocable
1693
+ - userInvocable
1694
+ - requestedCapabilities
1695
+ - digest
1696
+ properties:
1697
+ id: { type: string }
1698
+ name: { type: string }
1699
+ description: { type: string }
1700
+ providerId: { type: string }
1701
+ sourceScope: { type: string, enum: [builtin, user, configured, project, remote] }
1702
+ modelInvocable: { type: boolean }
1703
+ userInvocable: { type: boolean }
1704
+ requestedCapabilities:
1705
+ type: array
1706
+ items: { type: string }
1707
+ digest: { type: string }
1708
+ SkillPage:
1709
+ type: object
1710
+ additionalProperties: false
1711
+ required: [items, nextCursor]
1712
+ properties:
1713
+ items:
1714
+ type: array
1715
+ maxItems: 100
1716
+ items: { $ref: '#/components/schemas/SkillSummary' }
1717
+ nextCursor: { type: [string, 'null'] }
1718
+ McpServerSummary:
1719
+ type: object
1720
+ additionalProperties: false
1721
+ required:
1722
+ - id
1723
+ - name
1724
+ - transport
1725
+ - tags
1726
+ - disabled
1727
+ - state
1728
+ - generation
1729
+ - toolCount
1730
+ - activeCallCount
1731
+ properties:
1732
+ id: { type: string }
1733
+ name: { type: string }
1734
+ description: { type: string }
1735
+ transport:
1736
+ type: string
1737
+ enum: [stdio, sse, http, streamable-http, websocket]
1738
+ tags:
1739
+ type: array
1740
+ items: { type: string }
1741
+ disabled: { type: boolean }
1742
+ state:
1743
+ type: string
1744
+ enum: [dormant, activating, connected, idle, draining, failed]
1745
+ generation: { type: integer, minimum: 0 }
1746
+ toolCount: { type: integer, minimum: 0 }
1747
+ activeCallCount: { type: integer, minimum: 0 }
1748
+ failure: { type: string }
1749
+ McpPage:
1750
+ type: object
1751
+ additionalProperties: false
1752
+ required: [items, nextCursor]
1753
+ properties:
1754
+ items:
1755
+ type: array
1756
+ maxItems: 100
1757
+ items: { $ref: '#/components/schemas/McpServerSummary' }
1758
+ nextCursor: { type: [string, 'null'] }
1759
+ ToolDetailSummary:
1760
+ type: object
1761
+ additionalProperties: false
1762
+ required: [callId, sequence, toolName, state, outputBytes, hasArtifact]
1763
+ properties:
1764
+ callId: { type: string }
1765
+ sequence: { type: integer, minimum: 0 }
1766
+ turnId: { type: string }
1767
+ toolName: { type: string }
1768
+ state: { type: string, enum: [success, error, skipped] }
1769
+ outputBytes: { type: integer, minimum: 0 }
1770
+ artifactId:
1771
+ type: string
1772
+ description: Opaque project artifact identifier; it is not a filesystem path.
1773
+ hasArtifact: { type: boolean }
1774
+ ToolDetailSummaryPage:
1775
+ type: object
1776
+ additionalProperties: false
1777
+ required: [items, nextCursor]
1778
+ properties:
1779
+ items:
1780
+ type: array
1781
+ maxItems: 100
1782
+ items: { $ref: '#/components/schemas/ToolDetailSummary' }
1783
+ nextCursor: { type: [string, 'null'] }
1784
+ ToolDetailPage:
1785
+ type: object
1786
+ additionalProperties: false
1787
+ required: [content, offsetBytes, totalBytes, redacted]
1788
+ properties:
1789
+ content: { type: string }
1790
+ offsetBytes: { type: integer, minimum: 0 }
1791
+ nextOffsetBytes:
1792
+ type: [integer, 'null']
1793
+ minimum: 0
1794
+ description: Omitted or null when the page reaches the end of the artifact.
1795
+ totalBytes: { type: integer, minimum: 0 }
1796
+ redacted:
1797
+ type: boolean
1798
+ description: >-
1799
+ True when content is served from the browser-safe, pre-sanitized derivative. It does
1800
+ not imply that this particular page contained a secret replacement.
1801
+ SettingsRevision:
1802
+ type: string
1803
+ pattern: '^hmac-sha256:[a-f0-9]{64}$'
1804
+ description: >-
1805
+ Opaque HMAC over the exact current config bytes. The local HMAC key is never exposed.
1806
+ SettingsFieldCommon:
1807
+ type: object
1808
+ required: [source, scope, applies, overridden, writable]
1809
+ properties:
1810
+ source: { type: string, enum: [internal, model, global, project, session] }
1811
+ scope: { type: string, enum: [global, project, session] }
1812
+ applies:
1813
+ type: string
1814
+ enum: [live, next-logical-request, new-session, restart]
1815
+ overridden: { type: boolean }
1816
+ writable: { type: boolean }
1817
+ blockedReason:
1818
+ type: string
1819
+ enum: [runtime_busy, read_only, invalid_document]
1820
+ ThemeSettingsField:
1821
+ allOf:
1822
+ - $ref: '#/components/schemas/SettingsFieldCommon'
1823
+ - type: object
1824
+ required: [effectiveValue]
1825
+ properties:
1826
+ effectiveValue: { type: string, enum: [system, light, dark] }
1827
+ explicitValue: { type: string, enum: [system, light, dark] }
1828
+ inheritedValue: { type: string, enum: [system, light, dark] }
1829
+ MotionSettingsField:
1830
+ allOf:
1831
+ - $ref: '#/components/schemas/SettingsFieldCommon'
1832
+ - type: object
1833
+ required: [effectiveValue]
1834
+ properties:
1835
+ effectiveValue: { type: string, enum: [system, reduced] }
1836
+ explicitValue: { type: string, enum: [system, reduced] }
1837
+ inheritedValue: { type: string, enum: [system, reduced] }
1838
+ ModelSettingsField:
1839
+ allOf:
1840
+ - $ref: '#/components/schemas/SettingsFieldCommon'
1841
+ - type: object
1842
+ required: [effectiveValue]
1843
+ properties:
1844
+ effectiveValue: { type: string, minLength: 1 }
1845
+ explicitValue: { type: string, minLength: 1 }
1846
+ inheritedValue: { type: string, minLength: 1 }
1847
+ EffortSettingsField:
1848
+ allOf:
1849
+ - $ref: '#/components/schemas/SettingsFieldCommon'
1850
+ - type: object
1851
+ required: [effectiveValue]
1852
+ properties:
1853
+ effectiveValue: { $ref: '#/components/schemas/EffortPreference' }
1854
+ explicitValue: { $ref: '#/components/schemas/EffortPreference' }
1855
+ inheritedValue: { $ref: '#/components/schemas/EffortPreference' }
1856
+ ToolConfirmationSettingsField:
1857
+ allOf:
1858
+ - $ref: '#/components/schemas/SettingsFieldCommon'
1859
+ - type: object
1860
+ required: [effectiveValue]
1861
+ properties:
1862
+ effectiveValue: { type: string, enum: [allow, ask, deny] }
1863
+ explicitValue: { type: string, enum: [allow, ask, deny] }
1864
+ inheritedValue: { type: string, enum: [allow, ask, deny] }
1865
+ EffortPreference:
1866
+ type: string
1867
+ enum: [auto, none, minimal, low, medium, high, xhigh, max]
1868
+ ModelSummary:
1869
+ type: object
1870
+ additionalProperties: false
1871
+ required: [id, label]
1872
+ properties:
1873
+ id: { type: string, minLength: 1 }
1874
+ label: { type: string, minLength: 1 }
1875
+ provider: { type: string }
1876
+ CredentialSlot:
1877
+ type: object
1878
+ additionalProperties: false
1879
+ required: [providerId, state, source, writable]
1880
+ properties:
1881
+ providerId: { type: string, minLength: 1 }
1882
+ state: { type: string, enum: [ready, missing, unavailable] }
1883
+ source: { type: string, enum: [environment, legacy, none] }
1884
+ writable: { type: boolean, const: false }
1885
+ SettingsDocument:
1886
+ type: object
1887
+ additionalProperties: false
1888
+ required:
1889
+ - schemaVersion
1890
+ - revision
1891
+ - state
1892
+ - writable
1893
+ - hasDocument
1894
+ - workspace
1895
+ - sections
1896
+ - models
1897
+ - credentials
1898
+ properties:
1899
+ schemaVersion: { type: integer, const: 1 }
1900
+ revision: { $ref: '#/components/schemas/SettingsRevision' }
1901
+ state: { type: string, enum: [ready, invalid, read-only, unavailable] }
1902
+ writable: { type: boolean }
1903
+ hasDocument: { type: boolean }
1904
+ workspace: { type: string }
1905
+ sections:
1906
+ type: object
1907
+ additionalProperties: false
1908
+ required: [appearance, defaults, permissions]
1909
+ properties:
1910
+ appearance:
1911
+ type: object
1912
+ additionalProperties: false
1913
+ required: [theme, motion]
1914
+ properties:
1915
+ theme: { $ref: '#/components/schemas/ThemeSettingsField' }
1916
+ motion: { $ref: '#/components/schemas/MotionSettingsField' }
1917
+ defaults:
1918
+ type: object
1919
+ additionalProperties: false
1920
+ required: [model, effort]
1921
+ properties:
1922
+ model: { $ref: '#/components/schemas/ModelSettingsField' }
1923
+ effort: { $ref: '#/components/schemas/EffortSettingsField' }
1924
+ permissions:
1925
+ type: object
1926
+ additionalProperties: false
1927
+ required: [toolConfirmation]
1928
+ properties:
1929
+ toolConfirmation:
1930
+ $ref: '#/components/schemas/ToolConfirmationSettingsField'
1931
+ models:
1932
+ type: array
1933
+ items: { $ref: '#/components/schemas/ModelSummary' }
1934
+ credentials:
1935
+ type: array
1936
+ items: { $ref: '#/components/schemas/CredentialSlot' }
1937
+ currentSession:
1938
+ type: object
1939
+ additionalProperties: false
1940
+ required: [model, effort, overridesProjectEffort]
1941
+ properties:
1942
+ model: { type: string }
1943
+ effort: { $ref: '#/components/schemas/EffortPreference' }
1944
+ overridesProjectEffort: { type: boolean }
1945
+ diagnostic:
1946
+ type: object
1947
+ additionalProperties: false
1948
+ required: [code, message]
1949
+ properties:
1950
+ code: { type: string }
1951
+ message: { type: string }
1952
+ SettingsOperation:
1953
+ oneOf:
1954
+ - $ref: '#/components/schemas/SetThemeSetting'
1955
+ - $ref: '#/components/schemas/UnsetThemeSetting'
1956
+ - $ref: '#/components/schemas/SetMotionSetting'
1957
+ - $ref: '#/components/schemas/UnsetMotionSetting'
1958
+ - $ref: '#/components/schemas/SetModelSetting'
1959
+ - $ref: '#/components/schemas/UnsetModelSetting'
1960
+ - $ref: '#/components/schemas/SetEffortSetting'
1961
+ - $ref: '#/components/schemas/UnsetEffortSetting'
1962
+ - $ref: '#/components/schemas/SetToolConfirmationSetting'
1963
+ - $ref: '#/components/schemas/UnsetToolConfirmationSetting'
1964
+ SetThemeSetting:
1965
+ type: object
1966
+ additionalProperties: false
1967
+ required: [op, key, value]
1968
+ properties:
1969
+ op: { type: string, const: set }
1970
+ key: { type: string, const: appearance.theme }
1971
+ value: { type: string, enum: [system, light, dark] }
1972
+ UnsetThemeSetting:
1973
+ type: object
1974
+ additionalProperties: false
1975
+ required: [op, key]
1976
+ properties:
1977
+ op: { type: string, const: unset }
1978
+ key: { type: string, const: appearance.theme }
1979
+ SetMotionSetting:
1980
+ type: object
1981
+ additionalProperties: false
1982
+ required: [op, key, value]
1983
+ properties:
1984
+ op: { type: string, const: set }
1985
+ key: { type: string, const: appearance.motion }
1986
+ value: { type: string, enum: [system, reduced] }
1987
+ UnsetMotionSetting:
1988
+ type: object
1989
+ additionalProperties: false
1990
+ required: [op, key]
1991
+ properties:
1992
+ op: { type: string, const: unset }
1993
+ key: { type: string, const: appearance.motion }
1994
+ SetModelSetting:
1995
+ type: object
1996
+ additionalProperties: false
1997
+ required: [op, key, value]
1998
+ properties:
1999
+ op: { type: string, const: set }
2000
+ key: { type: string, const: defaults.model }
2001
+ value: { type: string, minLength: 1, maxLength: 200 }
2002
+ UnsetModelSetting:
2003
+ type: object
2004
+ additionalProperties: false
2005
+ required: [op, key]
2006
+ properties:
2007
+ op: { type: string, const: unset }
2008
+ key: { type: string, const: defaults.model }
2009
+ SetEffortSetting:
2010
+ type: object
2011
+ additionalProperties: false
2012
+ required: [op, key, value]
2013
+ properties:
2014
+ op: { type: string, const: set }
2015
+ key: { type: string, const: defaults.effort }
2016
+ value: { $ref: '#/components/schemas/EffortPreference' }
2017
+ UnsetEffortSetting:
2018
+ type: object
2019
+ additionalProperties: false
2020
+ required: [op, key]
2021
+ properties:
2022
+ op: { type: string, const: unset }
2023
+ key: { type: string, const: defaults.effort }
2024
+ SetToolConfirmationSetting:
2025
+ type: object
2026
+ additionalProperties: false
2027
+ required: [op, key, value]
2028
+ properties:
2029
+ op: { type: string, const: set }
2030
+ key: { type: string, const: permissions.toolConfirmation }
2031
+ value: { type: string, enum: [allow, ask, deny] }
2032
+ UnsetToolConfirmationSetting:
2033
+ type: object
2034
+ additionalProperties: false
2035
+ required: [op, key]
2036
+ properties:
2037
+ op: { type: string, const: unset }
2038
+ key: { type: string, const: permissions.toolConfirmation }
2039
+ UpdateSettingsRequest:
2040
+ type: object
2041
+ additionalProperties: false
2042
+ required: [requestId, expectedRevision, operations]
2043
+ properties:
2044
+ requestId: { $ref: '#/components/schemas/RequestId' }
2045
+ expectedRevision: { $ref: '#/components/schemas/SettingsRevision' }
2046
+ operations:
2047
+ type: array
2048
+ minItems: 1
2049
+ maxItems: 20
2050
+ items: { $ref: '#/components/schemas/SettingsOperation' }
2051
+ SettingsMutationResult:
2052
+ type: object
2053
+ additionalProperties: false
2054
+ required: [requestId, revision, appliedKeys, settings]
2055
+ properties:
2056
+ requestId: { $ref: '#/components/schemas/RequestId' }
2057
+ revision: { $ref: '#/components/schemas/SettingsRevision' }
2058
+ appliedKeys:
2059
+ type: array
2060
+ minItems: 1
2061
+ maxItems: 20
2062
+ items:
2063
+ type: string
2064
+ enum:
2065
+ - appearance.theme
2066
+ - appearance.motion
2067
+ - defaults.model
2068
+ - defaults.effort
2069
+ - permissions.toolConfirmation
2070
+ settings: { $ref: '#/components/schemas/SettingsDocument' }
2071
+ WebCommand:
2072
+ type: object
2073
+ additionalProperties: false
2074
+ required: [requestId, expectedContextRevision, workspaceId, expectedSessionId, type]
2075
+ allOf:
2076
+ - if:
2077
+ properties:
2078
+ type: { const: set_agent_mode }
2079
+ required: [type]
2080
+ then:
2081
+ required: [agentMode]
2082
+ properties:
2083
+ requestId: { $ref: '#/components/schemas/RequestId' }
2084
+ expectedContextRevision: { $ref: '#/components/schemas/ContextRevision' }
2085
+ workspaceId: { type: string, format: uuid }
2086
+ expectedSessionId:
2087
+ type: string
2088
+ minLength: 1
2089
+ maxLength: 256
2090
+ description: >-
2091
+ Compare-and-swap guard for the active Session. The Host returns 409
2092
+ active_session_changed without dispatching when the selection no longer matches.
2093
+ type:
2094
+ type: string
2095
+ enum:
2096
+ - submit
2097
+ - queue_followup
2098
+ - remove_followup
2099
+ - clear_followups
2100
+ - interrupt
2101
+ - permission_decision
2102
+ - goal_control
2103
+ - permission_mode_change
2104
+ - cycle_agent_mode
2105
+ - set_agent_mode
2106
+ text: { type: string, maxLength: 1048576 }
2107
+ itemId: { type: string }
2108
+ requestPermissionId: { type: string }
2109
+ approved: { type: boolean }
2110
+ scope: { type: string, enum: [once, project, global] }
2111
+ goalAction: { type: string, enum: [create, status, pause, resume, clear] }
2112
+ objective: { type: string }
2113
+ toolConfirmation: { type: string, enum: [allow, ask, deny] }
2114
+ agentMode: { type: string, enum: [interactive, plan, auto] }
2115
+ CommandResult:
2116
+ type: object
2117
+ additionalProperties: false
2118
+ required: [requestId, result]
2119
+ properties:
2120
+ requestId: { $ref: '#/components/schemas/RequestId' }
2121
+ result: { type: string }
2122
+ detail: { type: string }
2123
+ WebEventEnvelope:
2124
+ description: >-
2125
+ Versioned, cursor-ordered event union. `type` is the discriminator; every branch carries
2126
+ explicit `sessionId` and `threadId` keys. Runtime events allow null identities before a
2127
+ session or Thread exists; committed Thread events require both values to be non-null.
2128
+ oneOf:
2129
+ - $ref: '#/components/schemas/RuntimeEventEnvelope'
2130
+ - $ref: '#/components/schemas/ThreadEventEnvelope'
2131
+ - $ref: '#/components/schemas/WorkbenchStateEnvelope'
2132
+ - $ref: '#/components/schemas/SettingsInvalidatedEnvelope'
2133
+ - $ref: '#/components/schemas/WorkspaceResourceInvalidatedEnvelope'
2134
+ - $ref: '#/components/schemas/ReplayResetEnvelope'
2135
+ discriminator:
2136
+ propertyName: type
2137
+ mapping:
2138
+ runtime_event: '#/components/schemas/RuntimeEventEnvelope'
2139
+ thread_event: '#/components/schemas/ThreadEventEnvelope'
2140
+ workbench_state: '#/components/schemas/WorkbenchStateEnvelope'
2141
+ settings_invalidated: '#/components/schemas/SettingsInvalidatedEnvelope'
2142
+ workspace_resource_invalidated: '#/components/schemas/WorkspaceResourceInvalidatedEnvelope'
2143
+ replay_reset: '#/components/schemas/ReplayResetEnvelope'
2144
+ RuntimeEventEnvelope:
2145
+ type: object
2146
+ additionalProperties: false
2147
+ required:
2148
+ - apiVersion
2149
+ - eventId
2150
+ - cursor
2151
+ - sessionId
2152
+ - threadId
2153
+ - type
2154
+ - durable
2155
+ - timestamp
2156
+ - payload
2157
+ properties:
2158
+ apiVersion: { type: integer, const: 1 }
2159
+ eventId: { type: string, format: uuid }
2160
+ cursor: { type: integer, minimum: 1 }
2161
+ sessionId: { type: [string, 'null'] }
2162
+ threadId: { type: [string, 'null'] }
2163
+ type: { type: string, const: runtime_event }
2164
+ durable: { type: boolean }
2165
+ timestamp: { type: string, format: date-time }
2166
+ payload:
2167
+ type: object
2168
+ additionalProperties: false
2169
+ required: [eventType, value]
2170
+ properties:
2171
+ eventType: { type: string, minLength: 1 }
2172
+ value: { type: object, additionalProperties: true }
2173
+ ThreadEventEnvelope:
2174
+ type: object
2175
+ additionalProperties: false
2176
+ required:
2177
+ - apiVersion
2178
+ - eventId
2179
+ - cursor
2180
+ - sessionId
2181
+ - threadId
2182
+ - type
2183
+ - durable
2184
+ - timestamp
2185
+ - payload
2186
+ properties:
2187
+ apiVersion: { type: integer, const: 1 }
2188
+ eventId: { type: string, format: uuid }
2189
+ cursor: { type: integer, minimum: 1 }
2190
+ sessionId: { type: string, minLength: 1 }
2191
+ threadId: { type: string, minLength: 1 }
2192
+ type: { type: string, const: thread_event }
2193
+ durable: { type: boolean, const: true }
2194
+ timestamp: { type: string, format: date-time }
2195
+ payload:
2196
+ type: object
2197
+ additionalProperties: false
2198
+ required: [sequence, eventType, value]
2199
+ properties:
2200
+ sequence: { type: integer, minimum: 1 }
2201
+ eventType: { type: string, minLength: 1 }
2202
+ value: { type: object, additionalProperties: true }
2203
+ WorkbenchStateEnvelope:
2204
+ type: object
2205
+ additionalProperties: false
2206
+ required:
2207
+ - apiVersion
2208
+ - eventId
2209
+ - cursor
2210
+ - sessionId
2211
+ - threadId
2212
+ - type
2213
+ - durable
2214
+ - timestamp
2215
+ - payload
2216
+ properties:
2217
+ apiVersion: { type: integer, const: 1 }
2218
+ eventId: { type: string, format: uuid }
2219
+ cursor: { type: integer, minimum: 1 }
2220
+ sessionId: { type: [string, 'null'] }
2221
+ threadId: { type: [string, 'null'] }
2222
+ type: { type: string, const: workbench_state }
2223
+ durable: { type: boolean }
2224
+ timestamp: { type: string, format: date-time }
2225
+ payload:
2226
+ type: object
2227
+ additionalProperties: false
2228
+ required: [contextRevision, workspaceId, workspace, activeSessionId]
2229
+ properties:
2230
+ contextRevision: { $ref: '#/components/schemas/ContextRevision' }
2231
+ workspaceId: { type: string, format: uuid }
2232
+ workspace: { type: string }
2233
+ activeSessionId: { type: [string, 'null'] }
2234
+ SettingsInvalidatedEnvelope:
2235
+ type: object
2236
+ additionalProperties: false
2237
+ required:
2238
+ - apiVersion
2239
+ - eventId
2240
+ - cursor
2241
+ - sessionId
2242
+ - threadId
2243
+ - type
2244
+ - durable
2245
+ - timestamp
2246
+ - payload
2247
+ properties:
2248
+ apiVersion: { type: integer, const: 1 }
2249
+ eventId: { type: string, format: uuid }
2250
+ cursor: { type: integer, minimum: 1 }
2251
+ sessionId: { type: [string, 'null'] }
2252
+ threadId: { type: [string, 'null'] }
2253
+ type: { type: string, const: settings_invalidated }
2254
+ durable: { type: boolean, const: false }
2255
+ timestamp: { type: string, format: date-time }
2256
+ payload:
2257
+ type: object
2258
+ additionalProperties: false
2259
+ required: [revision, reason, state]
2260
+ properties:
2261
+ revision: { $ref: '#/components/schemas/SettingsRevision' }
2262
+ reason: { type: string, enum: [local-write, external-edit, workspace-change] }
2263
+ state: { type: string, enum: [ready, invalid] }
2264
+ WorkspaceResourceInvalidatedEnvelope:
2265
+ type: object
2266
+ additionalProperties: false
2267
+ required:
2268
+ - apiVersion
2269
+ - eventId
2270
+ - cursor
2271
+ - sessionId
2272
+ - threadId
2273
+ - type
2274
+ - durable
2275
+ - timestamp
2276
+ - payload
2277
+ properties:
2278
+ apiVersion: { type: integer, const: 1 }
2279
+ eventId: { type: string, format: uuid }
2280
+ cursor: { type: integer, minimum: 1 }
2281
+ sessionId: { type: [string, 'null'] }
2282
+ threadId: { type: [string, 'null'] }
2283
+ type: { type: string, const: workspace_resource_invalidated }
2284
+ durable: { type: boolean, const: false }
2285
+ timestamp: { type: string, format: date-time }
2286
+ payload:
2287
+ type: object
2288
+ additionalProperties: false
2289
+ required: [workspaceId, resources, reason]
2290
+ properties:
2291
+ workspaceId: { type: string, format: uuid }
2292
+ resources:
2293
+ type: array
2294
+ minItems: 1
2295
+ uniqueItems: true
2296
+ items: { type: string, enum: [files, git, review] }
2297
+ reason:
2298
+ type: string
2299
+ enum: [context-change, filesystem-change, terminal-command, tool-finished]
2300
+ ReplayResetEnvelope:
2301
+ type: object
2302
+ additionalProperties: false
2303
+ required:
2304
+ - apiVersion
2305
+ - eventId
2306
+ - cursor
2307
+ - sessionId
2308
+ - threadId
2309
+ - type
2310
+ - durable
2311
+ - timestamp
2312
+ - payload
2313
+ properties:
2314
+ apiVersion: { type: integer, const: 1 }
2315
+ eventId: { type: string, format: uuid }
2316
+ cursor: { type: integer, minimum: 1 }
2317
+ sessionId: { type: [string, 'null'] }
2318
+ threadId: { type: [string, 'null'] }
2319
+ type: { type: string, const: replay_reset }
2320
+ durable: { type: boolean, const: true }
2321
+ timestamp: { type: string, format: date-time }
2322
+ payload:
2323
+ type: object
2324
+ additionalProperties: false
2325
+ required: [reason, snapshotRequired]
2326
+ properties:
2327
+ reason: { type: string }
2328
+ snapshotRequired: { type: boolean, const: true }
2329
+ Problem:
2330
+ type: object
2331
+ additionalProperties: false
2332
+ required: [type, title, status, code]
2333
+ properties:
2334
+ type: { type: string }
2335
+ title: { type: string }
2336
+ status: { type: integer }
2337
+ code: { type: string, minLength: 1 }
2338
+ detail: { type: string }