voratiq 0.1.0-beta.21 → 0.1.0-beta.22

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 (149) hide show
  1. package/README.md +18 -22
  2. package/dist/agents/launch/chat.d.ts +3 -1
  3. package/dist/agents/launch/chat.js +2 -0
  4. package/dist/bin.js +28 -7
  5. package/dist/cli/auto.js +1 -0
  6. package/dist/cli/contract.d.ts +26 -17
  7. package/dist/cli/contract.js +3 -1
  8. package/dist/cli/doctor.d.ts +12 -0
  9. package/dist/cli/doctor.js +115 -0
  10. package/dist/cli/list.js +4 -1
  11. package/dist/cli/operator-envelope.d.ts +19 -6
  12. package/dist/cli/operator-envelope.js +61 -1
  13. package/dist/cli/run.js +2 -0
  14. package/dist/cli/verify.d.ts +1 -1
  15. package/dist/cli/verify.js +48 -9
  16. package/dist/commands/auto/command.d.ts +1 -0
  17. package/dist/commands/auto/command.js +22 -12
  18. package/dist/commands/auto/errors.js +1 -1
  19. package/dist/commands/doctor/agents.d.ts +5 -0
  20. package/dist/commands/{init → doctor}/agents.js +37 -19
  21. package/dist/commands/doctor/command.d.ts +22 -0
  22. package/dist/commands/doctor/command.js +99 -0
  23. package/dist/commands/doctor/environment.d.ts +2 -0
  24. package/dist/commands/{init → doctor}/environment.js +38 -6
  25. package/dist/commands/{init/types.d.ts → doctor/fix-types.d.ts} +30 -9
  26. package/dist/commands/doctor/fix.d.ts +2 -0
  27. package/dist/commands/{init/command.js → doctor/fix.js} +106 -10
  28. package/dist/commands/doctor/reconcile.d.ts +2 -0
  29. package/dist/commands/doctor/reconcile.js +101 -0
  30. package/dist/commands/interactive/lifecycle.d.ts +2 -0
  31. package/dist/commands/interactive/lifecycle.js +8 -0
  32. package/dist/commands/list/command.d.ts +1 -0
  33. package/dist/commands/list/command.js +211 -352
  34. package/dist/commands/list/normalization.d.ts +56 -0
  35. package/dist/commands/list/normalization.js +317 -0
  36. package/dist/commands/message/command.d.ts +2 -1
  37. package/dist/commands/message/command.js +35 -14
  38. package/dist/commands/message/errors.d.ts +12 -3
  39. package/dist/commands/message/errors.js +19 -3
  40. package/dist/commands/reduce/command.js +16 -17
  41. package/dist/commands/reduce/errors.d.ts +2 -2
  42. package/dist/commands/reduce/errors.js +3 -3
  43. package/dist/commands/reduce/targets.js +11 -2
  44. package/dist/commands/root-launcher/command.js +12 -6
  45. package/dist/commands/run/command.d.ts +1 -0
  46. package/dist/commands/run/command.js +4 -1
  47. package/dist/commands/run/record-init.d.ts +2 -0
  48. package/dist/commands/run/record-init.js +2 -1
  49. package/dist/commands/run/spec-provenance.d.ts +37 -0
  50. package/dist/commands/run/spec-provenance.js +384 -0
  51. package/dist/commands/run/validation.d.ts +4 -0
  52. package/dist/commands/run/validation.js +25 -62
  53. package/dist/commands/spec/command.js +19 -6
  54. package/dist/commands/spec/errors.d.ts +5 -0
  55. package/dist/commands/spec/errors.js +9 -0
  56. package/dist/commands/verify/agents.d.ts +4 -2
  57. package/dist/commands/verify/agents.js +4 -11
  58. package/dist/commands/verify/command.js +15 -5
  59. package/dist/commands/verify/errors.d.ts +12 -0
  60. package/dist/commands/verify/errors.js +22 -0
  61. package/dist/commands/verify/targets.js +108 -12
  62. package/dist/competition/shared/preflight.d.ts +1 -1
  63. package/dist/competition/shared/preflight.js +15 -2
  64. package/dist/contracts/list.d.ts +129 -149
  65. package/dist/contracts/list.js +47 -99
  66. package/dist/domain/interactive/persistence/adapter.d.ts +23 -0
  67. package/dist/domain/interactive/persistence/adapter.js +42 -0
  68. package/dist/domain/message/model/types.d.ts +32 -0
  69. package/dist/domain/message/model/types.js +25 -0
  70. package/dist/domain/reduce/competition/adapter.js +21 -7
  71. package/dist/domain/reduce/competition/finalize.d.ts +7 -0
  72. package/dist/domain/reduce/competition/finalize.js +19 -0
  73. package/dist/domain/reduce/model/types.d.ts +3 -3
  74. package/dist/domain/run/competition/agents/artifacts.js +4 -2
  75. package/dist/domain/run/competition/errors.d.ts +1 -1
  76. package/dist/domain/run/competition/errors.js +4 -7
  77. package/dist/domain/run/model/types.d.ts +384 -0
  78. package/dist/domain/run/model/types.js +87 -0
  79. package/dist/domain/spec/competition/adapter.d.ts +1 -0
  80. package/dist/domain/spec/competition/adapter.js +6 -1
  81. package/dist/domain/spec/model/types.d.ts +3 -0
  82. package/dist/domain/spec/model/types.js +5 -0
  83. package/dist/domain/verify/competition/finalize.d.ts +9 -0
  84. package/dist/domain/verify/competition/finalize.js +22 -3
  85. package/dist/domain/verify/model/types.d.ts +2 -2
  86. package/dist/interactive/providers/mcp.d.ts +1 -0
  87. package/dist/interactive/providers/mcp.js +45 -7
  88. package/dist/interactive/substrate.js +20 -3
  89. package/dist/mcp/server.js +26 -9
  90. package/dist/policy/verification.js +18 -1
  91. package/dist/preflight/agents.d.ts +24 -0
  92. package/dist/preflight/agents.js +71 -0
  93. package/dist/preflight/environment.d.ts +6 -0
  94. package/dist/preflight/environment.js +17 -0
  95. package/dist/preflight/formatting.d.ts +5 -0
  96. package/dist/preflight/formatting.js +20 -0
  97. package/dist/preflight/index.d.ts +2 -0
  98. package/dist/preflight/index.js +5 -9
  99. package/dist/preflight/operator.d.ts +32 -0
  100. package/dist/preflight/operator.js +40 -0
  101. package/dist/preflight/settings.d.ts +2 -0
  102. package/dist/preflight/settings.js +17 -0
  103. package/dist/render/transcripts/interactive.d.ts +16 -0
  104. package/dist/render/transcripts/interactive.js +42 -0
  105. package/dist/render/transcripts/list.d.ts +41 -0
  106. package/dist/render/transcripts/list.js +152 -3
  107. package/dist/render/transcripts/message.d.ts +2 -1
  108. package/dist/render/transcripts/message.js +19 -20
  109. package/dist/render/transcripts/reduce.d.ts +1 -0
  110. package/dist/render/transcripts/reduce.js +21 -21
  111. package/dist/render/transcripts/root-launcher.js +2 -12
  112. package/dist/render/transcripts/run.d.ts +3 -0
  113. package/dist/render/transcripts/run.js +30 -4
  114. package/dist/render/transcripts/spec.js +5 -8
  115. package/dist/render/transcripts/verify.d.ts +5 -3
  116. package/dist/render/transcripts/verify.js +44 -31
  117. package/dist/render/utils/duration.d.ts +5 -0
  118. package/dist/render/utils/duration.js +6 -0
  119. package/dist/render/utils/runs.d.ts +1 -0
  120. package/dist/render/utils/runs.js +1 -0
  121. package/dist/render/utils/transcript-shell.d.ts +2 -1
  122. package/dist/render/utils/transcript-shell.js +19 -6
  123. package/dist/utils/errors.d.ts +2 -1
  124. package/dist/utils/errors.js +3 -1
  125. package/dist/utils/git.d.ts +1 -1
  126. package/dist/utils/git.js +25 -2
  127. package/dist/utils/list-target.d.ts +4 -0
  128. package/dist/utils/list-target.js +35 -0
  129. package/dist/utils/terminal.d.ts +1 -0
  130. package/dist/utils/terminal.js +11 -0
  131. package/dist/workspace/chat/artifacts.d.ts +7 -0
  132. package/dist/workspace/chat/artifacts.js +94 -3
  133. package/dist/workspace/errors.js +2 -2
  134. package/dist/workspace/managed-state.d.ts +32 -0
  135. package/dist/workspace/managed-state.js +103 -0
  136. package/dist/workspace/setup.js +66 -2
  137. package/dist/workspace/shim.d.ts +1 -0
  138. package/dist/workspace/shim.js +3 -3
  139. package/dist/workspace/structure.d.ts +1 -0
  140. package/dist/workspace/structure.js +1 -0
  141. package/package.json +2 -2
  142. package/dist/cli/init.d.ts +0 -15
  143. package/dist/cli/init.js +0 -70
  144. package/dist/commands/init/agents.d.ts +0 -4
  145. package/dist/commands/init/command.d.ts +0 -2
  146. package/dist/commands/init/environment.d.ts +0 -2
  147. package/dist/render/transcripts/init.d.ts +0 -7
  148. package/dist/render/transcripts/init.js +0 -83
  149. /package/dist/commands/{init/types.js → doctor/fix-types.js} +0 -0
