@straiffi/archon 1.11.4 → 1.11.6

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 (164) hide show
  1. package/README.md +8 -0
  2. package/dist/client/assets/{ActivityView-Cj-JRM9h.js → ActivityView-D9dXuvls.js} +1 -1
  3. package/dist/client/assets/{GitHubActionsDialog-Bz7x-EXk.js → GitHubActionsDialog-DFB9FNX0.js} +1 -1
  4. package/dist/client/assets/{VerificationDialog-C1g5teUk.js → VerificationDialog-CCpZtj3u.js} +1 -1
  5. package/dist/client/assets/{architectureDiagram-3BPJPVTR-Czgp4_s_.js → architectureDiagram-3BPJPVTR-C5QNVdbR.js} +1 -1
  6. package/dist/client/assets/{blockDiagram-GPEHLZMM-D_eKxSQA.js → blockDiagram-GPEHLZMM-ygrKiT2B.js} +1 -1
  7. package/dist/client/assets/{c4Diagram-AAUBKEIU-D6nMuDM5.js → c4Diagram-AAUBKEIU-p6pvarzH.js} +1 -1
  8. package/dist/client/assets/channel-CjCFIS-2.js +1 -0
  9. package/dist/client/assets/{chunk-2J33WTMH-B6Mn8gmT.js → chunk-2J33WTMH-BEZXyYSy.js} +1 -1
  10. package/dist/client/assets/{chunk-3OPIFGDE-BBoS7imT.js → chunk-3OPIFGDE-CxmfjZmF.js} +1 -1
  11. package/dist/client/assets/{chunk-5ZQYHXKU-CdhOo0Gr.js → chunk-5ZQYHXKU-B2X60oxE.js} +1 -1
  12. package/dist/client/assets/{chunk-727SXJPM-Dq8Odwy5.js → chunk-727SXJPM-P03pDtRv.js} +1 -1
  13. package/dist/client/assets/{chunk-AQP2D5EJ-DsKFdfMh.js → chunk-AQP2D5EJ-DE0MLi-X.js} +1 -1
  14. package/dist/client/assets/{chunk-CSCIHK7Q-4Ol5HlMd.js → chunk-CSCIHK7Q-C3QVx-Wf.js} +1 -1
  15. package/dist/client/assets/{chunk-KSCS5N6A-Ao7uFEEm.js → chunk-KSCS5N6A-BvajGF5R.js} +1 -1
  16. package/dist/client/assets/{chunk-L5ZTLDWV-C9Gzx6GF.js → chunk-L5ZTLDWV-HtpQP1op.js} +1 -1
  17. package/dist/client/assets/{chunk-LZXEDZCA-Ceca_Ske.js → chunk-LZXEDZCA-CWfF3VMY.js} +2 -2
  18. package/dist/client/assets/{chunk-ND2GUHAM-Cs2auQCc.js → chunk-ND2GUHAM-kEAduwJl.js} +1 -1
  19. package/dist/client/assets/{chunk-NZK2D7GU-fssKuUqc.js → chunk-NZK2D7GU-DNG4qBtm.js} +1 -1
  20. package/dist/client/assets/{chunk-O5CBEL6O-BdRwmtR1.js → chunk-O5CBEL6O-CS4J6DbD.js} +1 -1
  21. package/dist/client/assets/{chunk-WU5MYG2G-DnWsSIYg.js → chunk-WU5MYG2G-B2-mpLQ2.js} +1 -1
  22. package/dist/client/assets/classDiagram-4FO5ZUOK-DQ1lcUTi.js +1 -0
  23. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-tiWbaJIg.js +1 -0
  24. package/dist/client/assets/{dagre-BM42HDAG-B71wyESx.js → dagre-BM42HDAG-CNK_Lkn1.js} +1 -1
  25. package/dist/client/assets/{diagram-2AECGRRQ-D7Xht5lG.js → diagram-2AECGRRQ-BGKodAdj.js} +1 -1
  26. package/dist/client/assets/{diagram-5GNKFQAL-BIL2jzaH.js → diagram-5GNKFQAL-O7IcwCBh.js} +1 -1
  27. package/dist/client/assets/{diagram-KO2AKTUF-CKLHtkTQ.js → diagram-KO2AKTUF-BzuzpIm4.js} +1 -1
  28. package/dist/client/assets/{diagram-LMA3HP47-CoTDrm1f.js → diagram-LMA3HP47-C6xFuQYj.js} +1 -1
  29. package/dist/client/assets/{diagram-OG6HWLK6-a6qcioel.js → diagram-OG6HWLK6-hp2uvo99.js} +1 -1
  30. package/dist/client/assets/{erDiagram-TEJ5UH35-CUTe5tSP.js → erDiagram-TEJ5UH35-CiiZ8B7W.js} +1 -1
  31. package/dist/client/assets/{flowDiagram-I6XJVG4X-CSDL4PU-.js → flowDiagram-I6XJVG4X-CMXv6xN7.js} +1 -1
  32. package/dist/client/assets/{ganttDiagram-6RSMTGT7-Ck4JCO9N.js → ganttDiagram-6RSMTGT7-EP8OVqmy.js} +1 -1
  33. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-D8h23S3l.js → gitGraphDiagram-PVQCEYII-Dacq4hgw.js} +1 -1
  34. package/dist/client/assets/index-a8IeMnRR.css +2 -0
  35. package/dist/client/assets/index-uGt4qt5t.js +287 -0
  36. package/dist/client/assets/{infoDiagram-5YYISTIA-Bq1wj1vH.js → infoDiagram-5YYISTIA-DpTIfB1a.js} +1 -1
  37. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-C6ry_1gD.js → ishikawaDiagram-YF4QCWOH-DOcryUZC.js} +1 -1
  38. package/dist/client/assets/{journeyDiagram-JHISSGLW-BCoSw_Ye.js → journeyDiagram-JHISSGLW-DgEfwhed.js} +1 -1
  39. package/dist/client/assets/{kanban-definition-UN3LZRKU-CvHdWXxq.js → kanban-definition-UN3LZRKU-Bg9Kz1IT.js} +1 -1
  40. package/dist/client/assets/{line-DDPHAHbi.js → line-DGt3zplT.js} +1 -1
  41. package/dist/client/assets/{mermaid-parser.core-B7v3eJbR.js → mermaid-parser.core-CeZgcMLs.js} +1 -1
  42. package/dist/client/assets/{mermaid.core-DoJjZ2zS.js → mermaid.core-Bp6d14EP.js} +3 -3
  43. package/dist/client/assets/{mindmap-definition-RKZ34NQL-D8uwnlrG.js → mindmap-definition-RKZ34NQL-CyJdo6SE.js} +1 -1
  44. package/dist/client/assets/{pieDiagram-4H26LBE5-B2zLClZg.js → pieDiagram-4H26LBE5-elm12Uf5.js} +1 -1
  45. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-DGGYHTHx.js → quadrantDiagram-W4KKPZXB-BXuIBixh.js} +1 -1
  46. package/dist/client/assets/{requirementDiagram-4Y6WPE33-JfCBqWur.js → requirementDiagram-4Y6WPE33-C5rIaCf4.js} +1 -1
  47. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-D9nUF-4P.js → sankeyDiagram-5OEKKPKP-CIYPcDTl.js} +1 -1
  48. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DGnNkDzT.js → sequenceDiagram-3UESZ5HK-CX_go9-1.js} +1 -1
  49. package/dist/client/assets/{stateDiagram-AJRCARHV-CFZlnYcA.js → stateDiagram-AJRCARHV-CYbsPFSQ.js} +1 -1
  50. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-QZ_UdR0J.js +1 -0
  51. package/dist/client/assets/{timeline-definition-PNZ67QCA-C-KYYKMX.js → timeline-definition-PNZ67QCA-B3pBx_YB.js} +1 -1
  52. package/dist/client/assets/{vennDiagram-CIIHVFJN-C3MGIjT1.js → vennDiagram-CIIHVFJN-B1Z6hLI-.js} +1 -1
  53. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-CUD7E4c3.js → wardleyDiagram-YWT4CUSO-BvJEPN2P.js} +1 -1
  54. package/dist/client/assets/{xychartDiagram-2RQKCTM6-CM2Q4-TE.js → xychartDiagram-2RQKCTM6-CKavkWIt.js} +1 -1
  55. package/dist/client/index.html +2 -2
  56. package/dist/server/db.js +63 -4
  57. package/dist/server/db.js.map +1 -1
  58. package/dist/server/index.js +55 -0
  59. package/dist/server/index.js.map +1 -1
  60. package/dist/server/lib/agent.js +277 -299
  61. package/dist/server/lib/agent.js.map +1 -1
  62. package/dist/server/lib/agentOutputLanguage.js +11 -0
  63. package/dist/server/lib/agentOutputLanguage.js.map +1 -0
  64. package/dist/server/lib/agentProvider.js.map +1 -1
  65. package/dist/server/lib/agentRuns.js +68 -4
  66. package/dist/server/lib/agentRuns.js.map +1 -1
  67. package/dist/server/lib/appLocale.js +19 -0
  68. package/dist/server/lib/appLocale.js.map +1 -0
  69. package/dist/server/lib/buildExecutionEnvironment.js +92 -1
  70. package/dist/server/lib/buildExecutionEnvironment.js.map +1 -1
  71. package/dist/server/lib/chatOperations.js +10 -3
  72. package/dist/server/lib/chatOperations.js.map +1 -1
  73. package/dist/server/lib/conversationResume.js +56 -3
  74. package/dist/server/lib/conversationResume.js.map +1 -1
  75. package/dist/server/lib/dockerSandboxOpencodeSessionOperations.js +81 -25
  76. package/dist/server/lib/dockerSandboxOpencodeSessionOperations.js.map +1 -1
  77. package/dist/server/lib/dockerSandboxReleaseProfiles.js +36 -7
  78. package/dist/server/lib/dockerSandboxReleaseProfiles.js.map +1 -1
  79. package/dist/server/lib/executionEnvironmentRoutes.js +71 -4
  80. package/dist/server/lib/executionEnvironmentRoutes.js.map +1 -1
  81. package/dist/server/lib/executionEnvironmentValidation.js +199 -19
  82. package/dist/server/lib/executionEnvironmentValidation.js.map +1 -1
  83. package/dist/server/lib/executionEnvironmentValidationEvidence.js +140 -0
  84. package/dist/server/lib/executionEnvironmentValidationEvidence.js.map +1 -0
  85. package/dist/server/lib/executionEnvironmentValidationOperations.js +13 -0
  86. package/dist/server/lib/executionEnvironmentValidationOperations.js.map +1 -1
  87. package/dist/server/lib/executionRetryContext.js +13 -0
  88. package/dist/server/lib/executionRetryContext.js.map +1 -1
  89. package/dist/server/lib/figmaResources.js +9 -2
  90. package/dist/server/lib/figmaResources.js.map +1 -1
  91. package/dist/server/lib/hostExecutionEnvironment.js +14 -2
  92. package/dist/server/lib/hostExecutionEnvironment.js.map +1 -1
  93. package/dist/server/lib/i18n/index.js +3 -2
  94. package/dist/server/lib/i18n/index.js.map +1 -1
  95. package/dist/server/lib/i18n/resources.js +0 -1
  96. package/dist/server/lib/i18n/resources.js.map +1 -1
  97. package/dist/server/lib/lightweightPrompt.js +4 -0
  98. package/dist/server/lib/lightweightPrompt.js.map +1 -1
  99. package/dist/server/lib/models.js +58 -18
  100. package/dist/server/lib/models.js.map +1 -1
  101. package/dist/server/lib/opencodeAgentProvider.js +54 -48
  102. package/dist/server/lib/opencodeAgentProvider.js.map +1 -1
  103. package/dist/server/lib/opencodeCli.js +244 -0
  104. package/dist/server/lib/opencodeCli.js.map +1 -0
  105. package/dist/server/lib/opencodePromptOutput.js +11 -65
  106. package/dist/server/lib/opencodePromptOutput.js.map +1 -1
  107. package/dist/server/lib/opencodeSessionOperations.js +44 -28
  108. package/dist/server/lib/opencodeSessionOperations.js.map +1 -1
  109. package/dist/server/lib/opencodeSessionProvenance.js +23 -0
  110. package/dist/server/lib/opencodeSessionProvenance.js.map +1 -0
  111. package/dist/server/lib/opencodeStream.js +263 -0
  112. package/dist/server/lib/opencodeStream.js.map +1 -0
  113. package/dist/server/lib/opencodeTaskSessions.js +3 -4
  114. package/dist/server/lib/opencodeTaskSessions.js.map +1 -1
  115. package/dist/server/lib/opencodeV2SessionOperations.js +453 -0
  116. package/dist/server/lib/opencodeV2SessionOperations.js.map +1 -0
  117. package/dist/server/lib/run.js +27 -41
  118. package/dist/server/lib/run.js.map +1 -1
  119. package/dist/server/lib/runProcessIdentity.js +10 -2
  120. package/dist/server/lib/runProcessIdentity.js.map +1 -1
  121. package/dist/server/lib/runProcesses.js +52 -19
  122. package/dist/server/lib/runProcesses.js.map +1 -1
  123. package/dist/server/lib/runServiceStop.js +62 -0
  124. package/dist/server/lib/runServiceStop.js.map +1 -0
  125. package/dist/server/lib/runServices.js +63 -4
  126. package/dist/server/lib/runServices.js.map +1 -1
  127. package/dist/server/lib/runSessionLifecycle.js +25 -0
  128. package/dist/server/lib/runSessionLifecycle.js.map +1 -1
  129. package/dist/server/lib/runtimePaths.js +7 -4
  130. package/dist/server/lib/runtimePaths.js.map +1 -1
  131. package/dist/server/lib/serviceRunLogs.js +179 -0
  132. package/dist/server/lib/serviceRunLogs.js.map +1 -0
  133. package/dist/server/lib/specOperations.js +7 -2
  134. package/dist/server/lib/specOperations.js.map +1 -1
  135. package/dist/server/lib/specReviewContext.js +3 -2
  136. package/dist/server/lib/specReviewContext.js.map +1 -1
  137. package/dist/server/lib/toolUpgrade.js +54 -5
  138. package/dist/server/lib/toolUpgrade.js.map +1 -1
  139. package/dist/server/lib/types.js.map +1 -1
  140. package/dist/server/workers/build.js +47 -9
  141. package/dist/server/workers/build.js.map +1 -1
  142. package/dist/server/workers/chat.js +74 -10
  143. package/dist/server/workers/chat.js.map +1 -1
  144. package/dist/server/workers/followUp.js +59 -22
  145. package/dist/server/workers/followUp.js.map +1 -1
  146. package/dist/server/workers/plan.js +109 -169
  147. package/dist/server/workers/plan.js.map +1 -1
  148. package/dist/server/workers/planFollowUp.js +27 -7
  149. package/dist/server/workers/planFollowUp.js.map +1 -1
  150. package/dist/server/workers/review.js +43 -10
  151. package/dist/server/workers/review.js.map +1 -1
  152. package/dist/server/workers/specReview.js +1 -0
  153. package/dist/server/workers/specReview.js.map +1 -1
  154. package/dist/server/workers/specSession.js +42 -5
  155. package/dist/server/workers/specSession.js.map +1 -1
  156. package/dist/shared/i18n/locales.js +12 -0
  157. package/dist/shared/i18n/locales.js.map +1 -0
  158. package/package.json +1 -1
  159. package/dist/client/assets/channel-BsoUrvI0.js +0 -1
  160. package/dist/client/assets/classDiagram-4FO5ZUOK-D79OdDcf.js +0 -1
  161. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CyG7JUxO.js +0 -1
  162. package/dist/client/assets/index-Ckj_syqH.js +0 -287
  163. package/dist/client/assets/index-RM0FaS4q.css +0 -2
  164. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-BB3Eu4sn.js +0 -1
