@mmerterden/multi-agent-pipeline 20.29.0 → 20.30.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 (146) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +5 -5
  3. package/README.tr.md +5 -5
  4. package/docs/architecture.md +3 -3
  5. package/docs/ecosystem.md +5 -5
  6. package/docs/facts.json +7 -7
  7. package/install/catalog-history.json +1 -1
  8. package/install/claude.mjs +10 -1
  9. package/install/codex.mjs +2 -0
  10. package/install/copilot.mjs +13 -0
  11. package/manifest.json +149 -48
  12. package/package.json +2 -1
  13. package/pipeline/commands/multi-agent/autopilot-on/SKILL.md +13 -15
  14. package/pipeline/commands/multi-agent/office-off/SKILL.md +27 -0
  15. package/pipeline/commands/multi-agent/office-on/SKILL.md +50 -0
  16. package/pipeline/commands/multi-agent/office-status/SKILL.md +29 -0
  17. package/pipeline/commands/multi-agent/serve/SKILL.md +4 -2
  18. package/pipeline/commands/multi-agent/stack/SKILL.md +15 -8
  19. package/pipeline/commands/multi-agent/steer/SKILL.md +10 -9
  20. package/pipeline/commands/multi-agent/sync/SKILL.md +3 -3
  21. package/pipeline/contract/CHANGELOG.md +62 -0
  22. package/pipeline/contract/README.md +52 -6
  23. package/pipeline/contract/fixtures/error-invalid-request.json +1 -1
  24. package/pipeline/contract/fixtures/error-unauthorized.json +1 -1
  25. package/pipeline/contract/fixtures/error-unsigned.json +1 -1
  26. package/pipeline/contract/manifest.json +367 -22
  27. package/pipeline/contract/types/index.d.ts +530 -3
  28. package/pipeline/multi-agent-refs/cross-cli-contract.md +5 -4
  29. package/pipeline/multi-agent-refs/features/office-threat-model.md +91 -0
  30. package/pipeline/multi-agent-refs/help/en.md +3 -0
  31. package/pipeline/multi-agent-refs/help/tr.md +3 -0
  32. package/pipeline/office/NOTICE.md +42 -0
  33. package/pipeline/office/assets/BIN.png +0 -0
  34. package/pipeline/office/assets/BOOKSHELF.png +0 -0
  35. package/pipeline/office/assets/CACTUS.png +0 -0
  36. package/pipeline/office/assets/CLOCK.png +0 -0
  37. package/pipeline/office/assets/COFFEE.png +0 -0
  38. package/pipeline/office/assets/COFFEE_TABLE.png +0 -0
  39. package/pipeline/office/assets/CUSHIONED_BENCH.png +0 -0
  40. package/pipeline/office/assets/CUSHIONED_CHAIR_BACK.png +0 -0
  41. package/pipeline/office/assets/CUSHIONED_CHAIR_FRONT.png +0 -0
  42. package/pipeline/office/assets/CUSHIONED_CHAIR_SIDE.png +0 -0
  43. package/pipeline/office/assets/DESK_FRONT.png +0 -0
  44. package/pipeline/office/assets/DESK_SIDE.png +0 -0
  45. package/pipeline/office/assets/DOUBLE_BOOKSHELF.png +0 -0
  46. package/pipeline/office/assets/HANGING_PLANT.png +0 -0
  47. package/pipeline/office/assets/LARGE_PAINTING.png +0 -0
  48. package/pipeline/office/assets/LARGE_PLANT.png +0 -0
  49. package/pipeline/office/assets/PC_BACK.png +0 -0
  50. package/pipeline/office/assets/PC_FRONT_OFF.png +0 -0
  51. package/pipeline/office/assets/PC_FRONT_ON_1.png +0 -0
  52. package/pipeline/office/assets/PC_FRONT_ON_2.png +0 -0
  53. package/pipeline/office/assets/PC_FRONT_ON_3.png +0 -0
  54. package/pipeline/office/assets/PC_SIDE.png +0 -0
  55. package/pipeline/office/assets/PLANT.png +0 -0
  56. package/pipeline/office/assets/PLANT_2.png +0 -0
  57. package/pipeline/office/assets/POT.png +0 -0
  58. package/pipeline/office/assets/SMALL_PAINTING.png +0 -0
  59. package/pipeline/office/assets/SMALL_PAINTING_2.png +0 -0
  60. package/pipeline/office/assets/SMALL_TABLE_FRONT.png +0 -0
  61. package/pipeline/office/assets/SMALL_TABLE_SIDE.png +0 -0
  62. package/pipeline/office/assets/SOFA_BACK.png +0 -0
  63. package/pipeline/office/assets/SOFA_FRONT.png +0 -0
  64. package/pipeline/office/assets/SOFA_SIDE.png +0 -0
  65. package/pipeline/office/assets/TABLE_FRONT.png +0 -0
  66. package/pipeline/office/assets/WHITEBOARD.png +0 -0
  67. package/pipeline/office/assets/WOODEN_BENCH.png +0 -0
  68. package/pipeline/office/assets/WOODEN_CHAIR_BACK.png +0 -0
  69. package/pipeline/office/assets/WOODEN_CHAIR_FRONT.png +0 -0
  70. package/pipeline/office/assets/WOODEN_CHAIR_SIDE.png +0 -0
  71. package/pipeline/office/assets/char_0.png +0 -0
  72. package/pipeline/office/assets/char_1.png +0 -0
  73. package/pipeline/office/assets/char_2.png +0 -0
  74. package/pipeline/office/assets/char_3.png +0 -0
  75. package/pipeline/office/assets/char_4.png +0 -0
  76. package/pipeline/office/assets/char_5.png +0 -0
  77. package/pipeline/office/assets/floor_0.png +0 -0
  78. package/pipeline/office/assets/floor_1.png +0 -0
  79. package/pipeline/office/assets/floor_2.png +0 -0
  80. package/pipeline/office/assets/floor_3.png +0 -0
  81. package/pipeline/office/assets/floor_4.png +0 -0
  82. package/pipeline/office/assets/floor_5.png +0 -0
  83. package/pipeline/office/assets/floor_6.png +0 -0
  84. package/pipeline/office/assets/floor_7.png +0 -0
  85. package/pipeline/office/assets/floor_8.png +0 -0
  86. package/pipeline/office/assets/wall_0.png +0 -0
  87. package/pipeline/office/index.html +5319 -0
  88. package/pipeline/schemas/activity-chat.schema.json +78 -0
  89. package/pipeline/schemas/activity-roles.json +48 -0
  90. package/pipeline/schemas/activity-roles.schema.json +49 -0
  91. package/pipeline/schemas/activity.schema.json +429 -0
  92. package/pipeline/schemas/autopilot-on-request.schema.json +33 -0
  93. package/pipeline/schemas/autopilot-on.schema.json +111 -0
  94. package/pipeline/schemas/contract-error.schema.json +33 -3
  95. package/pipeline/schemas/issue-maturity.schema.json +68 -0
  96. package/pipeline/schemas/ledger.schema.json +202 -0
  97. package/pipeline/schemas/permissions.schema.json +47 -0
  98. package/pipeline/schemas/prefs.schema.json +19 -0
  99. package/pipeline/schemas/prs.schema.json +73 -0
  100. package/pipeline/schemas/review-verdict-request.schema.json +20 -0
  101. package/pipeline/schemas/review-verdict.schema.json +62 -0
  102. package/pipeline/schemas/routine-delete.schema.json +59 -0
  103. package/pipeline/schemas/routines.schema.json +38 -0
  104. package/pipeline/schemas/run-evidence.schema.json +29 -0
  105. package/pipeline/schemas/run-results.schema.json +218 -0
  106. package/pipeline/schemas/service-read.schema.json +58 -0
  107. package/pipeline/schemas/stack-change.schema.json +82 -0
  108. package/pipeline/schemas/stack-request.schema.json +33 -0
  109. package/pipeline/schemas/stack.schema.json +59 -0
  110. package/pipeline/schemas/steer-request.schema.json +25 -0
  111. package/pipeline/schemas/steer.schema.json +59 -0
  112. package/pipeline/schemas/tool-call-request.schema.json +19 -0
  113. package/pipeline/schemas/tool-call.schema.json +47 -0
  114. package/pipeline/schemas/tools.schema.json +60 -0
  115. package/pipeline/scripts/_cost.mjs +66 -1
  116. package/pipeline/scripts/_office-smoke-lib.sh +115 -0
  117. package/pipeline/scripts/_spawn-async.mjs +73 -0
  118. package/pipeline/scripts/_transcript-tail.mjs +274 -0
  119. package/pipeline/scripts/activity-snapshot.mjs +1027 -0
  120. package/pipeline/scripts/autopilot-control.mjs +214 -9
  121. package/pipeline/scripts/contract-server.mjs +1178 -48
  122. package/pipeline/scripts/cost-analyze.mjs +2 -53
  123. package/pipeline/scripts/cost-table.json +1 -0
  124. package/pipeline/scripts/office-build.mjs +89 -0
  125. package/pipeline/scripts/office-control.mjs +383 -0
  126. package/pipeline/scripts/office-ledger.mjs +409 -0
  127. package/pipeline/scripts/routine-registry.mjs +42 -6
  128. package/pipeline/scripts/run-results.mjs +373 -0
  129. package/pipeline/scripts/service-read.mjs +244 -0
  130. package/pipeline/scripts/stack-toggle.mjs +285 -0
  131. package/pipeline/scripts/steer-run.mjs +97 -0
  132. package/pipeline/scripts/toolkit-tools.mjs +599 -0
  133. package/pipeline/scripts/uninstall.mjs +3 -0
  134. package/pipeline/scripts/work-items.mjs +304 -0
  135. package/pipeline/skills/.skill-manifest.json +19 -7
  136. package/pipeline/skills/.skills-index.json +34 -1
  137. package/pipeline/skills/shared/README.md +6 -3
  138. package/pipeline/skills/shared/core/multi-agent-autopilot-on/SKILL.md +13 -15
  139. package/pipeline/skills/shared/core/multi-agent-office-off/SKILL.md +16 -0
  140. package/pipeline/skills/shared/core/multi-agent-office-on/SKILL.md +22 -0
  141. package/pipeline/skills/shared/core/multi-agent-office-status/SKILL.md +17 -0
  142. package/pipeline/skills/shared/core/multi-agent-serve/SKILL.md +4 -2
  143. package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +14 -6
  144. package/pipeline/skills/shared/core/multi-agent-steer/SKILL.md +10 -9
  145. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +3 -3
  146. package/pipeline/skills/skills-index.md +4 -1