@@ -1,20 +1,20 @@
1
+ import { readInteractiveRecords, } from "../../domain/interactive/persistence/adapter.js";
1
2
  import { readMessageRecords, } from "../../domain/message/persistence/adapter.js";
2
3
  import { readReductionRecords, } from "../../domain/reduce/persistence/adapter.js";
3
4
  import { readRunRecords, } from "../../domain/run/persistence/adapter.js";
4
5
  import { readSpecRecords, } from "../../domain/spec/persistence/adapter.js";
5
6
  import { TERMINAL_VERIFICATION_STATUSES } from "../../domain/verify/model/types.js";
6
7
  import { readVerificationRecords, } from "../../domain/verify/persistence/adapter.js";
7
- import { renderListTableTranscript, renderMessageList, renderReduceList, renderRunList, renderSpecList, renderVerifyList, } from "../../render/transcripts/list.js";
8
+ import { renderInteractiveTranscript } from "../../render/transcripts/interactive.js";
9
+ import { renderInteractiveListTable, renderListTableTranscript, renderMessageListTable, renderReduceListTable, renderRunListTable, renderSpecListTable, renderVerifyListTable, } from "../../render/transcripts/list.js";
8
10
  import { formatMessageElapsed, formatMessageRecipientDuration, renderMessageTranscript, } from "../../render/transcripts/message.js";
