vinta-ai-workflows 0.7.0-alpha8 → 0.7.0

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 (67) hide show
  1. package/CHANGELOG.md +472 -595
  2. package/README.md +33 -19
  3. package/package.json +4 -1
  4. package/schemas/README.md +11 -3
  5. package/schemas/ai-models.v1.schema.json +5 -0
  6. package/schemas/interview-answers.v1.schema.json +122 -0
  7. package/schemas/interview-round.v1.schema.json +346 -0
  8. package/schemas/plan-review.v1.schema.json +342 -0
  9. package/schemas/postmortem.v1.schema.json +848 -3
  10. package/schemas/prs-context-comments.v1.schema.json +1 -1
  11. package/schemas/prs-context-frontmatter.v1.schema.json +18 -7
  12. package/schemas/vinta-ai-workflows-config.v1.schema.json +677 -18
  13. package/schemas/workflow.v1.schema.json +751 -26
  14. package/skills/vinta-analyze-codebase/SKILL.md +5 -0
  15. package/skills/vinta-bootstrap-ai-tools/SKILL.md +154 -31
  16. package/skills/vinta-bootstrap-ai-tools/resources/stacks/README.md +1 -1
  17. package/skills/vinta-bootstrap-ai-tools/resources/stacks/django/notes.md +36 -1
  18. package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/README.md +85 -0
  19. package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/lib-template.sh +160 -0
  20. package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/prepare-template.sh +250 -0
  21. package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/teardown-template.sh +96 -0
  22. package/skills/vinta-derive-skills/SKILL.md +23 -15
  23. package/skills/vinta-derive-skills/resources/dependency-license-block.md +8 -9
  24. package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/SKILL.md +1 -1
  25. package/skills/vinta-derive-skills/resources/foundation-skills/create-qa-use-cases/SKILL.md +3 -3
  26. package/skills/vinta-derive-skills/resources/foundation-skills/create-spec/SKILL.md +21 -2
  27. package/skills/vinta-derive-skills/resources/foundation-skills/handoff/SKILL.md +3 -3
  28. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/SKILL.md +121 -0
  29. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/examples/docs/D4-concurrency.md +28 -0
  30. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/examples/round-01.json +60 -0
  31. package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/SKILL.md +1 -1
  32. package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/scripts/open-pr.sh +34 -7
  33. package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/SKILL.md +363 -142
  34. package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/resources/ai-models.yaml +19 -13
  35. package/skills/vinta-derive-skills/resources/foundation-skills/prepare-worktree/SKILL.md +39 -21
  36. package/skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-code-quality-review/SKILL.md +8 -6
  37. package/skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-review-loop/SKILL.md +181 -0
  38. package/skills/vinta-derive-skills/resources/plan-execution/README.md +40 -7
  39. package/skills/vinta-derive-skills/resources/plan-execution/partials/agent-models.md +14 -35
  40. package/skills/vinta-derive-skills/resources/plan-execution/partials/commit-strategy/stacked.md +21 -0
  41. package/skills/vinta-derive-skills/resources/plan-execution/partials/dispatched-agent.md +31 -0
  42. package/skills/vinta-derive-skills/resources/plan-execution/partials/implementer-prompt.md +67 -6
  43. package/skills/vinta-derive-skills/resources/plan-execution/partials/maestro-live-run.md +44 -0
  44. package/skills/vinta-derive-skills/resources/plan-execution/partials/model-pick.md +9 -3
  45. package/skills/vinta-derive-skills/resources/plan-execution/partials/parallel-lanes.md +95 -50
  46. package/skills/vinta-derive-skills/resources/plan-execution/partials/pr-context.md +4 -2
  47. package/skills/vinta-derive-skills/resources/plan-execution/partials/relay-questions.md +13 -0
  48. package/skills/vinta-derive-skills/resources/plan-execution/partials/review-loop.md +81 -0
  49. package/skills/vinta-derive-skills/resources/plan-execution/partials/worktree-seam.md +86 -17
  50. package/skills/vinta-derive-skills/resources/plan-execution/shell/amend-plan-template.md +35 -16
  51. package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-phase-template.md +12 -1
  52. package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-plan-template.md +49 -33
  53. package/skills/vinta-derive-skills/resources/plan-execution/shell/integrate-phase-template.md +2 -1
  54. package/skills/vinta-derive-skills/resources/plan-execution/shell/review-phase-template.md +19 -27
  55. package/skills/vinta-derive-skills/resources/prs-context-template.md +5 -4
  56. package/skills/vinta-derive-skills/resources/systematic-debugging-mcp-tools.md +1 -1
  57. package/skills/vinta-derive-skills/resources/systematic-debugging-template.md +8 -8
  58. package/skills/vinta-derive-skills/resources/write-unit-test-packs/stacks/django.md +4 -1
  59. package/skills/vinta-derive-skills/resources/write-unit-test-template.md +3 -0
  60. package/skills/vinta-derive-subagents/SKILL.md +25 -9
  61. package/skills/vinta-install-ai-tools-setup/SKILL.md +29 -2
  62. package/skills/vinta-migrate-plans-specs/SKILL.md +7 -7
  63. package/skills/vinta-sync-ai-tools/SKILL.md +19 -2
  64. package/skills/vinta-update-project-skills/SKILL.md +1 -0
  65. package/skills/vinta-write-agents-md/SKILL.md +10 -6
  66. package/skills/vinta-write-agents-md/resources/asking-the-human.md +56 -0
  67. package/skills/vinta-derive-skills/resources/plan-execution/partials/review-layers.md +0 -101