@@ -0,0 +1,78 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/mmerterden/multi-agent-pipeline/pipeline/schemas/activity-chat.schema.json",
4
+ "title": "Agent chat page",
5
+ "description": "What GET /v1/agents/{sessionId}/{agentId}/chat returns and `activity-snapshot.mjs chat` prints: one page of an agent's transcript read from its end, oldest first, at most `limit` messages. Only user and assistant records are read; api-request records are never parsed and thinking blocks are never emitted. Every text has been through the redactor; a text the outbound gate still flags is replaced by a marker. `before` is the byte offset to send back for the previous page, null at the start of the file.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["contractVersion", "sessionId", "agentId", "messages", "before", "redacted"],
9
+ "properties": {
10
+ "contractVersion": {
11
+ "type": "string",
12
+ "pattern": "^1\\.[0-9]+\\.[0-9]+$",
13
+ "x-sensitivity": "none"
14
+ },
15
+ "sessionId": { "type": "string", "x-sensitivity": "none" },
16
+ "agentId": {
17
+ "type": ["string", "null"],
18
+ "description": "null for the session's own transcript (the orchestrator).",
19
+ "x-sensitivity": "none"
20
+ },
21
+ "messages": {
22
+ "type": "array",
23
+ "x-sensitivity": "none",
24
+ "items": {
25
+ "type": "object",
26
+ "additionalProperties": false,
27
+ "required": ["offset", "role", "at", "blocks"],
28
+ "properties": {
29
+ "offset": { "type": "integer", "minimum": 0 },
30
+ "role": { "enum": ["user", "assistant"] },
31
+ "at": { "type": ["string", "null"] },
32
+ "blocks": {
33
+ "type": "array",
34
+ "items": {
35
+ "oneOf": [
36
+ {
37
+ "type": "object",
38
+ "additionalProperties": false,
39
+ "required": ["kind", "text"],
40
+ "properties": { "kind": { "const": "text" }, "text": { "type": "string" } }
41
+ },
42
+ {
43
+ "type": "object",
44
+ "additionalProperties": false,
45
+ "required": ["kind", "name", "summary", "toolUseId"],
46
+ "properties": {
47
+ "kind": { "const": "tool" },
48
+ "name": { "type": "string" },
49
+ "summary": { "type": "string" },
50
+ "toolUseId": { "type": ["string", "null"] }
51
+ }
52
+ },
53
+ {
54
+ "type": "object",
55
+ "additionalProperties": false,
56
+ "required": ["kind", "toolUseId", "text", "isError"],
57
+ "properties": {
58
+ "kind": { "const": "result" },
59
+ "toolUseId": { "type": ["string", "null"] },
60
+ "text": { "type": "string" },
61
+ "isError": { "type": "boolean" }
62
+ }
63
+ }
64
+ ]
65
+ }
66
+ }
67
+ }
68
+ }
69
+ },
70
+ "before": { "type": ["integer", "null"], "minimum": 0, "x-sensitivity": "none" },
71
+ "redacted": {
72
+ "type": "integer",
73
+ "minimum": 0,
74
+ "description": "How many items the redactor replaced on this page.",
75
+ "x-sensitivity": "none"
76
+ }
77
+ }
78
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "$schema": "./activity-roles.schema.json",
3
+ "contractVersion": "1.0.0",
4
+ "description": "The role label shown above each agent in the office view, by agent type. activity-snapshot.mjs reads it and nothing else names a role. Labels stay English (they are technical names). A type in `untyped` takes its role from the run phase it was spawned in; a type in neither list is shown as its raw agentType, never guessed. smoke-activity-roles.sh fails when an agent under pipeline/agents/ is missing from `agentTypes`.",
5
+ "orchestrator": "Orchestrator",
6
+ "agentTypes": {
7
+ "task-clarifier": "Clarifier",
8
+ "test-gen-analyst": "Test Gap Analyst",
9
+ "explorer": "Explorer",
10
+ "Explore": "Explorer",
11
+ "Plan": "Planner",
12
+ "plan-critic": "Plan Critic",
13
+ "ios-architect": "iOS Architect",
14
+ "android-architect": "Android Architect",
15
+ "backend-architect": "Backend Architect",
16
+ "dev-critic": "Dev Critic",
17
+ "code-reviewer": "Reviewer",
18
+ "security-auditor": "Security Auditor",
19
+ "bulk-reader": "Reader"
20
+ },
21
+ "untyped": ["general-purpose", "claude", "fork"],
22
+ "phaseRoles": {
23
+ "1": "Planner",
24
+ "2": "Developer",
25
+ "3": "Reviewer",
26
+ "4": "Committer",
27
+ "5": "Reporter"
28
+ },
29
+ "styles": {
30
+ "Orchestrator": { "sprite": 0, "color": "#3d6fd8" },
31
+ "Clarifier": { "sprite": 1, "color": "#8a63d2" },
32
+ "Explorer": { "sprite": 2, "color": "#1f9e89" },
33
+ "Planner": { "sprite": 3, "color": "#d98b1f" },
34
+ "Plan Critic": { "sprite": 4, "color": "#c2553d" },
35
+ "iOS Architect": { "sprite": 5, "color": "#2b8bd6" },
36
+ "Android Architect": { "sprite": 5, "color": "#3f9c35" },
37
+ "Backend Architect": { "sprite": 5, "color": "#7a6a55" },
38
+ "Developer": { "sprite": 6, "color": "#2f8f5b" },
39
+ "Dev Critic": { "sprite": 4, "color": "#b5487a" },
40
+ "Test Gap Analyst": { "sprite": 2, "color": "#9a7b1c" },
41
+ "Reviewer": { "sprite": 7, "color": "#c43d3d" },
42
+ "Security Auditor": { "sprite": 8, "color": "#4a4a4a" },
43
+ "Reader": { "sprite": 2, "color": "#6b7f99" },
44
+ "Committer": { "sprite": 9, "color": "#5c6bc0" },
45
+ "Reporter": { "sprite": 9, "color": "#00897b" }
46
+ },
47
+ "unknownStyle": { "sprite": 10, "color": "#888888" }
48
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/mmerterden/multi-agent-pipeline/pipeline/schemas/activity-roles.schema.json",
4
+ "title": "Office role table",
5
+ "description": "The shape of activity-roles.json: the role label per agent type, the agent types whose role follows the run phase, the phase-to-role map and one fixed sprite and color per role.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "contractVersion",
10
+ "orchestrator",
11
+ "agentTypes",
12
+ "untyped",
13
+ "phaseRoles",
14
+ "styles",
15
+ "unknownStyle"
16
+ ],
17
+ "properties": {
18
+ "$schema": { "type": "string" },
19
+ "contractVersion": { "type": "string", "pattern": "^1\\.[0-9]+\\.[0-9]+$" },
20
+ "description": { "type": "string" },
21
+ "orchestrator": { "type": "string", "minLength": 1 },
22
+ "agentTypes": {
23
+ "type": "object",
24
+ "additionalProperties": { "type": "string", "minLength": 1 }
25
+ },
26
+ "untyped": { "type": "array", "items": { "type": "string", "minLength": 1 } },
27
+ "phaseRoles": {
28
+ "type": "object",
29
+ "propertyNames": { "pattern": "^[0-9]+$" },
30
+ "additionalProperties": { "type": "string", "minLength": 1 }
31
+ },
32
+ "styles": {
33
+ "type": "object",
34
+ "additionalProperties": { "$ref": "#/$defs/style" }
35
+ },
36
+ "unknownStyle": { "$ref": "#/$defs/style" }
37
+ },
38
+ "$defs": {
39
+ "style": {
40
+ "type": "object",
41
+ "additionalProperties": false,
42
+ "required": ["sprite", "color"],
43
+ "properties": {
44
+ "sprite": { "type": "integer", "minimum": 0, "maximum": 15 },
45
+ "color": { "type": "string", "pattern": "^#[0-9a-f]{6}$" }
46
+ }
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,429 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/mmerterden/multi-agent-pipeline/pipeline/schemas/activity.schema.json",
4
+ "title": "Office activity",
5
+ "description": "What GET /v1/activity returns and `activity-snapshot.mjs --json` prints, and what each GET /v1/activity/stream event carries: one room per repository, one table per run (its team; a session no run claims sits at a table of its own), one seat per agent seen in the recent window, the orchestrator at the head. Derived from disk on every call. No field is machine-local: there are no paths, seat labels come from allow-listed fields only (tool name, file basename, sidecar description), and every free-text string has been through the redactor, so the redacted and the full view are the same document.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["contractVersion", "generatedAt", "recentMinutes", "rooms", "corridors", "counts"],
9
+ "properties": {
10
+ "contractVersion": {
11
+ "type": "string",
12
+ "pattern": "^1\\.[0-9]+\\.[0-9]+$",
13
+ "x-sensitivity": "none"
14
+ },
15
+ "generatedAt": {
16
+ "type": "string",
17
+ "format": "date-time",
18
+ "x-sensitivity": "none"
19
+ },
20
+ "recentMinutes": {
21
+ "type": "number",
22
+ "description": "A session or subagent whose transcript changed within this window has a desk.",
23
+ "x-sensitivity": "none"
24
+ },
25
+ "counts": {
26
+ "type": "object",
27
+ "additionalProperties": false,
28
+ "required": ["rooms", "tables", "seats", "live", "waiting"],
29
+ "x-sensitivity": "none",
30
+ "properties": {
31
+ "rooms": {
32
+ "type": "integer",
33
+ "minimum": 0
34
+ },
35
+ "tables": {
36
+ "type": "integer",
37
+ "minimum": 0
38
+ },
39
+ "seats": {
40
+ "type": "integer",
41
+ "minimum": 0
42
+ },
43
+ "live": {
44
+ "type": "integer",
45
+ "minimum": 0
46
+ },
47
+ "waiting": {
48
+ "type": "integer",
49
+ "minimum": 0
50
+ }
51
+ }
52
+ },
53
+ "rooms": {
54
+ "type": "array",
55
+ "x-sensitivity": "none",
56
+ "items": {
57
+ "type": "object",
58
+ "additionalProperties": false,
59
+ "required": ["repo", "tables"],
60
+ "properties": {
61
+ "repo": {
62
+ "type": "string"
63
+ },
64
+ "tables": {
65
+ "type": "array",
66
+ "items": {
67
+ "$ref": "#/$defs/table"
68
+ }
69
+ }
70
+ }
71
+ }
72
+ },
73
+ "corridors": {
74
+ "type": "array",
75
+ "x-sensitivity": "none",
76
+ "description": "Runs over more than one repository: the table and the rooms its corridor joins.",
77
+ "items": {
78
+ "type": "object",
79
+ "additionalProperties": false,
80
+ "required": ["tableId", "repos"],
81
+ "properties": {
82
+ "tableId": {
83
+ "type": "string"
84
+ },
85
+ "repos": {
86
+ "type": "array",
87
+ "items": {
88
+ "type": "string"
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ },
95
+ "$defs": {
96
+ "table": {
97
+ "type": "object",
98
+ "additionalProperties": false,
99
+ "required": [
100
+ "id",
101
+ "kind",
102
+ "taskId",
103
+ "title",
104
+ "host",
105
+ "limited",
106
+ "sessionId",
107
+ "matchedBy",
108
+ "repos",
109
+ "phase",
110
+ "now",
111
+ "status",
112
+ "waitingForYou",
113
+ "pendingQuestion",
114
+ "tokens",
115
+ "estUsd",
116
+ "costSource",
117
+ "repo",
118
+ "location",
119
+ "branch",
120
+ "phaseHistory",
121
+ "startedAt",
122
+ "elapsedSeconds",
123
+ "holder",
124
+ "previousHolder",
125
+ "seats"
126
+ ],
127
+ "properties": {
128
+ "id": {
129
+ "type": "string"
130
+ },
131
+ "kind": {
132
+ "enum": ["run", "session", "unmatched"],
133
+ "description": "run: a pipeline run; session: a session no run claims (outside the pipeline); unmatched: a session more than one run could claim, kept apart rather than guessed."
134
+ },
135
+ "taskId": {
136
+ "type": ["string", "null"]
137
+ },
138
+ "title": {
139
+ "type": ["string", "null"]
140
+ },
141
+ "host": {
142
+ "enum": ["claude", "copilot", "codex"]
143
+ },
144
+ "limited": {
145
+ "type": "boolean",
146
+ "description": "true for a Copilot CLI or Codex session: no subagent detail exists there."
147
+ },
148
+ "sessionId": {
149
+ "type": ["string", "null"]
150
+ },
151
+ "matchedBy": {
152
+ "enum": ["session", "cwd-branch", null],
153
+ "description": "How the session was tied to the run: the session id the run recorded, or its working directory and branch."
154
+ },
155
+ "repos": {
156
+ "type": "array",
157
+ "items": {
158
+ "type": "string"
159
+ }
160
+ },
161
+ "phase": {
162
+ "oneOf": [
163
+ {
164
+ "type": "object",
165
+ "additionalProperties": false,
166
+ "required": ["id", "name", "last"],
167
+ "properties": {
168
+ "id": {
169
+ "type": "integer"
170
+ },
171
+ "name": {
172
+ "type": "string"
173
+ },
174
+ "last": {
175
+ "type": "integer",
176
+ "description": "The last phase id, for an n of last display."
177
+ }
178
+ }
179
+ },
180
+ {
181
+ "type": "null"
182
+ }
183
+ ]
184
+ },
185
+ "now": {
186
+ "type": ["string", "null"]
187
+ },
188
+ "status": {
189
+ "type": ["string", "null"]
190
+ },
191
+ "waitingForYou": {
192
+ "type": "boolean"
193
+ },
194
+ "pendingQuestion": {
195
+ "oneOf": [
196
+ {
197
+ "type": "object",
198
+ "additionalProperties": false,
199
+ "required": ["id", "text", "kind", "options"],
200
+ "properties": {
201
+ "id": {
202
+ "type": "string"
203
+ },
204
+ "text": {
205
+ "type": "string"
206
+ },
207
+ "kind": {
208
+ "enum": ["single-select", "multi-select"]
209
+ },
210
+ "options": {
211
+ "type": "array",
212
+ "items": {
213
+ "type": "object",
214
+ "additionalProperties": false,
215
+ "required": ["id", "label"],
216
+ "properties": {
217
+ "id": {
218
+ "type": "string"
219
+ },
220
+ "label": {
221
+ "type": "string"
222
+ }
223
+ }
224
+ }
225
+ }
226
+ }
227
+ },
228
+ {
229
+ "type": "null"
230
+ }
231
+ ]
232
+ },
233
+ "tokens": {
234
+ "oneOf": [
235
+ {
236
+ "type": "object",
237
+ "additionalProperties": false,
238
+ "required": ["in", "out", "cached"],
239
+ "properties": {
240
+ "in": {
241
+ "type": "integer",
242
+ "minimum": 0
243
+ },
244
+ "out": {
245
+ "type": "integer",
246
+ "minimum": 0
247
+ },
248
+ "cached": {
249
+ "type": "integer",
250
+ "minimum": 0
251
+ }
252
+ }
253
+ },
254
+ {
255
+ "type": "null"
256
+ }
257
+ ]
258
+ },
259
+ "estUsd": {
260
+ "type": ["number", "null"]
261
+ },
262
+ "costSource": {
263
+ "enum": ["tracker-state", "not-measured"],
264
+ "description": "Where tokens and estUsd come from. not-measured means the numbers are null, never 0."
265
+ },
266
+ "repo": {
267
+ "type": "string",
268
+ "description": "The room this table stands in."
269
+ },
270
+ "location": {
271
+ "enum": ["worktree", "local", "unknown"],
272
+ "description": "worktree: the run works in its own worktree; local: in the main checkout; unknown when the state does not say."
273
+ },
274
+ "branch": {
275
+ "type": ["string", "null"]
276
+ },
277
+ "phaseHistory": {
278
+ "type": "array",
279
+ "items": {
280
+ "type": "object",
281
+ "additionalProperties": false,
282
+ "required": ["id", "name", "status", "startedAt", "completedAt"],
283
+ "properties": {
284
+ "id": {
285
+ "type": ["integer", "null"]
286
+ },
287
+ "name": {
288
+ "type": "string"
289
+ },
290
+ "status": {
291
+ "type": "string"
292
+ },
293
+ "startedAt": {
294
+ "type": ["string", "null"]
295
+ },
296
+ "completedAt": {
297
+ "type": ["string", "null"]
298
+ }
299
+ }
300
+ }
301
+ },
302
+ "startedAt": {
303
+ "type": ["string", "null"]
304
+ },
305
+ "elapsedSeconds": {
306
+ "type": ["integer", "null"],
307
+ "minimum": 0
308
+ },
309
+ "holder": {
310
+ "type": ["string", "null"],
311
+ "description": "The seat id that holds the work now."
312
+ },
313
+ "previousHolder": {
314
+ "type": ["string", "null"],
315
+ "description": "The last seat of an earlier phase, for drawing the handoff."
316
+ },
317
+ "seats": {
318
+ "type": "array",
319
+ "items": {
320
+ "$ref": "#/$defs/seat"
321
+ }
322
+ }
323
+ }
324
+ },
325
+ "seat": {
326
+ "type": "object",
327
+ "additionalProperties": false,
328
+ "required": [
329
+ "id",
330
+ "sessionId",
331
+ "agentId",
332
+ "agentType",
333
+ "role",
334
+ "label",
335
+ "known",
336
+ "sprite",
337
+ "color",
338
+ "model",
339
+ "modelLabel",
340
+ "description",
341
+ "state",
342
+ "tool",
343
+ "detail",
344
+ "live",
345
+ "startedAt",
346
+ "lastAt",
347
+ "phase",
348
+ "status",
349
+ "doing"
350
+ ],
351
+ "properties": {
352
+ "id": {
353
+ "type": "string"
354
+ },
355
+ "sessionId": {
356
+ "type": ["string", "null"]
357
+ },
358
+ "agentId": {
359
+ "type": ["string", "null"],
360
+ "description": "null for the session's own (orchestrator) desk."
361
+ },
362
+ "agentType": {
363
+ "type": ["string", "null"]
364
+ },
365
+ "role": {
366
+ "type": "string"
367
+ },
368
+ "label": {
369
+ "type": "string",
370
+ "description": "The role, numbered when agents of the same role sit at one table (Reviewer 1, Reviewer 2)."
371
+ },
372
+ "known": {
373
+ "type": "boolean",
374
+ "description": "false when the agent type is in no role table entry and the raw type is shown."
375
+ },
376
+ "sprite": {
377
+ "type": "integer",
378
+ "minimum": 0
379
+ },
380
+ "color": {
381
+ "type": "string",
382
+ "pattern": "^#[0-9a-f]{6}$"
383
+ },
384
+ "model": {
385
+ "type": ["string", "null"]
386
+ },
387
+ "modelLabel": {
388
+ "type": ["string", "null"]
389
+ },
390
+ "description": {
391
+ "type": ["string", "null"],
392
+ "maxLength": 64
393
+ },
394
+ "state": {
395
+ "enum": ["reading", "writing", "spawning", "waiting", "idle", "done"]
396
+ },
397
+ "tool": {
398
+ "type": ["string", "null"]
399
+ },
400
+ "detail": {
401
+ "type": ["string", "null"]
402
+ },
403
+ "live": {
404
+ "type": ["boolean", "null"],
405
+ "description": "Whether the session is alive per `claude agents --json`; null when that list cannot be read."
406
+ },
407
+ "startedAt": {
408
+ "type": ["string", "null"],
409
+ "format": "date-time"
410
+ },
411
+ "lastAt": {
412
+ "type": ["string", "null"],
413
+ "format": "date-time"
414
+ },
415
+ "phase": {
416
+ "type": ["integer", "null"],
417
+ "description": "The run phase the agent was spawned in; null for the orchestrator or outside a run."
418
+ },
419
+ "status": {
420
+ "enum": ["working", "idle", "done"]
421
+ },
422
+ "doing": {
423
+ "type": "string",
424
+ "description": "What the seat is doing in a few plain words (Reading Foo.swift, Running a command), else the raw tool name."
425
+ }
426
+ }
427
+ }
428
+ }
429
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/mmerterden/multi-agent-pipeline/pipeline/schemas/autopilot-on-request.schema.json",
4
+ "title": "Autopilot on request",
5
+ "description": "The body of POST /v1/autopilot/on. The first request names the selection (repos, by nameWithOwner, each already in the autopilot config) and gets a preview and a confirm token; the second sends only the token and turns the mode on for exactly what was previewed. An empty selection is refused: the mode is never turned on without a repository.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["contractVersion"],
9
+ "properties": {
10
+ "contractVersion": {
11
+ "type": "string",
12
+ "pattern": "^1\\.[0-9]+\\.[0-9]+$",
13
+ "x-sensitivity": "none"
14
+ },
15
+ "repos": {
16
+ "type": "array",
17
+ "minItems": 1,
18
+ "maxItems": 50,
19
+ "items": {
20
+ "type": "string",
21
+ "pattern": "^[A-Za-z0-9._-]{1,100}(/[A-Za-z0-9._-]{1,100})?$"
22
+ }
23
+ },
24
+ "configureOnly": {
25
+ "type": "boolean",
26
+ "description": "Save the selection without scheduling anything."
27
+ },
28
+ "confirmToken": {
29
+ "type": "string",
30
+ "pattern": "^[A-Za-z0-9_-]{16,128}$"
31
+ }
32
+ }
33
+ }