@@ -0,0 +1,453 @@
1
+ import { execFile as execFileCallback } from 'node:child_process';
2
+ import { EMPTY_OPENCODE_USAGE_SNAPSHOT, extractOpencodeUsageSnapshot, parseOpencodeTaskEnvelope, } from './opencodeSessionOperations.js';
3
+ const API_TIMEOUT_MS = 10_000;
4
+ const API_OUTPUT_LIMIT_BYTES = 4 * 1024 * 1024;
5
+ export const ARCHON_OPENCODE_SESSION_CONTRACT_VERSION = 1;
6
+ export class OpencodeV2SessionApiError extends Error {
7
+ kind;
8
+ constructor(kind, message, options = {}) {
9
+ super(message, options);
10
+ this.name = 'OpencodeV2SessionApiError';
11
+ this.kind = kind;
12
+ }
13
+ }
14
+ const isObject = (value) => (value !== null && typeof value === 'object' && !Array.isArray(value));
15
+ const requiredString = (value, field) => {
16
+ if (typeof value !== 'string' || value.trim() === '') {
17
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode session API returned an invalid ${field}.`);
18
+ }
19
+ return value.trim();
20
+ };
21
+ const requiredText = (value, field) => {
22
+ if (typeof value !== 'string') {
23
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode session API returned an invalid ${field}.`);
24
+ }
25
+ return value;
26
+ };
27
+ const optionalString = (value, field) => {
28
+ if (value === undefined || value === null) {
29
+ return null;
30
+ }
31
+ if (typeof value !== 'string') {
32
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode session API returned an invalid ${field}.`);
33
+ }
34
+ return value.trim() || null;
35
+ };
36
+ const requiredNumber = (value, field) => {
37
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
38
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode session API returned an invalid ${field}.`);
39
+ }
40
+ return value;
41
+ };
42
+ const decodeJson = (output, operation) => {
43
+ let value;
44
+ try {
45
+ value = JSON.parse(output);
46
+ }
47
+ catch (error) {
48
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned malformed JSON.`, { cause: error });
49
+ }
50
+ return value;
51
+ };
52
+ const decodeDataEnvelope = (value, operation) => {
53
+ if (!isObject(value)
54
+ || !Object.hasOwn(value, 'data')
55
+ || Object.keys(value).some(key => key !== 'data')) {
56
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned an unknown response envelope.`);
57
+ }
58
+ return value.data;
59
+ };
60
+ const decodePageEnvelope = (value, operation) => {
61
+ if (!isObject(value)
62
+ || !Array.isArray(value.data)
63
+ || !isObject(value.cursor)
64
+ || Object.keys(value).some(key => key !== 'data' && key !== 'cursor')
65
+ || Object.keys(value.cursor).some(key => key !== 'previous' && key !== 'next')) {
66
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned an invalid paginated response envelope.`);
67
+ }
68
+ return {
69
+ data: value.data,
70
+ nextCursor: optionalString(value.cursor.next, 'pagination cursor'),
71
+ };
72
+ };
73
+ const decodeSession = (value, operation) => {
74
+ if (!isObject(value) || !isObject(value.time) || !isObject(value.location)) {
75
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned an invalid session.`);
76
+ }
77
+ return {
78
+ id: requiredString(value.id, 'session id'),
79
+ directory: requiredString(value.location.directory, 'session directory'),
80
+ parentId: optionalString(value.parentID, 'session parent id'),
81
+ title: optionalString(value.title, 'session title'),
82
+ timeCreated: requiredNumber(value.time.created, 'session creation time'),
83
+ data: value,
84
+ };
85
+ };
86
+ const decodeSessionList = (value, operation) => {
87
+ if (!Array.isArray(value)) {
88
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned a non-array session collection.`);
89
+ }
90
+ return value.map(session => decodeSession(session, operation));
91
+ };
92
+ const decodeToolContent = (value, operation) => {
93
+ if (!Array.isArray(value)) {
94
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned invalid tool content.`);
95
+ }
96
+ return value.map(item => {
97
+ if (!isObject(item) || (item.type !== 'text' && item.type !== 'file')) {
98
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned invalid tool content.`);
99
+ }
100
+ if (item.type === 'text') {
101
+ requiredText(item.text, 'tool text content');
102
+ }
103
+ else {
104
+ requiredString(item.uri, 'tool file URI');
105
+ requiredString(item.mime, 'tool file MIME type');
106
+ }
107
+ return item;
108
+ });
109
+ };
110
+ const toolOutputText = (content) => content.flatMap(item => (item.type === 'text' && typeof item.text === 'string' ? [item.text] : [])).join('\n').trim() || null;
111
+ const decodeAssistantContent = (value, operation, messageId, index) => {
112
+ if (!isObject(value)) {
113
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned invalid assistant content.`);
114
+ }
115
+ const type = requiredString(value.type, 'assistant content type');
116
+ if (type === 'text' || type === 'reasoning') {
117
+ return {
118
+ ...value,
119
+ id: `${messageId}:${type}:${index}`,
120
+ text: requiredText(value.text, `${type} content`),
121
+ };
122
+ }
123
+ if (type !== 'tool' || !isObject(value.state) || !isObject(value.time)) {
124
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned invalid assistant tool content.`);
125
+ }
126
+ const status = requiredString(value.state.status, 'assistant tool status');
127
+ if (!['streaming', 'running', 'completed', 'error'].includes(status)) {
128
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned an unknown assistant tool status.`);
129
+ }
130
+ requiredNumber(value.time.created, 'assistant tool creation time');
131
+ if (status === 'streaming' && typeof value.state.input !== 'string') {
132
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned invalid streaming tool input.`);
133
+ }
134
+ if (status !== 'streaming' && !isObject(value.state.input)) {
135
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned invalid assistant tool input.`);
136
+ }
137
+ if (value.state.metadata !== undefined && !isObject(value.state.metadata)) {
138
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned invalid assistant tool metadata.`);
139
+ }
140
+ const content = value.state.content === undefined
141
+ ? []
142
+ : decodeToolContent(value.state.content, operation);
143
+ if (status === 'completed' && content.length === 0) {
144
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned completed tool content without output.`);
145
+ }
146
+ const output = toolOutputText(content);
147
+ return {
148
+ type: 'tool',
149
+ id: requiredString(value.id, 'assistant tool id'),
150
+ tool: requiredString(value.name, 'assistant tool name'),
151
+ time: value.time,
152
+ state: {
153
+ status,
154
+ input: value.state.input,
155
+ ...(output ? { output } : {}),
156
+ ...(isObject(value.state.metadata) ? { metadata: value.state.metadata } : {}),
157
+ ...(isObject(value.state.error) || typeof value.state.error === 'string'
158
+ ? { error: value.state.error }
159
+ : {}),
160
+ },
161
+ };
162
+ };
163
+ const decodeMessage = (value, operation) => {
164
+ if (!isObject(value) || !isObject(value.time)) {
165
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned an invalid projected message.`);
166
+ }
167
+ const messageId = requiredString(value.id, 'message id');
168
+ const role = requiredString(value.type, 'message type');
169
+ const rawContent = role === 'assistant' ? value.content : [];
170
+ if (!Array.isArray(rawContent)) {
171
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned assistant content without a collection.`);
172
+ }
173
+ const parts = rawContent.map((part, index) => decodeAssistantContent(part, operation, messageId, index));
174
+ return {
175
+ id: messageId,
176
+ role,
177
+ timeCreated: requiredNumber(value.time.created, 'message creation time'),
178
+ timeCompleted: value.time.completed === undefined || value.time.completed === null
179
+ ? null
180
+ : requiredNumber(value.time.completed, 'message completion time'),
181
+ data: value,
182
+ parts,
183
+ };
184
+ };
185
+ const decodeMessageList = (value, operation) => {
186
+ if (!Array.isArray(value)) {
187
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} returned a non-array message collection.`);
188
+ }
189
+ return value.map(message => decodeMessage(message, operation));
190
+ };
191
+ const normalizeTitle = (title) => title && !/^New session\b/i.test(title) ? title : null;
192
+ const toMetadata = (session) => ({
193
+ id: session.id,
194
+ title: normalizeTitle(session.title),
195
+ });
196
+ const getNestedString = (value, path) => {
197
+ let current = value;
198
+ for (const segment of path) {
199
+ if (!isObject(current)) {
200
+ return null;
201
+ }
202
+ current = current[segment];
203
+ }
204
+ return typeof current === 'string' && current.trim() ? current.trim() : null;
205
+ };
206
+ const mapTaskStatus = (value) => {
207
+ if (value === 'completed' || value === 'complete' || value === 'done') {
208
+ return 'done';
209
+ }
210
+ if (value === 'error' || value === 'failed') {
211
+ return 'error';
212
+ }
213
+ return 'running';
214
+ };
215
+ const taskLabel = (part) => {
216
+ const description = getNestedString(part, ['state', 'input', 'description'])
217
+ ?? getNestedString(part, ['state', 'input', 'title'])
218
+ ?? getNestedString(part, ['state', 'input', 'task'])
219
+ ?? 'Subagent';
220
+ const firstLine = description.split('\n')[0] ?? description;
221
+ const clipped = firstLine.length > 120 ? `${firstLine.slice(0, 117)}...` : firstLine;
222
+ return clipped.startsWith('Subagent:') ? clipped : `Subagent: ${clipped}`;
223
+ };
224
+ const mergeUsage = (current, next) => ({
225
+ usage_snapshot_context_window: next.usage_snapshot_context_window ?? current.usage_snapshot_context_window,
226
+ usage_snapshot_max_output_tokens: next.usage_snapshot_max_output_tokens ?? current.usage_snapshot_max_output_tokens,
227
+ usage_snapshot_total_tokens: next.usage_snapshot_total_tokens ?? current.usage_snapshot_total_tokens,
228
+ usage_snapshot_input_tokens: next.usage_snapshot_input_tokens ?? current.usage_snapshot_input_tokens,
229
+ usage_snapshot_output_tokens: next.usage_snapshot_output_tokens ?? current.usage_snapshot_output_tokens,
230
+ usage_snapshot_cache_read_tokens: next.usage_snapshot_cache_read_tokens ?? current.usage_snapshot_cache_read_tokens,
231
+ usage_snapshot_reasoning_tokens: next.usage_snapshot_reasoning_tokens ?? current.usage_snapshot_reasoning_tokens,
232
+ usage_snapshot_cost: next.usage_snapshot_cost ?? current.usage_snapshot_cost,
233
+ });
234
+ const partTime = (part, messageTime) => {
235
+ if (!isObject(part.time)) {
236
+ return messageTime;
237
+ }
238
+ const candidate = part.time.created ?? part.time.start;
239
+ return typeof candidate === 'number' && Number.isFinite(candidate) ? candidate : messageTime;
240
+ };
241
+ const apiArgs = (operation, parameters) => [
242
+ 'api',
243
+ operation,
244
+ ...Object.entries(parameters).flatMap(([name, value]) => ['--param', `${name}=${String(value)}`]),
245
+ ];
246
+ const createApiClient = (runner) => async (operation, parameters = {}, options = {}) => {
247
+ let result;
248
+ try {
249
+ result = await runner(apiArgs(operation, parameters), options);
250
+ }
251
+ catch (error) {
252
+ throw new OpencodeV2SessionApiError('unavailable', `OpenCode ${operation} is unavailable.`, { cause: error });
253
+ }
254
+ if (result.exitCode !== 0) {
255
+ const detail = result.stderr.trim().slice(0, 300);
256
+ throw new OpencodeV2SessionApiError('unavailable', `OpenCode ${operation} is unavailable${detail ? `: ${detail}` : '.'}`);
257
+ }
258
+ return decodeJson(result.stdout, operation);
259
+ };
260
+ const listApiCollection = async (call, operation, parameters, options = {}) => {
261
+ const data = [];
262
+ const observedCursors = new Set();
263
+ let nextParameters = parameters;
264
+ while (true) {
265
+ const page = decodePageEnvelope(await call(operation, nextParameters, options), operation);
266
+ data.push(...page.data);
267
+ if (!page.nextCursor) {
268
+ return data;
269
+ }
270
+ if (observedCursors.has(page.nextCursor)) {
271
+ throw new OpencodeV2SessionApiError('unsupported', `OpenCode ${operation} repeated a pagination cursor.`);
272
+ }
273
+ observedCursors.add(page.nextCursor);
274
+ nextParameters = {
275
+ ...('sessionID' in parameters ? { sessionID: parameters.sessionID } : {}),
276
+ cursor: page.nextCursor,
277
+ };
278
+ }
279
+ };
280
+ export const createOpencodeV2SessionOperations = (runner) => {
281
+ const call = createApiClient(runner);
282
+ const listMessages = async (sessionId) => {
283
+ const messages = decodeMessageList(await listApiCollection(call, 'session.message.list', {
284
+ sessionID: sessionId,
285
+ limit: 200,
286
+ order: 'asc',
287
+ }), 'session.message.list');
288
+ return messages;
289
+ };
290
+ const getExactSession = async (sessionId, cwd) => {
291
+ const session = decodeSession(decodeDataEnvelope(await call('session.get', { sessionID: sessionId }, cwd ? { cwd } : {}), 'session.get'), 'session.get');
292
+ if (session.id !== sessionId) {
293
+ throw new OpencodeV2SessionApiError('unsupported', 'OpenCode exact-session lookup returned a different session.');
294
+ }
295
+ return session;
296
+ };
297
+ return {
298
+ supportsTaskSessions: async () => true,
299
+ findSessionById: async (sessionId) => toMetadata(await getExactSession(sessionId)),
300
+ findLatestSessionAfter: async (createdAfter, scope) => {
301
+ if (!scope.directory) {
302
+ return null;
303
+ }
304
+ const sessions = decodeSessionList(await listApiCollection(call, 'session.list', { directory: scope.directory, limit: 200, order: 'desc' }, { cwd: scope.directory }), 'session.list')
305
+ .filter(session => session.directory === scope.directory && session.timeCreated > createdAfter)
306
+ .sort((left, right) => right.timeCreated - left.timeCreated || right.id.localeCompare(left.id));
307
+ return sessions[0] ? toMetadata(sessions[0]) : null;
308
+ },
309
+ findParentSessionSince: async (createdSince, scope) => {
310
+ if (!scope.directory) {
311
+ return null;
312
+ }
313
+ const sessions = decodeSessionList(await listApiCollection(call, 'session.list', { directory: scope.directory, parentID: 'null', limit: 200, order: 'asc' }, { cwd: scope.directory }), 'session.list')
314
+ .filter(session => session.directory === scope.directory
315
+ && session.parentId === null
316
+ && session.timeCreated >= createdSince)
317
+ .sort((left, right) => left.timeCreated - right.timeCreated || left.id.localeCompare(right.id));
318
+ return sessions[0]?.id ?? null;
319
+ },
320
+ hasCompletedAssistantSince: async (sessionId, createdSince) => ((await listMessages(sessionId)).some(message => (message.role === 'assistant'
321
+ && message.timeCreated >= createdSince
322
+ && message.timeCompleted !== null))),
323
+ readUsageSnapshot: async (sessionId, createdSince = null) => {
324
+ const session = await getExactSession(sessionId);
325
+ const messages = (await listMessages(sessionId))
326
+ .filter(message => message.role === 'assistant'
327
+ && message.timeCompleted !== null
328
+ && (createdSince === null || message.timeCreated >= createdSince))
329
+ .sort((left, right) => right.timeCreated - left.timeCreated || right.id.localeCompare(left.id));
330
+ const messageUsage = messages[0] ? extractOpencodeUsageSnapshot(messages[0].data) : {};
331
+ return mergeUsage(mergeUsage(EMPTY_OPENCODE_USAGE_SNAPSHOT, extractOpencodeUsageSnapshot(session.data)), messageUsage);
332
+ },
333
+ listTaskInvocations: async (parentSessionId, createdSince) => {
334
+ const messages = await listMessages(parentSessionId);
335
+ return messages.flatMap(message => message.parts.flatMap(part => {
336
+ const created = partTime(part, message.timeCreated);
337
+ const tool = typeof part.tool === 'string' ? part.tool.toLowerCase().replace(/[^a-z0-9]/g, '') : '';
338
+ if (part.type !== 'tool' || !['task', 'subagent', 'agent'].includes(tool) || created < createdSince) {
339
+ return [];
340
+ }
341
+ const callId = requiredString(part.callID ?? part.callId ?? part.id, 'task call id');
342
+ const output = getNestedString(part, ['state', 'output']);
343
+ const envelope = parseOpencodeTaskEnvelope(output);
344
+ const childSessionId = getNestedString(part, ['state', 'metadata', 'sessionID'])
345
+ ?? getNestedString(part, ['state', 'metadata', 'sessionId'])
346
+ ?? envelope?.childSessionId
347
+ ?? null;
348
+ const state = getNestedString(part, ['state', 'status']) ?? envelope?.state ?? null;
349
+ return [{
350
+ callId,
351
+ label: taskLabel(part),
352
+ status: mapTaskStatus(state?.toLowerCase() ?? null),
353
+ output: envelope ? envelope.result : output,
354
+ childSessionId,
355
+ timeCreated: created,
356
+ }];
357
+ })).sort((left, right) => left.timeCreated - right.timeCreated || left.callId.localeCompare(right.callId));
358
+ },
359
+ listChildSessions: async (parentSessionId, createdSince, scope) => decodeSessionList(await listApiCollection(call, 'session.list', {
360
+ directory: scope.directory,
361
+ parentID: parentSessionId,
362
+ limit: 200,
363
+ order: 'asc',
364
+ }, { cwd: scope.directory }), 'session.list').filter(session => (session.directory === scope.directory
365
+ && session.parentId === parentSessionId
366
+ && session.timeCreated >= createdSince))
367
+ .sort((left, right) => left.timeCreated - right.timeCreated || left.id.localeCompare(right.id))
368
+ .map(session => ({
369
+ id: session.id,
370
+ title: session.title,
371
+ timeCreated: session.timeCreated,
372
+ })),
373
+ listSessionParts: async (sessionId, createdSince) => (await listMessages(sessionId)).flatMap(message => (message.parts.flatMap(part => {
374
+ const timeCreated = partTime(part, message.timeCreated);
375
+ if (createdSince !== undefined && timeCreated < createdSince) {
376
+ return [];
377
+ }
378
+ return [{
379
+ id: requiredString(part.id, 'message part id'),
380
+ messageId: message.id,
381
+ role: message.role,
382
+ timeCreated,
383
+ data: part,
384
+ }];
385
+ }))).sort((left, right) => left.timeCreated - right.timeCreated || left.id.localeCompare(right.id)),
386
+ };
387
+ };
388
+ export const createHostOpencodeV2ApiRunner = () => (args, options = {}) => new Promise((resolve, reject) => {
389
+ execFileCallback('opencode', [...args], {
390
+ cwd: options.cwd,
391
+ signal: options.signal,
392
+ timeout: API_TIMEOUT_MS,
393
+ maxBuffer: API_OUTPUT_LIMIT_BYTES,
394
+ encoding: 'utf8',
395
+ windowsHide: true,
396
+ }, (error, stdout, stderr) => {
397
+ if (error) {
398
+ reject(error);
399
+ return;
400
+ }
401
+ resolve({ exitCode: 0, stdout, stderr });
402
+ });
403
+ });
404
+ export const hostOpencodeV2SessionOperations = createOpencodeV2SessionOperations(createHostOpencodeV2ApiRunner());
405
+ export const probeOpencodeV2SessionApi = async ({ runner, directory, sessionId, expectedCompletion, signal, }) => {
406
+ const call = createApiClient(runner);
407
+ try {
408
+ const sessions = decodeSessionList(await listApiCollection(call, 'session.list', {
409
+ directory,
410
+ limit: 200,
411
+ order: 'desc',
412
+ }, { cwd: directory, signal }), 'session.list');
413
+ if (sessions.some(session => session.directory !== directory) || !sessions.some(session => session.id === sessionId)) {
414
+ throw new OpencodeV2SessionApiError('unsupported', 'OpenCode directory-scoped session list did not contain only the destination session directory.');
415
+ }
416
+ const exact = decodeSession(decodeDataEnvelope(await call('session.get', { sessionID: sessionId }, { cwd: directory, signal }), 'session.get'), 'session.get');
417
+ if (exact.id !== sessionId || exact.directory !== directory) {
418
+ throw new OpencodeV2SessionApiError('unsupported', 'OpenCode exact-session lookup returned a different session.');
419
+ }
420
+ const messages = decodeMessageList(await listApiCollection(call, 'session.message.list', {
421
+ sessionID: sessionId,
422
+ limit: 200,
423
+ order: 'asc',
424
+ }, { cwd: directory, signal }), 'session.message.list');
425
+ const hasCompletion = messages.some(message => message.role === 'assistant'
426
+ && message.timeCompleted !== null
427
+ && message.parts.some(part => part.type === 'text'
428
+ && typeof part.text === 'string'
429
+ && part.text.trim() === expectedCompletion));
430
+ if (!hasCompletion) {
431
+ throw new OpencodeV2SessionApiError('unsupported', 'OpenCode session messages did not contain the destination completion.');
432
+ }
433
+ const children = decodeSessionList(await listApiCollection(call, 'session.list', {
434
+ parentID: sessionId,
435
+ limit: 200,
436
+ order: 'asc',
437
+ }, { cwd: directory, signal }), 'session.list');
438
+ if (children.some(child => child.parentId !== sessionId)) {
439
+ throw new OpencodeV2SessionApiError('unsupported', 'OpenCode child-session lookup returned an unrelated session.');
440
+ }
441
+ return { status: 'compatible', contractVersion: ARCHON_OPENCODE_SESSION_CONTRACT_VERSION };
442
+ }
443
+ catch (error) {
444
+ if (error instanceof OpencodeV2SessionApiError) {
445
+ return { status: error.kind, reason: error.message };
446
+ }
447
+ return {
448
+ status: 'unavailable',
449
+ reason: error instanceof Error ? error.message : 'OpenCode session API is unavailable.',
450
+ };
451
+ }
452
+ };
453
+ //# sourceMappingURL=opencodeV2SessionOperations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencodeV2SessionOperations.js","sourceRoot":"","sources":["../../../server/lib/opencodeV2SessionOperations.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,10 @@
1
1
  import { spawn } from "child_process";
2
+ import { randomUUID } from "crypto";
2
3
  import { requireExecutableAgent } from "./agentCatalog.js";
3
4
  import { assertHostSessionRequest, createHostRunSession, createRunConfigSnapshot, finishHostService, queueHostServices, serviceIdentity } from "./hostRunSession.js";
4
- import { isProcessAlive, killManagedProcess, runCommand, runWorkspaceSetup, stopRunProcesses, trackExecutionHandle, waitForProcessesToExit } from "./runProcesses.js";
5
+ import { isProcessAlive, killManagedProcess, runCommand, runWorkspaceSetup, stopRunProcesses, trackExecutionHandle } from "./runProcesses.js";
5
6
  import { createRunServiceLauncher } from "./runServices.js";
7
+ import { stopHostService } from "./runServiceStop.js";
6
8
  import { withHostServiceRecovery } from "./hostServiceRunProvider.js";
7
9
  import { createHostSessionSettler, finalizeDurableRun } from "./runSessionLifecycle.js";
8
10
  import { existsSync } from "fs";
@@ -10,11 +12,11 @@ import { getLocalProjectBranch, resolveWorktreePath } from "./git.js";
10
12
  import { getProjectById, getProjectRunConfig } from "./projects.js";
11
13
  import { resolveHelperModelConfig } from "./agentModelConfig.js";
12
14
  import config from "./config.js";
13
- import { createIdlePreviewStatus, createRunPreviewStatus, isPreviewService, } from "./preview.js";
15
+ import { createIdlePreviewStatus, createRunPreviewStatus, } from "./preview.js";
14
16
  import { deactivatePreviewProxyForProject, } from "./previewProxy.js";
15
17
  import { resolveShell } from "./shell.js";
16
18
  import { isTicketRunSetupReady } from "./ticketDependencies.js";
17
- import { listTicketsInRunContext, resolveTicketBranch, resolveTicketContextKey, resolveTicketTool, } from "./tickets.js";
19
+ import { listTicketsInRunContext, getBundle, resolveTicketBranch, resolveTicketContextKey, resolveTicketTool, } from "./tickets.js";
18
20
  import { createWorkspaceProcessEnvironment } from "./workspaceProcessEnvironment.js";
19
21
  import { resolveWorkloadExecutionEnvironment } from "./buildExecutionEnvironment.js";
20
22
  import { classifyTicketExecutionTarget, createExecutionTargetKey, resolveExecutionTarget, resolveExecutionTargetLocation, } from "./executionTargets.js";
@@ -22,6 +24,7 @@ import { createServiceRun, markServiceRunAllocationStarted, hasActiveProjectServ
22
24
  import { appendLifecycleEvent, transitionExecutionRun } from "./executionRuns.js";
23
25
  import { forceReleaseProjectServiceCleanup, retryProjectServiceCleanup } from "./serviceRunCleanup.js";
24
26
  import { registerReadyPreviewCandidateResolver } from "./runPreviewCandidate.js";
27
+ import { startServiceRunLog, stopServiceRunLog } from './serviceRunLogs.js';
25
28
  export { resolveReadyPreviewCandidate } from "./runPreviewCandidate.js";
26
29
  const runningProcesses = new Map();
27
30
  const lastRunStatuses = new Map();
@@ -262,6 +265,9 @@ const clearRunState = (contextKey, state, onStopped) => {
262
265
  return;
263
266
  }
264
267
  deactivatePreviewProxyForProject(state.active_run.project_id);
268
+ if (state.run_log) {
269
+ stopServiceRunLog(state.run_log);
270
+ }
265
271
  state.preview_log_buffer = "";
266
272
  if (state.active_run.project_id && state.active_run.config_snapshot) {
267
273
  lastRunStatuses.set(state.active_run.project_id, {
@@ -275,13 +281,16 @@ const clearRunState = (contextKey, state, onStopped) => {
275
281
  const canCreateDurableServiceRun = (project, targetDescriptor) => Boolean(targetDescriptor
276
282
  && project.id
277
283
  && project.active_execution_profile_revision_id);
278
- const startRun = ({ activeRun, cwd, executionAgent, executionModel, logLabelPrefix, onStopped, project, runConfig, skipSetup = false, targetDescriptor, profileSelection, serviceId, sessionId, }) => {
284
+ const startRun = ({ activeRun, cwd, executionAgent, executionModel, logLabelPrefix, onStopped, project, runConfig, skipSetup = false, targetDescriptor, profileSelection, serviceId, sessionId, ticketTitle, }) => {
279
285
  requireExecutableAgent(executionAgent);
280
286
  const contextKey = activeRun.context_key;
281
287
  const admittedProvider = profileSelection?.reason === "explicit_service_host_override"
282
288
  ? "host" : project?.build_execution_provider ?? "host";
283
289
  const existing = runningProcesses.get(contextKey);
284
290
  if (existing) {
291
+ if (existing.active_run.project_id !== project.id) {
292
+ throw new RunAdmissionError('service_context_conflict', 'The service run context belongs to another project');
293
+ }
285
294
  if (existing.admission_pending) {
286
295
  throw new RunAdmissionError("service_admission_pending", "Service admission is still pending. Retry after admission settles.");
287
296
  }
@@ -395,6 +404,17 @@ const startRun = ({ activeRun, cwd, executionAgent, executionModel, logLabelPref
395
404
  throw new RunAdmissionError("service_admission_rejected", getErrorMessage(error));
396
405
  }
397
406
  }
407
+ if (project.id && activeRun.project_id === project.id) {
408
+ const source = activeRun.kind === 'ticket'
409
+ ? { kind: 'ticket', ticket_id: activeRun.ticket_id, ticket_title: ticketTitle }
410
+ : activeRun.target_kind === 'bundle' && activeRun.target_bundle_id
411
+ ? { kind: 'bundle', bundle_id: activeRun.target_bundle_id,
412
+ bundle_name: getBundle(activeRun.target_bundle_id, project.id)?.name }
413
+ : { kind: 'project' };
414
+ state.run_log = startServiceRunLog(project.id, state.execution_run_id ?? randomUUID(), source, (runConfig.services ?? []).map((service, index) => ({
415
+ service_id: serviceIdentity(service, index), name: service.name ?? service.cmd,
416
+ })));
417
+ }
398
418
  state.admission_pending = false;
399
419
  state.settle_session = createHostSessionSettler(state, () => runningProcesses.get(contextKey) === state, () => clearRunState(contextKey, state, onStopped));
400
420
  const startup = async () => {
@@ -648,42 +668,7 @@ export const stopTicket = async (ticketOrKey, options = {}) => {
648
668
  if (state.host_session) {
649
669
  assertHostSessionRequest(state.host_session, options.serviceId, options.sessionId);
650
670
  if (options.serviceId !== undefined) {
651
- const session = state.host_session;
652
- session.pending.delete(options.serviceId);
653
- const status = session.services.find(service => service.service_id === options.serviceId);
654
- const proc = session.processes.get(options.serviceId);
655
- if (!proc) {
656
- status.status = "stopped";
657
- if (!state.start_services && session.pending.size === 0 && session.processes.size === 0) {
658
- await stopTicket(contextKey, { sessionId: session.id });
659
- return;
660
- }
661
- await state.settle_session?.();
662
- return;
663
- }
664
- state.launch_operations = (state.launch_operations ?? 0) + 1;
665
- try {
666
- status.status = "stopping";
667
- const configuredService = session.config.services.find((service, index) => serviceIdentity(service, index) === options.serviceId);
668
- if (configuredService && isPreviewService(configuredService, state.preview_status)) {
669
- deactivatePreviewProxyForProject(state.active_run.project_id);
670
- state.preview_status = { ...state.preview_status, state: "idle", detected_url: null, detected_origin: null, detected_path: null, proxy_url: null };
671
- state.preview_log_buffer = "";
672
- }
673
- killManagedProcess(proc, "SIGTERM");
674
- await waitForProcessesToExit([proc], 1000);
675
- killManagedProcess(proc, "SIGKILL");
676
- await waitForProcessesToExit([proc], 1000);
677
- if (isProcessAlive(proc)) {
678
- throw new Error("The service did not exit. Retry stopping it before restarting.");
679
- }
680
- finishHostService(session, options.serviceId, proc, proc.exitCode);
681
- state.on_state_changed?.();
682
- }
683
- finally {
684
- state.launch_operations -= 1;
685
- await state.settle_session?.();
686
- }
671
+ await stopHostService(state, options.serviceId, () => stopTicket(contextKey, { sessionId: state.host_session.id }));
687
672
  return;
688
673
  }
689
674
  }
@@ -733,7 +718,7 @@ export const stopTicket = async (ticketOrKey, options = {}) => {
733
718
  }
734
719
  state.finalization ??= finalizeDurableRun(state, "cancelled", "service_run_cancelled", state.execution_provider === "docker_sandbox"
735
720
  ? "The service run was stopped. Docker Sandbox interruption stops the whole environment and every attached service."
736
- : "The service run host processes were stopped.").then(() => clearRunState(contextKey, state)).catch(error => {
721
+ : "The service run host processes were stopped.").then(() => clearRunState(contextKey, state, state.on_state_changed)).catch(error => {
737
722
  state.finalization = null;
738
723
  throw error;
739
724
  });
@@ -770,6 +755,7 @@ export const runTicketInWorkspace = (ticket, io, project = null, workspaceCwd =
770
755
  preferWorkflow: true,
771
756
  }).model,
772
757
  logLabelPrefix: `ticket:${ticket.id}`,
758
+ ticketTitle: ticket.title,
773
759
  onStopped: () => emitRunStateForContext(io, ticket, isRunning(ticket)),
774
760
  project: project,
775
761
  runConfig,