@@ -0,0 +1,346 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/vintasoftware/vinta-ai-workflows/schemas/interview-round.v1.schema.json",
4
+ "title": "interview round (v1)",
5
+ "description": "One round of an agent-driven interview, written by the agent to `<interview-dir>/rounds/round-NN.json` and rendered by the `vinta-ai-maestro` interview page as a full-screen decision form. Decisions are grouped; each decision carries the context the agent already knows, an optional explainer document (Markdown with Mermaid, or HTML), and options with their consequences. The browser answers with an `interview-answers.v1` payload. Lives at `<interview-dir>/rounds/round-NN.json`, where `<interview-dir>` is `.vinta-ai-workflows/interviews/<slug>/` in a target project (gitignored). Written by the agent running the interview; served to the browser by `vinta-ai-maestro interview`. GENERATED from packages/vinta-ai-maestro/src/interview/document.ts — edit there, not here. See schemas/README.md for versioning rules.",
6
+ "type": "object",
7
+ "properties": {
8
+ "schema_version": {
9
+ "type": "number",
10
+ "const": 1
11
+ },
12
+ "round": {
13
+ "type": "integer",
14
+ "minimum": 1,
15
+ "maximum": 9007199254740991,
16
+ "description": "1-based round number. Must match the `NN` in the filename (`round-01.json` → 1)."
17
+ },
18
+ "interview": {
19
+ "type": "object",
20
+ "properties": {
21
+ "slug": {
22
+ "type": "string",
23
+ "pattern": "^[a-z0-9][a-z0-9-]*$",
24
+ "description": "Stable kebab-case id for the whole interview. The page keys browser drafts on it; the agent uses it as the interview directory name."
25
+ },
26
+ "title": {
27
+ "type": "string",
28
+ "minLength": 1,
29
+ "description": "Human title shown in the header, e.g. `Order tags — spec interview`."
30
+ },
31
+ "skill": {
32
+ "description": "Skill that is running the interview (`create-spec`, `plan-feature`, …). Display only.",
33
+ "type": "string"
34
+ }
35
+ },
36
+ "required": [
37
+ "slug",
38
+ "title"
39
+ ],
40
+ "additionalProperties": false
41
+ },
42
+ "kind": {
43
+ "default": "questions",
44
+ "description": "`questions` (default) renders decisions one per screen. `readback` additionally renders `summary` first — use it for the final \"anything I got wrong before I draft?\" round.",
45
+ "type": "string",
46
+ "enum": [
47
+ "questions",
48
+ "readback"
49
+ ]
50
+ },
51
+ "intro": {
52
+ "description": "Markdown shown above the first decision — what this round is about, what changed since the last one.",
53
+ "type": "string"
54
+ },
55
+ "summary": {
56
+ "description": "Markdown read-back of every load-bearing decision so far. Rendered only when `kind` is `readback`.",
57
+ "type": "string"
58
+ },
59
+ "replies": {
60
+ "description": "Agent answers to questions the user asked in earlier rounds (`interview-answers.v1` → `questions[]`). Shown next to the decision they refer to, or in the general panel when `decision_id` is absent.",
61
+ "type": "array",
62
+ "items": {
63
+ "$ref": "#/$defs/reply"
64
+ }
65
+ },
66
+ "groups": {
67
+ "minItems": 1,
68
+ "type": "array",
69
+ "items": {
70
+ "$ref": "#/$defs/group"
71
+ },
72
+ "description": "Ordered groups (the left rail). For `create-spec` these are its interview groups A–I."
73
+ }
74
+ },
75
+ "required": [
76
+ "schema_version",
77
+ "round",
78
+ "interview",
79
+ "groups"
80
+ ],
81
+ "additionalProperties": false,
82
+ "$defs": {
83
+ "reply": {
84
+ "type": "object",
85
+ "properties": {
86
+ "question_id": {
87
+ "description": "`questions[].id` from the answers payload being replied to.",
88
+ "type": "string"
89
+ },
90
+ "decision_id": {
91
+ "description": "Decision the question was about. Omit for general questions.",
92
+ "type": "string"
93
+ },
94
+ "question": {
95
+ "type": "string",
96
+ "description": "The user's question, quoted."
97
+ },
98
+ "answer": {
99
+ "type": "string",
100
+ "description": "Markdown answer. Mermaid fences allowed."
101
+ }
102
+ },
103
+ "required": [
104
+ "question",
105
+ "answer"
106
+ ],
107
+ "additionalProperties": false
108
+ },
109
+ "group": {
110
+ "type": "object",
111
+ "properties": {
112
+ "id": {
113
+ "type": "string",
114
+ "minLength": 1
115
+ },
116
+ "title": {
117
+ "type": "string",
118
+ "minLength": 1
119
+ },
120
+ "decisions": {
121
+ "type": "array",
122
+ "items": {
123
+ "$ref": "#/$defs/decision"
124
+ }
125
+ }
126
+ },
127
+ "required": [
128
+ "id",
129
+ "title",
130
+ "decisions"
131
+ ],
132
+ "additionalProperties": false
133
+ },
134
+ "decision": {
135
+ "type": "object",
136
+ "properties": {
137
+ "id": {
138
+ "type": "string",
139
+ "minLength": 1,
140
+ "description": "Stable id within the interview (e.g. `D4`). Reused across rounds when a decision is re-asked."
141
+ },
142
+ "title": {
143
+ "type": "string",
144
+ "minLength": 1,
145
+ "description": "The question, as a full sentence the user can answer."
146
+ },
147
+ "short": {
148
+ "description": "Rail label when `title` is long.",
149
+ "type": "string"
150
+ },
151
+ "why": {
152
+ "description": "One sentence on why the answer matters (the `*Why:*` line from the create-spec question bank).",
153
+ "type": "string"
154
+ },
155
+ "context": {
156
+ "description": "Markdown: what the agent already knows that bears on this decision — earlier answers quoted back, repo facts, constraints. Mermaid fences allowed.",
157
+ "type": "string"
158
+ },
159
+ "explainer": {
160
+ "description": "Rich explanation. Either inline Markdown (string or `{markdown}`) or a file under `<interview-dir>/docs/` (`{path}`). `.md` files render in the page with Mermaid support; `.html` files render in a sandboxed iframe for layouts Markdown cannot express.",
161
+ "$ref": "#/$defs/explainer"
162
+ },
163
+ "required": {
164
+ "default": true,
165
+ "description": "When `false`, the round can be submitted with this decision left open. Default `true`.",
166
+ "type": "boolean"
167
+ },
168
+ "waivable": {
169
+ "default": true,
170
+ "description": "Show the \"not applicable — skip\" toggle. Default `true`.",
171
+ "type": "boolean"
172
+ },
173
+ "waive_label": {
174
+ "type": "string"
175
+ },
176
+ "input": {
177
+ "$ref": "#/$defs/input"
178
+ }
179
+ },
180
+ "required": [
181
+ "id",
182
+ "title",
183
+ "input"
184
+ ],
185
+ "additionalProperties": false
186
+ },
187
+ "explainer": {
188
+ "anyOf": [
189
+ {
190
+ "type": "string",
191
+ "minLength": 1,
192
+ "description": "Inline Markdown. Mermaid fences allowed."
193
+ },
194
+ {
195
+ "type": "object",
196
+ "properties": {
197
+ "title": {
198
+ "type": "string"
199
+ },
200
+ "markdown": {
201
+ "type": "string",
202
+ "minLength": 1,
203
+ "description": "Inline Markdown. Mermaid fences allowed."
204
+ }
205
+ },
206
+ "required": [
207
+ "markdown"
208
+ ],
209
+ "additionalProperties": false,
210
+ "description": "Inline Markdown with a title."
211
+ },
212
+ {
213
+ "type": "object",
214
+ "properties": {
215
+ "title": {
216
+ "type": "string"
217
+ },
218
+ "path": {
219
+ "type": "string",
220
+ "pattern": "^(docs\\/)?[^\\0]+\\.(md|markdown|html|htm)$",
221
+ "description": "Relative to the interview dir, inside `docs/` (e.g. `docs/D4-concurrency.md`). The server refuses anything that escapes `docs/`."
222
+ }
223
+ },
224
+ "required": [
225
+ "path"
226
+ ],
227
+ "additionalProperties": false,
228
+ "description": "A document under `docs/`. `.md` files render in the page with Mermaid support; `.html` files render in a sandboxed iframe, for layouts Markdown cannot express."
229
+ }
230
+ ]
231
+ },
232
+ "input": {
233
+ "type": "object",
234
+ "properties": {
235
+ "type": {
236
+ "type": "string",
237
+ "enum": [
238
+ "single",
239
+ "multi",
240
+ "text",
241
+ "confirm"
242
+ ],
243
+ "description": "`single` — pick one option; `multi` — pick any; `text` — free-form answer; `confirm` — like `single`, for yes/no and read-back confirmations."
244
+ },
245
+ "options": {
246
+ "type": "array",
247
+ "items": {
248
+ "$ref": "#/$defs/option"
249
+ }
250
+ },
251
+ "allow_other": {
252
+ "description": "Adds a \"Something else\" card with a text field. Default: on when `options` is empty, off otherwise.",
253
+ "type": "boolean"
254
+ },
255
+ "other_label": {
256
+ "type": "string"
257
+ },
258
+ "other_placeholder": {
259
+ "type": "string"
260
+ },
261
+ "label": {
262
+ "description": "`text` input only — field label.",
263
+ "type": "string"
264
+ },
265
+ "placeholder": {
266
+ "description": "`text` input only — placeholder with a real example answer.",
267
+ "type": "string"
268
+ }
269
+ },
270
+ "required": [
271
+ "type"
272
+ ],
273
+ "additionalProperties": false
274
+ },
275
+ "option": {
276
+ "type": "object",
277
+ "properties": {
278
+ "value": {
279
+ "type": "string",
280
+ "minLength": 1,
281
+ "description": "Stable machine value echoed back in `answers[].values`."
282
+ },
283
+ "label": {
284
+ "type": "string",
285
+ "minLength": 1,
286
+ "description": "Short card title, a few words."
287
+ },
288
+ "description": {
289
+ "description": "One or two sentences: what this option is.",
290
+ "type": "string"
291
+ },
292
+ "consequences": {
293
+ "description": "What picking this implies downstream — a new plan phase, a one-way door, a dependency, a cost. The \"choose wisely\" line.",
294
+ "type": "string"
295
+ },
296
+ "recommended": {
297
+ "description": "Marks the agent's recommended default. At most one per decision.",
298
+ "type": "boolean"
299
+ },
300
+ "tags": {
301
+ "description": "Small pills under the card, e.g. `{label: \"One-way door\", tone: \"warn\"}`.",
302
+ "type": "array",
303
+ "items": {
304
+ "$ref": "#/$defs/tag"
305
+ }
306
+ },
307
+ "explainer": {
308
+ "description": "Rich explanation. Either inline Markdown (string or `{markdown}`) or a file under `<interview-dir>/docs/` (`{path}`). `.md` files render in the page with Mermaid support; `.html` files render in a sandboxed iframe for layouts Markdown cannot express.",
309
+ "$ref": "#/$defs/explainer"
310
+ }
311
+ },
312
+ "required": [
313
+ "value",
314
+ "label"
315
+ ],
316
+ "additionalProperties": false
317
+ },
318
+ "tag": {
319
+ "anyOf": [
320
+ {
321
+ "type": "string"
322
+ },
323
+ {
324
+ "type": "object",
325
+ "properties": {
326
+ "label": {
327
+ "type": "string"
328
+ },
329
+ "tone": {
330
+ "type": "string",
331
+ "enum": [
332
+ "neutral",
333
+ "warn",
334
+ "ok"
335
+ ]
336
+ }
337
+ },
338
+ "required": [
339
+ "label"
340
+ ],
341
+ "additionalProperties": false
342
+ }
343
+ ]
344
+ }
345
+ }
346
+ }
@@ -0,0 +1,342 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/vintasoftware/vinta-ai-workflows/schemas/plan-review.v1.schema.json",
4
+ "title": "vinta-ai-maestro plan review",
5
+ "description": "A plan review: comments on a plan-feature plan and the conversation about it between the person reviewing it and the agent that wrote it. Lives at `ai-plans/<workflow-id>.review.json` in a target project, beside the plan and its `.workflow.json`, and is committed with them. Written by the `vinta-ai-maestro` review page and by `vinta-ai-maestro review reply`; read by the agent running `plan-feature` through `vinta-ai-maestro review wait`. GENERATED from packages/vinta-ai-maestro/src/review/document.ts — edit there, not here. See schemas/README.md for versioning rules.",
6
+ "type": "object",
7
+ "properties": {
8
+ "$schema": {
9
+ "type": "string"
10
+ },
11
+ "schema_version": {
12
+ "type": "number",
13
+ "const": 1
14
+ },
15
+ "workflow_id": {
16
+ "type": "string",
17
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
18
+ },
19
+ "status": {
20
+ "type": "string",
21
+ "enum": [
22
+ "open",
23
+ "approved"
24
+ ]
25
+ },
26
+ "approved_at": {
27
+ "type": "string",
28
+ "minLength": 1
29
+ },
30
+ "comments": {
31
+ "type": "array",
32
+ "items": {
33
+ "type": "object",
34
+ "properties": {
35
+ "id": {
36
+ "type": "string",
37
+ "minLength": 1
38
+ },
39
+ "anchor": {
40
+ "oneOf": [
41
+ {
42
+ "type": "object",
43
+ "properties": {
44
+ "kind": {
45
+ "type": "string",
46
+ "const": "plan"
47
+ }
48
+ },
49
+ "required": [
50
+ "kind"
51
+ ],
52
+ "additionalProperties": false
53
+ },
54
+ {
55
+ "type": "object",
56
+ "properties": {
57
+ "kind": {
58
+ "type": "string",
59
+ "const": "section"
60
+ },
61
+ "section": {
62
+ "type": "string",
63
+ "minLength": 1,
64
+ "maxLength": 200
65
+ },
66
+ "heading": {
67
+ "type": "string",
68
+ "minLength": 1,
69
+ "maxLength": 300
70
+ }
71
+ },
72
+ "required": [
73
+ "kind",
74
+ "section"
75
+ ],
76
+ "additionalProperties": false
77
+ },
78
+ {
79
+ "type": "object",
80
+ "properties": {
81
+ "kind": {
82
+ "type": "string",
83
+ "const": "phase"
84
+ },
85
+ "node": {
86
+ "type": "string",
87
+ "minLength": 1,
88
+ "maxLength": 200
89
+ }
90
+ },
91
+ "required": [
92
+ "kind",
93
+ "node"
94
+ ],
95
+ "additionalProperties": false
96
+ },
97
+ {
98
+ "type": "object",
99
+ "properties": {
100
+ "kind": {
101
+ "type": "string",
102
+ "const": "prompt"
103
+ },
104
+ "node": {
105
+ "type": "string",
106
+ "minLength": 1,
107
+ "maxLength": 200
108
+ },
109
+ "role": {
110
+ "type": "string",
111
+ "enum": [
112
+ "implementer",
113
+ "fixer"
114
+ ]
115
+ }
116
+ },
117
+ "required": [
118
+ "kind",
119
+ "node",
120
+ "role"
121
+ ],
122
+ "additionalProperties": false
123
+ },
124
+ {
125
+ "type": "object",
126
+ "properties": {
127
+ "kind": {
128
+ "type": "string",
129
+ "const": "gate"
130
+ },
131
+ "gate": {
132
+ "type": "string",
133
+ "minLength": 1,
134
+ "maxLength": 200
135
+ },
136
+ "node": {
137
+ "type": "string",
138
+ "minLength": 1,
139
+ "maxLength": 200
140
+ }
141
+ },
142
+ "required": [
143
+ "kind",
144
+ "gate"
145
+ ],
146
+ "additionalProperties": false
147
+ }
148
+ ]
149
+ },
150
+ "quote": {
151
+ "type": "string",
152
+ "minLength": 1,
153
+ "maxLength": 2000
154
+ },
155
+ "author": {
156
+ "type": "object",
157
+ "properties": {
158
+ "kind": {
159
+ "type": "string",
160
+ "enum": [
161
+ "human",
162
+ "agent"
163
+ ]
164
+ },
165
+ "name": {
166
+ "type": "string",
167
+ "minLength": 1,
168
+ "maxLength": 200
169
+ }
170
+ },
171
+ "required": [
172
+ "kind"
173
+ ],
174
+ "additionalProperties": false
175
+ },
176
+ "body": {
177
+ "type": "string",
178
+ "minLength": 1,
179
+ "maxLength": 8000
180
+ },
181
+ "created_at": {
182
+ "type": "string",
183
+ "minLength": 1
184
+ },
185
+ "status": {
186
+ "type": "string",
187
+ "enum": [
188
+ "open",
189
+ "resolved"
190
+ ]
191
+ },
192
+ "resolved_at": {
193
+ "type": "string",
194
+ "minLength": 1
195
+ },
196
+ "sent_at": {
197
+ "type": "string",
198
+ "minLength": 1
199
+ },
200
+ "replies": {
201
+ "type": "array",
202
+ "items": {
203
+ "type": "object",
204
+ "properties": {
205
+ "id": {
206
+ "type": "string",
207
+ "minLength": 1
208
+ },
209
+ "author": {
210
+ "type": "object",
211
+ "properties": {
212
+ "kind": {
213
+ "type": "string",
214
+ "enum": [
215
+ "human",
216
+ "agent"
217
+ ]
218
+ },
219
+ "name": {
220
+ "type": "string",
221
+ "minLength": 1,
222
+ "maxLength": 200
223
+ }
224
+ },
225
+ "required": [
226
+ "kind"
227
+ ],
228
+ "additionalProperties": false
229
+ },
230
+ "body": {
231
+ "type": "string",
232
+ "minLength": 1,
233
+ "maxLength": 8000
234
+ },
235
+ "created_at": {
236
+ "type": "string",
237
+ "minLength": 1
238
+ },
239
+ "sent_at": {
240
+ "type": "string",
241
+ "minLength": 1
242
+ }
243
+ },
244
+ "required": [
245
+ "id",
246
+ "author",
247
+ "body",
248
+ "created_at"
249
+ ],
250
+ "additionalProperties": false
251
+ }
252
+ }
253
+ },
254
+ "required": [
255
+ "id",
256
+ "anchor",
257
+ "author",
258
+ "body",
259
+ "created_at",
260
+ "status",
261
+ "replies"
262
+ ],
263
+ "additionalProperties": false
264
+ }
265
+ },
266
+ "conversation": {
267
+ "type": "array",
268
+ "items": {
269
+ "type": "object",
270
+ "properties": {
271
+ "id": {
272
+ "type": "string",
273
+ "minLength": 1
274
+ },
275
+ "kind": {
276
+ "type": "string",
277
+ "enum": [
278
+ "message",
279
+ "approval"
280
+ ]
281
+ },
282
+ "author": {
283
+ "type": "object",
284
+ "properties": {
285
+ "kind": {
286
+ "type": "string",
287
+ "enum": [
288
+ "human",
289
+ "agent"
290
+ ]
291
+ },
292
+ "name": {
293
+ "type": "string",
294
+ "minLength": 1,
295
+ "maxLength": 200
296
+ }
297
+ },
298
+ "required": [
299
+ "kind"
300
+ ],
301
+ "additionalProperties": false
302
+ },
303
+ "body": {
304
+ "type": "string",
305
+ "maxLength": 8000
306
+ },
307
+ "created_at": {
308
+ "type": "string",
309
+ "minLength": 1
310
+ },
311
+ "comment_ids": {
312
+ "type": "array",
313
+ "items": {
314
+ "type": "string",
315
+ "minLength": 1
316
+ }
317
+ },
318
+ "delivered_at": {
319
+ "type": "string",
320
+ "minLength": 1
321
+ }
322
+ },
323
+ "required": [
324
+ "id",
325
+ "kind",
326
+ "author",
327
+ "body",
328
+ "created_at"
329
+ ],
330
+ "additionalProperties": false
331
+ }
332
+ }
333
+ },
334
+ "required": [
335
+ "schema_version",
336
+ "workflow_id",
337
+ "status",
338
+ "comments",
339
+ "conversation"
340
+ ],
341
+ "additionalProperties": false
342
+ }