9
11
  import { formatReduceElapsed, formatReducerDuration, renderReduceTranscript, } from "../../render/transcripts/reduce.js";
10
- import { formatRunElapsed, renderRunTranscript, } from "../../render/transcripts/run.js";
12
+ import { renderRunTranscript } from "../../render/transcripts/run.js";
11
13
  import { formatSpecAgentDuration, formatSpecElapsed, renderSpecTranscript, } from "../../render/transcripts/spec.js";
12
14
  import { formatVerifyElapsed, renderVerifyTranscript, } from "../../render/transcripts/verify.js";
13
- import { formatAgentDuration } from "../../render/utils/agents.js";
14
- import { formatRenderLifecycleDuration } from "../../render/utils/duration.js";
15
- import { formatCompactDiffStatistics } from "../../utils/diff.js";
15
+ import { formatRenderLifecycleRowDuration } from "../../render/utils/duration.js";
16
16
  import { pathExists } from "../../utils/fs.js";
17
- import { getMessageSessionDirectoryPath, getReductionSessionDirectoryPath, getRunDirectoryPath, getSpecSessionDirectoryPath, getVerificationSessionDirectoryPath, } from "../../workspace/structure.js";
17
+ import { formatTargetDisplay, formatTargetTablePreview, normalizeListDetailSession, normalizeListSession, toListJsonTargetRef, } from "./normalization.js";
18
18
  const DEFAULT_LIMIT = 10;
19
19
  const DASH = "—";
20
20
  export async function executeListCommand(input) {
@@ -35,16 +35,17 @@ async function executeTableMode(input) {
35
35
  ? query.records
36
36
  : query.records.filter((record) => shouldIncludeInDefaultTable(operator, getRecordStatus(record)));
37
37
  const records = filtered.slice(0, limit);
38
+ const sessions = records.map((record) => normalizeListSession(operator, record));
38
39
  const warnings = query.warnings;
39
- const output = renderTableOutput(operator, records);
40
+ const output = renderTableOutput(operator, records, sessions);
40
41
  return {
41
42
  warnings,
42
43
  output,
43
44
  mode: "table",
44
45
  json: {
45
46
  operator,
46
- mode: "table",
47
- records: records.map((record) => toJsonTableRecord(operator, record)),
47
+ mode: "list",
48
+ sessions: sessions.map(toJsonSummarySession),
48
49
  warnings,
49
50
  },
50
51
  };
@@ -70,74 +71,117 @@ async function executeDetailMode(input) {
70
71
  json: {
71
72
  operator,
72
73
  mode: "detail",
73
- sessionId,
74
74
  session: null,
75
75
  warnings,
76
76
  },
77
77
  };
78
78
  }
79
+ const detailSession = normalizeListDetailSession(operator, record);
79
80
  return {
80
81
  warnings,
81
- output: renderDetailOutput(operator, record),
82
+ output: renderDetailOutput(operator, detailSession),
82
83
  mode: "detail",
83
84
  json: {
84
85
  operator,
85
86
  mode: "detail",
86
- sessionId,
87
- session: toJsonDetailSession(operator, record),
87
+ session: toJsonDetailSession(detailSession),
88
88
  warnings,
89
89
  },
90
90
  };
91
91
  }
92
- function renderTableOutput(operator, records) {
92
+ function renderTableOutput(operator, records, sessions) {
93
93
  if (records.length === 0) {
94
94
  return undefined;
95
95
  }
96
96
  const table = operator === "run"
97
- ? renderRunList(records)
97
+ ? renderRunListTable(sessions.map((session) => ({
98
+ id: session.sessionId,
99
+ target: session.target
100
+ ? formatTargetTablePreview(session.target)
101
+ : DASH,
102
+ status: session.status,
103
+ createdAt: session.createdAt,
104
+ })))
98
105
  : operator === "spec"
99
- ? renderSpecList(records)
106
+ ? renderSpecListTable(sessions.map((session) => {
107
+ return {
108
+ id: session.sessionId,
109
+ description: session.description ?? null,
110
+ status: session.status,
111
+ createdAt: session.createdAt,
112
+ };
113
+ }))
100
114
  : operator === "message"
101
- ? renderMessageList(records)
102
- : operator === "reduce"
103
- ? renderReduceList(records)
104
- : renderVerifyList(records);
115
+ ? renderMessageListTable(sessions.map((session) => ({
116
+ id: session.sessionId,
117
+ target: session.target
118
+ ? formatTargetTablePreview(session.target)
119
+ : DASH,
120
+ status: session.status,
121
+ createdAt: session.createdAt,
122
+ })))
123
+ : operator === "interactive"
124
+ ? renderInteractiveListTable(sessions.map((session) => ({
125
+ id: session.sessionId,
126
+ status: session.status,
127
+ createdAt: session.createdAt,
128
+ })))
129
+ : operator === "reduce"
130
+ ? renderReduceListTable(sessions.map((session) => ({
131
+ id: session.sessionId,
132
+ target: session.target
133
+ ? formatTargetTablePreview(session.target)
134
+ : DASH,
135
+ status: session.status,
136
+ createdAt: session.createdAt,
137
+ })))
138
+ : renderVerifyListTable(sessions.map((session) => ({
139
+ id: session.sessionId,
140
+ target: session.target
141
+ ? formatTargetTablePreview(session.target)
142
+ : DASH,
143
+ status: session.status,
144
+ createdAt: session.createdAt,
145
+ })));
105
146
  return renderListTableTranscript(table);
106
147
  }
107
- function renderDetailOutput(operator, record) {
148
+ function renderDetailOutput(operator, session) {
108
149
  if (operator === "run") {
109
- const runRecord = record;
110
150
  return renderRunTranscript({
111
- runId: runRecord.runId,
112
- status: runRecord.status,
113
- workspacePath: getRunDirectoryPath(runRecord.runId),
114
- createdAt: runRecord.createdAt,
115
- startedAt: runRecord.startedAt,
116
- completedAt: runRecord.completedAt,
117
- agents: runRecord.agents.map((agent) => ({
118
- agentId: agent.agentId,
151
+ runId: session.sessionId,
152
+ status: session.status,
153
+ workspacePath: session.workspacePath,
154
+ createdAt: session.createdAt,
155
+ startedAt: session.startedAt,
156
+ completedAt: session.completedAt,
157
+ targetDisplay: session.target
158
+ ? formatTargetDisplay(session.target)
159
+ : undefined,
160
+ agents: session.agents.map((agent) => ({
161
+ agentId: agent.agentId ?? DASH,
119
162
  status: agent.status,
120
163
  startedAt: agent.startedAt,
121
164
  completedAt: agent.completedAt,
122
165
  diffStatistics: agent.diffStatistics,
166
+ outputPath: agent.outputPath,
167
+ errorLine: agent.errorLine,
123
168
  })),
124
169
  isTty: process.stdout.isTTY,
125
170
  });
126
171
  }
127
172
  if (operator === "spec") {
128
- const specRecord = record;
129
173
  return renderSpecTranscript({
130
- sessionId: specRecord.sessionId,
131
- createdAt: specRecord.createdAt,
174
+ sessionId: session.sessionId,
175
+ createdAt: session.createdAt,
132
176
  elapsed: formatSpecElapsed({
133
- status: specRecord.status,
134
- startedAt: specRecord.startedAt,
135
- completedAt: specRecord.completedAt,
177
+ status: session.status,
178
+ startedAt: session.startedAt,
179
+ completedAt: session.completedAt,
136
180
  }) ?? DASH,
137
- workspacePath: getSpecSessionDirectoryPath(specRecord.sessionId),
138
- status: specRecord.status,
139
- agents: specRecord.agents.map((agent) => ({
140
- agentId: agent.agentId,
181
+ workspacePath: session.workspacePath,
182
+ status: session.status,
183
+ agents: session.agents.map((agent) => ({
184
+ agentId: agent.agentId ?? DASH,
141
185
  status: agent.status,
142
186
  duration: formatSpecAgentDuration({
143
187
  status: agent.status,
@@ -146,346 +190,151 @@ function renderDetailOutput(operator, record) {
146
190
  }),
147
191
  outputPath: agent.outputPath,
148
192
  dataPath: agent.dataPath,
149
- errorLine: agent.error ?? undefined,
193
+ errorLine: agent.errorLine,
150
194
  })),
151
195
  isTty: process.stdout.isTTY,
152
196
  }, { suppressHint: true });
153
197
  }
154
198
  if (operator === "reduce") {
155
- const reductionRecord = record;
156
199
  return renderReduceTranscript({
157
- reductionId: reductionRecord.sessionId,
158
- createdAt: reductionRecord.createdAt,
200
+ reductionId: session.sessionId,
201
+ createdAt: session.createdAt,
159
202
  elapsed: formatReduceElapsed({
160
- status: reductionRecord.status,
161
- startedAt: reductionRecord.startedAt,
162
- completedAt: reductionRecord.completedAt,
203
+ status: session.status,
204
+ startedAt: session.startedAt,
205
+ completedAt: session.completedAt,
163
206
  }) ?? DASH,
164
- workspacePath: getReductionSessionDirectoryPath(reductionRecord.sessionId),
165
- status: reductionRecord.status,
166
- reducers: reductionRecord.reducers.map((reducer) => ({
167
- reducerAgentId: reducer.agentId,
168
- status: reducer.status,
207
+ workspacePath: session.workspacePath,
208
+ status: session.status,
209
+ targetDisplay: session.target
210
+ ? formatTargetDisplay(session.target)
211
+ : undefined,
212
+ reducers: session.agents.map((agent) => ({
213
+ reducerAgentId: agent.agentId ?? DASH,
214
+ status: agent.status,
169
215
  duration: formatReducerDuration({
170
- status: reducer.status,
171
- startedAt: reducer.startedAt,
172
- completedAt: reducer.completedAt,
216
+ status: agent.status,
217
+ startedAt: agent.startedAt,
218
+ completedAt: agent.completedAt,
173
219
  }),
174
- outputPath: reducer.outputPath,
175
- dataPath: reducer.dataPath,
176
- errorLine: reducer.error ?? undefined,
220
+ outputPath: agent.outputPath,
221
+ dataPath: agent.dataPath,
222
+ errorLine: agent.errorLine,
177
223
  })),
178
224
  suppressHint: true,
179
225
  isTty: process.stdout.isTTY,
180
226
  });
181
227
  }
182
228
  if (operator === "message") {
183
- const messageRecord = record;
184
229
  return renderMessageTranscript({
185
- messageId: messageRecord.sessionId,
186
- createdAt: messageRecord.createdAt,
230
+ messageId: session.sessionId,
231
+ createdAt: session.createdAt,
187
232
  elapsed: formatMessageElapsed({
188
- status: messageRecord.status,
189
- startedAt: messageRecord.startedAt,
190
- completedAt: messageRecord.completedAt,
233
+ status: session.status,
234
+ startedAt: session.startedAt,
235
+ completedAt: session.completedAt,
191
236
  }) ?? DASH,
192
- workspacePath: getMessageSessionDirectoryPath(messageRecord.sessionId),
193
- status: messageRecord.status,
194
- recipients: messageRecord.recipients.map((recipient) => ({
195
- agentId: recipient.agentId,
196
- status: recipient.status,
237
+ workspacePath: session.workspacePath,
238
+ status: session.status,
239
+ targetDisplay: session.target
240
+ ? formatTargetDisplay(session.target)
241
+ : undefined,
242
+ recipients: session.agents.map((agent) => ({
243
+ agentId: agent.agentId ?? DASH,
244
+ status: agent.status,
197
245
  duration: formatMessageRecipientDuration({
198
- status: recipient.status,
199
- startedAt: recipient.startedAt,
200
- completedAt: recipient.completedAt,
201
- }) ?? DASH,
202
- outputPath: recipient.outputPath,
203
- errorLine: recipient.error ?? undefined,
246
+ status: agent.status,
247
+ startedAt: agent.startedAt,
248
+ completedAt: agent.completedAt,
249
+ }),
250
+ outputPath: agent.outputPath,
251
+ errorLine: agent.errorLine,
204
252
  })),
205
253
  isTty: process.stdout.isTTY,
206
254
  });
207
255
  }
208
- const verificationRecord = record;
256
+ if (operator === "interactive") {
257
+ const interactiveAgent = session.agents[0];
258
+ return renderInteractiveTranscript({
259
+ sessionId: session.sessionId,
260
+ createdAt: session.createdAt,
261
+ elapsed: DASH,
262
+ workspacePath: session.workspacePath,
263
+ status: session.status,
264
+ agents: [
265
+ {
266
+ agentId: interactiveAgent?.agentId ?? DASH,
267
+ status: interactiveAgent?.status ??
268
+ "failed",
269
+ duration: DASH,
270
+ outputPath: interactiveAgent?.outputPath,
271
+ },
272
+ ],
273
+ isTty: process.stdout.isTTY,
274
+ });
275
+ }
209
276
  return renderVerifyTranscript({
210
- verificationId: verificationRecord.sessionId,
211
- createdAt: verificationRecord.createdAt,
277
+ verificationId: session.sessionId,
278
+ createdAt: session.createdAt,
212
279
  elapsed: formatVerifyElapsed({
213
- status: verificationRecord.status,
214
- startedAt: verificationRecord.startedAt,
215
- completedAt: verificationRecord.completedAt,
280
+ status: session.status,
281
+ startedAt: session.startedAt,
282
+ completedAt: session.completedAt,
216
283
  }) ?? DASH,
217
- workspacePath: getVerificationSessionDirectoryPath(verificationRecord.sessionId),
218
- target: verificationRecord.target,
219
- status: verificationRecord.status,
220
- methods: verificationRecord.methods.map((method) => ({
221
- verifierLabel: method.method === "programmatic"
222
- ? "programmatic"
223
- : (method.template ?? "rubric"),
224
- agentLabel: method.verifierId,
225
- status: method.status,
226
- duration: formatVerifyMethodDuration(method),
227
- artifactPath: method.artifactPath,
228
- errorLine: method.error ?? undefined,
284
+ workspacePath: session.workspacePath,
285
+ targetDisplay: session.target
286
+ ? formatTargetDisplay(session.target)
287
+ : undefined,
288
+ status: session.status,
289
+ methods: session.agents.map((agent) => ({
290
+ verifierLabel: agent.verifier ?? "rubric",
291
+ agentLabel: agent.agentId ?? undefined,
292
+ status: agent.status,
293
+ duration: formatVerifyAgentDuration(agent),
294
+ artifactPath: agent.outputPath,
295
+ errorLine: agent.errorLine,
229
296
  })),
230
297
  suppressHint: true,
231
298
  isTty: process.stdout.isTTY,
232
299
  });
233
300
  }
234
- function toJsonTableRecord(operator, record) {
235
- if (operator === "run") {
236
- const runRecord = record;
237
- return {
238
- id: runRecord.runId,
239
- status: runRecord.status,
240
- createdAt: runRecord.createdAt,
241
- specPath: runRecord.spec.path,
242
- };
243
- }
244
- if (operator === "spec") {
245
- const specRecord = record;
246
- return {
247
- id: specRecord.sessionId,
248
- status: specRecord.status,
249
- createdAt: specRecord.createdAt,
250
- description: normalizeDescription(specRecord.description),
251
- };
252
- }
253
- if (operator === "reduce") {
254
- const reductionRecord = record;
255
- return {
256
- id: reductionRecord.sessionId,
257
- status: reductionRecord.status,
258
- createdAt: reductionRecord.createdAt,
259
- target: {
260
- kind: reductionRecord.target.type,
261
- id: reductionRecord.target.id,
262
- },
263
- };
264
- }
265
- if (operator === "message") {
266
- const messageRecord = record;
267
- return {
268
- id: messageRecord.sessionId,
269
- status: messageRecord.status,
270
- createdAt: messageRecord.createdAt,
271
- promptPreview: normalizePreviewText(messageRecord.prompt),
272
- };
273
- }
274
- const verificationRecord = record;
275
- return {
276
- id: verificationRecord.sessionId,
277
- status: verificationRecord.status,
278
- createdAt: verificationRecord.createdAt,
279
- target: {
280
- kind: verificationRecord.target.kind,
281
- id: verificationRecord.target.sessionId,
282
- },
283
- };
284
- }
285
- function toJsonDetailSession(operator, record) {
286
- if (operator === "run") {
287
- const runRecord = record;
288
- return {
289
- id: runRecord.runId,
290
- status: runRecord.status,
291
- createdAt: runRecord.createdAt,
292
- elapsed: formatRunRecordElapsed(runRecord),
293
- workspacePath: getRunDirectoryPath(runRecord.runId),
294
- rows: runRecord.agents.map(toRunJsonRow),
295
- artifacts: [],
296
- };
297
- }
298
- if (operator === "spec") {
299
- const specRecord = record;
300
- return {
301
- id: specRecord.sessionId,
302
- status: specRecord.status,
303
- createdAt: specRecord.createdAt,
304
- elapsed: formatSpecRecordElapsed(specRecord),
305
- workspacePath: getSpecSessionDirectoryPath(specRecord.sessionId),
306
- rows: specRecord.agents.map(toSpecJsonRow),
307
- artifacts: specRecord.agents.map(toSpecArtifact),
308
- };
309
- }
310
- if (operator === "reduce") {
311
- const reductionRecord = record;
312
- return {
313
- id: reductionRecord.sessionId,
314
- status: reductionRecord.status,
315
- createdAt: reductionRecord.createdAt,
316
- elapsed: formatReductionRecordElapsed(reductionRecord),
317
- workspacePath: getReductionSessionDirectoryPath(reductionRecord.sessionId),
318
- target: {
319
- kind: reductionRecord.target.type,
320
- id: reductionRecord.target.id,
321
- },
322
- rows: reductionRecord.reducers.map(toReductionJsonRow),
323
- artifacts: reductionRecord.reducers.map(toReductionArtifact),
324
- };
325
- }
326
- if (operator === "message") {
327
- const messageRecord = record;
328
- return {
329
- id: messageRecord.sessionId,
330
- status: messageRecord.status,
331
- createdAt: messageRecord.createdAt,
332
- elapsed: formatMessageRecordElapsed(messageRecord),
333
- workspacePath: getMessageSessionDirectoryPath(messageRecord.sessionId),
334
- rows: messageRecord.recipients.map(toMessageJsonRow),
335
- artifacts: messageRecord.recipients.flatMap(toMessageArtifacts),
336
- };
337
- }
338
- const verificationRecord = record;
301
+ function toJsonSummarySession(session) {
339
302
  return {
340
- id: verificationRecord.sessionId,
341
- status: verificationRecord.status,
342
- createdAt: verificationRecord.createdAt,
343
- elapsed: formatVerificationRecordElapsed(verificationRecord),
344
- workspacePath: getVerificationSessionDirectoryPath(verificationRecord.sessionId),
345
- target: {
346
- kind: verificationRecord.target.kind,
347
- id: verificationRecord.target.sessionId,
348
- },
349
- rows: verificationRecord.methods.map(toVerificationJsonRow),
350
- artifacts: verificationRecord.methods.map(toVerificationArtifact),
303
+ operator: session.operator,
304
+ sessionId: session.sessionId,
305
+ status: session.status,
306
+ createdAt: session.createdAt,
307
+ ...(session.target ? { target: toListJsonTargetRef(session.target) } : {}),
308
+ ...(session.description !== undefined
309
+ ? { description: session.description }
310
+ : {}),
351
311
  };
352
312
  }
353
- function formatRunRecordElapsed(record) {
354
- return formatRunElapsed({
355
- status: record.status,
356
- startedAt: record.startedAt,
357
- completedAt: record.completedAt,
358
- });
359
- }
360
- function formatSpecRecordElapsed(record) {
361
- return formatSpecElapsed({
362
- status: record.status,
363
- startedAt: record.startedAt,
364
- completedAt: record.completedAt,
365
- });
366
- }
367
- function formatReductionRecordElapsed(record) {
368
- return formatReduceElapsed({
369
- status: record.status,
370
- startedAt: record.startedAt,
371
- completedAt: record.completedAt,
372
- });
373
- }
374
- function formatMessageRecordElapsed(record) {
375
- return formatMessageElapsed({
376
- status: record.status,
377
- startedAt: record.startedAt,
378
- completedAt: record.completedAt,
379
- });
380
- }
381
- function normalizePreviewText(value) {
382
- if (!value) {
383
- return null;
384
- }
385
- const normalized = value.replace(/\s+/gu, " ").trim();
386
- return normalized.length > 0 ? normalized : null;
387
- }
388
- function formatVerificationRecordElapsed(record) {
389
- return formatVerifyElapsed({
390
- status: record.status,
391
- startedAt: record.startedAt,
392
- completedAt: record.completedAt,
393
- });
394
- }
395
- function formatRunRowDuration(agent) {
396
- return agent.status === "running"
397
- ? DASH
398
- : (formatAgentDuration(agent) ?? DASH);
399
- }
400
- function toRunJsonRow(agent) {
313
+ function toJsonDetailSession(session) {
401
314
  return {
402
- agentId: agent.agentId,
403
- status: agent.status,
404
- duration: formatRunRowDuration(agent),
405
- changes: formatCompactDiffStatistics(agent.diffStatistics) ?? null,
315
+ operator: session.operator,
316
+ sessionId: session.sessionId,
317
+ status: session.status,
318
+ createdAt: session.createdAt,
319
+ ...(session.startedAt ? { startedAt: session.startedAt } : {}),
320
+ ...(session.completedAt ? { completedAt: session.completedAt } : {}),
321
+ workspacePath: session.workspacePath,
322
+ ...(session.target ? { target: toListJsonTargetRef(session.target) } : {}),
323
+ ...(session.description !== undefined
324
+ ? { description: session.description }
325
+ : {}),
326
+ agents: session.agents.map(toJsonAgent),
406
327
  };
407
328
  }
408
- function formatSpecRowDuration(agent) {
409
- return (formatSpecAgentDuration({
410
- status: agent.status,
411
- startedAt: agent.startedAt,
412
- completedAt: agent.completedAt,
413
- }) ?? DASH);
414
- }
415
- function toSpecJsonRow(agent) {
329
+ function toJsonAgent(agent) {
416
330
  return {
417
331
  agentId: agent.agentId,
418
332
  status: agent.status,
419
- duration: formatSpecRowDuration(agent),
420
- };
421
- }
422
- function toSpecArtifact(agent) {
423
- return {
424
- kind: "spec",
425
- agentId: agent.agentId,
426
- path: agent.outputPath ?? null,
427
- };
428
- }
429
- function formatReductionRowDuration(reducer) {
430
- return (formatReducerDuration({
431
- status: reducer.status,
432
- startedAt: reducer.startedAt,
433
- completedAt: reducer.completedAt,
434
- }) ?? DASH);
435
- }
436
- function toReductionJsonRow(reducer) {
437
- return {
438
- agentId: reducer.agentId,
439
- status: reducer.status,
440
- duration: formatReductionRowDuration(reducer),
441
- };
442
- }
443
- function toReductionArtifact(reducer) {
444
- return {
445
- kind: "reduction",
446
- agentId: reducer.agentId,
447
- path: reducer.outputPath ?? null,
448
- };
449
- }
450
- function toMessageJsonRow(recipient) {
451
- return {
452
- agentId: recipient.agentId,
453
- status: recipient.status,
454
- duration: formatMessageRecipientDuration({
455
- status: recipient.status,
456
- startedAt: recipient.startedAt,
457
- completedAt: recipient.completedAt,
458
- }) ?? DASH,
459
- };
460
- }
461
- function toMessageArtifacts(recipient) {
462
- return [
463
- {
464
- kind: "output",
465
- agentId: recipient.agentId,
466
- path: recipient.outputPath ?? null,
467
- },
468
- ];
469
- }
470
- function getVerificationMethodLabel(method) {
471
- return method.method === "programmatic"
472
- ? "programmatic"
473
- : (method.template ?? "rubric");
474
- }
475
- function toVerificationJsonRow(method) {
476
- return {
477
- agentId: method.verifierId ?? null,
478
- verifier: getVerificationMethodLabel(method),
479
- status: method.status,
480
- duration: formatVerifyMethodDuration(method),
481
- };
482
- }
483
- function toVerificationArtifact(method) {
484
- return {
485
- kind: "result",
486
- agentId: method.verifierId ?? null,
487
- verifier: getVerificationMethodLabel(method),
488
- path: method.artifactPath ?? null,
333
+ ...(agent.startedAt ? { startedAt: agent.startedAt } : {}),
334
+ ...(agent.completedAt ? { completedAt: agent.completedAt } : {}),
335
+ ...(agent.verifier ? { verifier: agent.verifier } : {}),
336
+ ...(agent.changes ? { changes: agent.changes } : {}),
337
+ artifacts: agent.artifacts,
489
338
  };
490
339
  }
491
340
  function shouldIncludeInDefaultTable(operator, status) {
@@ -567,6 +416,23 @@ async function readOperatorRecords(input) {
567
416
  warnings: warnings.map(formatSessionWarning),
568
417
  };
569
418
  }
419
+ if (operator === "interactive") {
420
+ if (!(await pathExists(input.interactiveFilePath))) {
421
+ return { records: [], warnings: [] };
422
+ }
423
+ const warnings = [];
424
+ const records = await readInteractiveRecords({
425
+ root,
426
+ interactiveFilePath: input.interactiveFilePath,
427
+ limit: input.limit,
428
+ predicate: input.predicate,
429
+ onWarning: (warning) => warnings.push(warning),
430
+ });
431
+ return {
432
+ records,
433
+ warnings: warnings.map(formatSessionWarning),
434
+ };
435
+ }
570
436
  if (!(await pathExists(input.verificationsFilePath))) {
571
437
  return { records: [], warnings: [] };
572
438
  }
@@ -598,20 +464,13 @@ function getRecordId(operator, record) {
598
464
  function formatSessionWarning(warning) {
599
465
  return `Ignoring corrupt session ${warning.displayPath}`;
600
466
  }
601
- function normalizeDescription(value) {
602
- if (!value) {
603
- return null;
604
- }
605
- const normalized = value.replace(/\s+/g, " ").trim();
606
- return normalized.length > 0 ? normalized : null;
607
- }
608
- function formatVerifyMethodDuration(method) {
609
- return (formatRenderLifecycleDuration({
467
+ function formatVerifyAgentDuration(agent) {
468
+ return formatRenderLifecycleRowDuration({
610
469
  lifecycle: {
611
- status: method.status,
612
- startedAt: method.startedAt,
613
- completedAt: method.completedAt,
470
+ status: agent.status,
471
+ startedAt: agent.startedAt,
472
+ completedAt: agent.completedAt,
614
473
  },
615
474
  terminalStatuses: TERMINAL_VERIFICATION_STATUSES,
616
- }) ?? DASH);
475
+ });
617
476
  }