@team-agent/installer 0.2.11 → 0.3.1

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 (326) hide show
  1. package/Cargo.lock +744 -0
  2. package/Cargo.toml +34 -0
  3. package/crates/team-agent/Cargo.toml +33 -0
  4. package/crates/team-agent/src/cli/adapters.rs +1343 -0
  5. package/crates/team-agent/src/cli/diagnose.rs +554 -0
  6. package/crates/team-agent/src/cli/emit.rs +1204 -0
  7. package/crates/team-agent/src/cli/helpers.rs +88 -0
  8. package/crates/team-agent/src/cli/leader.rs +216 -0
  9. package/crates/team-agent/src/cli/mod.rs +1207 -0
  10. package/crates/team-agent/src/cli/profile.rs +306 -0
  11. package/crates/team-agent/src/cli/send.rs +215 -0
  12. package/crates/team-agent/src/cli/status.rs +179 -0
  13. package/crates/team-agent/src/cli/status_port.rs +502 -0
  14. package/crates/team-agent/src/cli/tests/base.rs +616 -0
  15. package/crates/team-agent/src/cli/tests/compile.rs +96 -0
  16. package/crates/team-agent/src/cli/tests/divergence.rs +509 -0
  17. package/crates/team-agent/src/cli/tests/lane_c.rs +333 -0
  18. package/crates/team-agent/src/cli/tests/leader_watch.rs +395 -0
  19. package/crates/team-agent/src/cli/tests/main_preserved.rs +675 -0
  20. package/crates/team-agent/src/cli/tests/missing_subcommands.rs +390 -0
  21. package/crates/team-agent/src/cli/tests/mod.rs +97 -0
  22. package/crates/team-agent/src/cli/tests/peer_allow.rs +137 -0
  23. package/crates/team-agent/src/cli/tests/repair_state_byte_lock.rs +302 -0
  24. package/crates/team-agent/src/cli/tests/run_delegation.rs +305 -0
  25. package/crates/team-agent/src/cli/tests/status_send.rs +385 -0
  26. package/crates/team-agent/src/cli/tests/verb_profile.rs +182 -0
  27. package/crates/team-agent/src/cli/tests/verb_settle.rs +236 -0
  28. package/crates/team-agent/src/cli/tests/verb_validate.rs +184 -0
  29. package/crates/team-agent/src/cli/types.rs +605 -0
  30. package/crates/team-agent/src/compiler/tests.rs +701 -0
  31. package/crates/team-agent/src/compiler.rs +489 -0
  32. package/crates/team-agent/src/coordinator/backoff.rs +153 -0
  33. package/crates/team-agent/src/coordinator/health.rs +557 -0
  34. package/crates/team-agent/src/coordinator/mod.rs +80 -0
  35. package/crates/team-agent/src/coordinator/orphan.rs +179 -0
  36. package/crates/team-agent/src/coordinator/tests/abnormal.rs +255 -0
  37. package/crates/team-agent/src/coordinator/tests/basics.rs +262 -0
  38. package/crates/team-agent/src/coordinator/tests/daemon.rs +323 -0
  39. package/crates/team-agent/src/coordinator/tests/health_sync.rs +263 -0
  40. package/crates/team-agent/src/coordinator/tests/main_preserved.rs +136 -0
  41. package/crates/team-agent/src/coordinator/tests/mod.rs +310 -0
  42. package/crates/team-agent/src/coordinator/tests/spine.rs +261 -0
  43. package/crates/team-agent/src/coordinator/tests/takeover.rs +227 -0
  44. package/crates/team-agent/src/coordinator/tests/tick_core.rs +256 -0
  45. package/crates/team-agent/src/coordinator/tests/watch.rs +167 -0
  46. package/crates/team-agent/src/coordinator/tick.rs +2032 -0
  47. package/crates/team-agent/src/coordinator/types.rs +584 -0
  48. package/crates/team-agent/src/db/migration.rs +716 -0
  49. package/crates/team-agent/src/db/mod.rs +23 -0
  50. package/crates/team-agent/src/db/schema.rs +378 -0
  51. package/crates/team-agent/src/event_log.rs +375 -0
  52. package/crates/team-agent/src/fake_worker.rs +253 -0
  53. package/crates/team-agent/src/leader/helpers.rs +190 -0
  54. package/crates/team-agent/src/leader/inject.rs +33 -0
  55. package/crates/team-agent/src/leader/lease.rs +1084 -0
  56. package/crates/team-agent/src/leader/mod.rs +99 -0
  57. package/crates/team-agent/src/leader/owner_bind.rs +292 -0
  58. package/crates/team-agent/src/leader/rediscover/tests.rs +526 -0
  59. package/crates/team-agent/src/leader/rediscover.rs +1101 -0
  60. package/crates/team-agent/src/leader/start.rs +273 -0
  61. package/crates/team-agent/src/leader/takeover.rs +235 -0
  62. package/crates/team-agent/src/leader/tests/basics.rs +183 -0
  63. package/crates/team-agent/src/leader/tests/byte_findings.rs +237 -0
  64. package/crates/team-agent/src/leader/tests/identity.rs +206 -0
  65. package/crates/team-agent/src/leader/tests/idle.rs +272 -0
  66. package/crates/team-agent/src/leader/tests/lease_api.rs +225 -0
  67. package/crates/team-agent/src/leader/tests/lease_claim.rs +410 -0
  68. package/crates/team-agent/src/leader/tests/mod.rs +125 -0
  69. package/crates/team-agent/src/leader/tests/rediscover.rs +351 -0
  70. package/crates/team-agent/src/leader/tests/wake_start_owner.rs +204 -0
  71. package/crates/team-agent/src/leader/types.rs +489 -0
  72. package/crates/team-agent/src/lib.rs +85 -0
  73. package/crates/team-agent/src/lifecycle/display.rs +228 -0
  74. package/crates/team-agent/src/lifecycle/helpers.rs +112 -0
  75. package/crates/team-agent/src/lifecycle/launch/plan.rs +227 -0
  76. package/crates/team-agent/src/lifecycle/launch.rs +2109 -0
  77. package/crates/team-agent/src/lifecycle/mod.rs +62 -0
  78. package/crates/team-agent/src/lifecycle/restart/agent.rs +533 -0
  79. package/crates/team-agent/src/lifecycle/restart/common.rs +517 -0
  80. package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +41 -0
  81. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +268 -0
  82. package/crates/team-agent/src/lifecycle/restart/remove.rs +780 -0
  83. package/crates/team-agent/src/lifecycle/restart/selection.rs +208 -0
  84. package/crates/team-agent/src/lifecycle/restart/team_state.rs +242 -0
  85. package/crates/team-agent/src/lifecycle/restart.rs +76 -0
  86. package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +455 -0
  87. package/crates/team-agent/src/lifecycle/tests/core.rs +989 -0
  88. package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +583 -0
  89. package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +985 -0
  90. package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +265 -0
  91. package/crates/team-agent/src/lifecycle/tests.rs +27 -0
  92. package/crates/team-agent/src/lifecycle/types.rs +710 -0
  93. package/crates/team-agent/src/main.rs +41 -0
  94. package/crates/team-agent/src/mcp_server/helpers.rs +228 -0
  95. package/crates/team-agent/src/mcp_server/mod.rs +183 -0
  96. package/crates/team-agent/src/mcp_server/normalize.rs +312 -0
  97. package/crates/team-agent/src/mcp_server/tests/golden.rs +283 -0
  98. package/crates/team-agent/src/mcp_server/tests/normalize.rs +244 -0
  99. package/crates/team-agent/src/mcp_server/tests/scoped.rs +189 -0
  100. package/crates/team-agent/src/mcp_server/tests/send.rs +222 -0
  101. package/crates/team-agent/src/mcp_server/tests/tools.rs +158 -0
  102. package/crates/team-agent/src/mcp_server/tests/wire.rs +187 -0
  103. package/crates/team-agent/src/mcp_server/tests.rs +38 -0
  104. package/crates/team-agent/src/mcp_server/tools.rs +603 -0
  105. package/crates/team-agent/src/mcp_server/types.rs +421 -0
  106. package/crates/team-agent/src/mcp_server/wire.rs +468 -0
  107. package/crates/team-agent/src/message_store.rs +767 -0
  108. package/crates/team-agent/src/messaging/activity.rs +433 -0
  109. package/crates/team-agent/src/messaging/delivery.rs +743 -0
  110. package/crates/team-agent/src/messaging/helpers.rs +209 -0
  111. package/crates/team-agent/src/messaging/leader_receiver.rs +329 -0
  112. package/crates/team-agent/src/messaging/mod.rs +147 -0
  113. package/crates/team-agent/src/messaging/peers.rs +32 -0
  114. package/crates/team-agent/src/messaging/results.rs +553 -0
  115. package/crates/team-agent/src/messaging/scheduler.rs +344 -0
  116. package/crates/team-agent/src/messaging/selftest.rs +100 -0
  117. package/crates/team-agent/src/messaging/send.rs +578 -0
  118. package/crates/team-agent/src/messaging/tests/basic.rs +357 -0
  119. package/crates/team-agent/src/messaging/tests/main_preserved.rs +122 -0
  120. package/crates/team-agent/src/messaging/tests/mod.rs +293 -0
  121. package/crates/team-agent/src/messaging/tests/runtime.rs +1422 -0
  122. package/crates/team-agent/src/messaging/tests/spine.rs +437 -0
  123. package/crates/team-agent/src/messaging/trust.rs +192 -0
  124. package/crates/team-agent/src/messaging/types.rs +355 -0
  125. package/crates/team-agent/src/messaging/watchers.rs +591 -0
  126. package/crates/team-agent/src/model/enums.rs +311 -0
  127. package/crates/team-agent/src/model/errors.rs +17 -0
  128. package/crates/team-agent/src/model/ids.rs +155 -0
  129. package/crates/team-agent/src/model/mod.rs +22 -0
  130. package/crates/team-agent/src/model/paths.rs +228 -0
  131. package/crates/team-agent/src/model/permissions.rs +567 -0
  132. package/crates/team-agent/src/model/routing.rs +340 -0
  133. package/crates/team-agent/src/model/spec.rs +680 -0
  134. package/crates/team-agent/src/model/task_graph.rs +380 -0
  135. package/crates/team-agent/src/model/testdata/fuzz.golden.yaml +43 -0
  136. package/crates/team-agent/src/model/testdata/fuzz.yaml +43 -0
  137. package/crates/team-agent/src/model/testdata/spec_invalid_a.yaml +207 -0
  138. package/crates/team-agent/src/model/testdata/team.spec.golden.yaml +206 -0
  139. package/crates/team-agent/src/model/testdata/team.spec.yaml +206 -0
  140. package/crates/team-agent/src/model/yaml/tests.rs +288 -0
  141. package/crates/team-agent/src/model/yaml.rs +800 -0
  142. package/crates/team-agent/src/packaging/install.rs +305 -0
  143. package/crates/team-agent/src/packaging/migrate.rs +30 -0
  144. package/crates/team-agent/src/packaging/mod.rs +82 -0
  145. package/crates/team-agent/src/packaging/repair.rs +24 -0
  146. package/crates/team-agent/src/packaging/tests.rs +829 -0
  147. package/crates/team-agent/src/packaging/types.rs +369 -0
  148. package/crates/team-agent/src/provider/adapter.rs +801 -0
  149. package/crates/team-agent/src/provider/approvals/mod.rs +2 -0
  150. package/crates/team-agent/src/provider/approvals/parsing.rs +452 -0
  151. package/crates/team-agent/src/provider/approvals/runtime_prompts.rs +163 -0
  152. package/crates/team-agent/src/provider/classify.rs +456 -0
  153. package/crates/team-agent/src/provider/faults.rs +136 -0
  154. package/crates/team-agent/src/provider/helpers.rs +41 -0
  155. package/crates/team-agent/src/provider/mod.rs +53 -0
  156. package/crates/team-agent/src/provider/startup_prompt.rs +423 -0
  157. package/crates/team-agent/src/provider/tests/adapter.rs +239 -0
  158. package/crates/team-agent/src/provider/tests/classify.rs +240 -0
  159. package/crates/team-agent/src/provider/tests/faults.rs +120 -0
  160. package/crates/team-agent/src/provider/tests/idle.rs +208 -0
  161. package/crates/team-agent/src/provider/tests/wire.rs +213 -0
  162. package/crates/team-agent/src/provider/tests.rs +31 -0
  163. package/crates/team-agent/src/provider/types.rs +424 -0
  164. package/crates/team-agent/src/state/identity.rs +659 -0
  165. package/crates/team-agent/src/state/mod.rs +58 -0
  166. package/crates/team-agent/src/state/owner_gate.rs +423 -0
  167. package/crates/team-agent/src/state/persist.rs +712 -0
  168. package/crates/team-agent/src/state/projection.rs +657 -0
  169. package/crates/team-agent/src/state/selector.rs +105 -0
  170. package/crates/team-agent/src/state/testdata/state-rich.canonical.json +133 -0
  171. package/crates/team-agent/src/tmux_backend/tests.rs +765 -0
  172. package/crates/team-agent/src/tmux_backend.rs +810 -0
  173. package/crates/team-agent/src/transport/test_support.rs +252 -0
  174. package/crates/team-agent/src/transport/tests/behavior.rs +327 -0
  175. package/crates/team-agent/src/transport/tests/mod.rs +199 -0
  176. package/crates/team-agent/src/transport/tests/wire.rs +527 -0
  177. package/crates/team-agent/src/transport.rs +774 -0
  178. package/npm/install.mjs +118 -112
  179. package/package.json +15 -13
  180. package/crates/team-agent-core/Cargo.toml +0 -12
  181. package/crates/team-agent-core/src/lib.rs +0 -332
  182. package/crates/team-agent-core/src/main.rs +0 -152
  183. package/pyproject.toml +0 -18
  184. package/scripts/install.py +0 -88
  185. package/scripts/run_regression_tests.py +0 -83
  186. package/src/team_agent/__init__.py +0 -3
  187. package/src/team_agent/__main__.py +0 -5
  188. package/src/team_agent/_legacy_pane_discovery.py +0 -186
  189. package/src/team_agent/abnormal_track.py +0 -253
  190. package/src/team_agent/approvals/__init__.py +0 -65
  191. package/src/team_agent/approvals/constants.py +0 -6
  192. package/src/team_agent/approvals/parsing.py +0 -176
  193. package/src/team_agent/approvals/runtime_prompts.py +0 -171
  194. package/src/team_agent/approvals/status.py +0 -176
  195. package/src/team_agent/cli/__init__.py +0 -137
  196. package/src/team_agent/cli/commands.py +0 -481
  197. package/src/team_agent/cli/e2e.py +0 -202
  198. package/src/team_agent/cli/helpers.py +0 -226
  199. package/src/team_agent/cli/parser.py +0 -540
  200. package/src/team_agent/compiler.py +0 -334
  201. package/src/team_agent/coordinator/__init__.py +0 -53
  202. package/src/team_agent/coordinator/__main__.py +0 -119
  203. package/src/team_agent/coordinator/lifecycle.py +0 -411
  204. package/src/team_agent/coordinator/metadata.py +0 -61
  205. package/src/team_agent/coordinator/paths.py +0 -17
  206. package/src/team_agent/diagnose/__init__.py +0 -48
  207. package/src/team_agent/diagnose/checks.py +0 -101
  208. package/src/team_agent/diagnose/comms.py +0 -213
  209. package/src/team_agent/diagnose/health.py +0 -241
  210. package/src/team_agent/diagnose/orphan_cleanup.py +0 -364
  211. package/src/team_agent/diagnose/preflight.py +0 -194
  212. package/src/team_agent/diagnose/quick_start.py +0 -324
  213. package/src/team_agent/display/__init__.py +0 -92
  214. package/src/team_agent/display/adaptive.py +0 -511
  215. package/src/team_agent/display/backend.py +0 -46
  216. package/src/team_agent/display/close.py +0 -154
  217. package/src/team_agent/display/ghostty.py +0 -77
  218. package/src/team_agent/display/rebuild.py +0 -102
  219. package/src/team_agent/display/tiling.py +0 -156
  220. package/src/team_agent/display/worker_window.py +0 -114
  221. package/src/team_agent/display/workspace.py +0 -382
  222. package/src/team_agent/errors.py +0 -10
  223. package/src/team_agent/events.py +0 -84
  224. package/src/team_agent/fake_worker.py +0 -80
  225. package/src/team_agent/idle_predicate.py +0 -218
  226. package/src/team_agent/idle_takeover.py +0 -59
  227. package/src/team_agent/idle_takeover_wiring.py +0 -114
  228. package/src/team_agent/launch/__init__.py +0 -41
  229. package/src/team_agent/launch/bootstrap.py +0 -85
  230. package/src/team_agent/launch/config.py +0 -106
  231. package/src/team_agent/launch/core.py +0 -301
  232. package/src/team_agent/launch/requirements.py +0 -57
  233. package/src/team_agent/leader/__init__.py +0 -926
  234. package/src/team_agent/leader_binding.py +0 -183
  235. package/src/team_agent/lifecycle/__init__.py +0 -5
  236. package/src/team_agent/lifecycle/agents.py +0 -278
  237. package/src/team_agent/lifecycle/operations.py +0 -411
  238. package/src/team_agent/lifecycle/paste_buffer_hygiene.py +0 -39
  239. package/src/team_agent/lifecycle/start.py +0 -363
  240. package/src/team_agent/mcp_server/__init__.py +0 -42
  241. package/src/team_agent/mcp_server/__main__.py +0 -7
  242. package/src/team_agent/mcp_server/contracts.py +0 -148
  243. package/src/team_agent/mcp_server/normalize.py +0 -257
  244. package/src/team_agent/mcp_server/server.py +0 -150
  245. package/src/team_agent/mcp_server/tools.py +0 -352
  246. package/src/team_agent/message_store/__init__.py +0 -23
  247. package/src/team_agent/message_store/agent_health.py +0 -113
  248. package/src/team_agent/message_store/core.py +0 -497
  249. package/src/team_agent/message_store/leader_notification_log.py +0 -198
  250. package/src/team_agent/message_store/result_watchers.py +0 -251
  251. package/src/team_agent/message_store/schema.py +0 -308
  252. package/src/team_agent/message_store/schema_migration.py +0 -448
  253. package/src/team_agent/messaging/__init__.py +0 -1
  254. package/src/team_agent/messaging/activity_detector.py +0 -262
  255. package/src/team_agent/messaging/delivery.py +0 -504
  256. package/src/team_agent/messaging/deps.py +0 -247
  257. package/src/team_agent/messaging/idle_alerts.py +0 -423
  258. package/src/team_agent/messaging/internal_delivery.py +0 -46
  259. package/src/team_agent/messaging/leader.py +0 -497
  260. package/src/team_agent/messaging/leader_api_errors.py +0 -216
  261. package/src/team_agent/messaging/leader_panes.py +0 -673
  262. package/src/team_agent/messaging/owner_bypass.py +0 -29
  263. package/src/team_agent/messaging/result_delivery.py +0 -539
  264. package/src/team_agent/messaging/results.py +0 -447
  265. package/src/team_agent/messaging/scheduler.py +0 -450
  266. package/src/team_agent/messaging/send.py +0 -532
  267. package/src/team_agent/messaging/session_drift.py +0 -94
  268. package/src/team_agent/messaging/tmux_io.py +0 -506
  269. package/src/team_agent/messaging/tmux_prompt.py +0 -338
  270. package/src/team_agent/messaging/trust_auto_answer.py +0 -52
  271. package/src/team_agent/orchestrator/__init__.py +0 -376
  272. package/src/team_agent/orchestrator/plan.py +0 -122
  273. package/src/team_agent/orchestrator/state.py +0 -128
  274. package/src/team_agent/paths.py +0 -45
  275. package/src/team_agent/permissions.py +0 -123
  276. package/src/team_agent/profiles/__init__.py +0 -82
  277. package/src/team_agent/profiles/constants.py +0 -19
  278. package/src/team_agent/profiles/core.py +0 -407
  279. package/src/team_agent/profiles/helpers.py +0 -69
  280. package/src/team_agent/profiles/provider_env.py +0 -188
  281. package/src/team_agent/profiles/smoke.py +0 -201
  282. package/src/team_agent/provider_cli/__init__.py +0 -43
  283. package/src/team_agent/provider_cli/adapter.py +0 -172
  284. package/src/team_agent/provider_cli/base.py +0 -48
  285. package/src/team_agent/provider_cli/claude.py +0 -503
  286. package/src/team_agent/provider_cli/codex.py +0 -336
  287. package/src/team_agent/provider_cli/copilot.py +0 -8
  288. package/src/team_agent/provider_cli/fake.py +0 -39
  289. package/src/team_agent/provider_cli/gemini.py +0 -95
  290. package/src/team_agent/provider_cli/opencode.py +0 -8
  291. package/src/team_agent/provider_cli/prompt.py +0 -62
  292. package/src/team_agent/provider_cli/registry.py +0 -18
  293. package/src/team_agent/provider_cli/unsupported.py +0 -32
  294. package/src/team_agent/provider_state/README.md +0 -78
  295. package/src/team_agent/provider_state/__init__.py +0 -91
  296. package/src/team_agent/provider_state/claude.py +0 -86
  297. package/src/team_agent/provider_state/codex.py +0 -84
  298. package/src/team_agent/provider_state/common.py +0 -207
  299. package/src/team_agent/provider_state/registry.py +0 -118
  300. package/src/team_agent/providers.py +0 -163
  301. package/src/team_agent/quality_gates.py +0 -104
  302. package/src/team_agent/restart/__init__.py +0 -34
  303. package/src/team_agent/restart/orchestration.py +0 -554
  304. package/src/team_agent/restart/selection.py +0 -89
  305. package/src/team_agent/restart/snapshot.py +0 -70
  306. package/src/team_agent/routing.py +0 -84
  307. package/src/team_agent/runtime.py +0 -1243
  308. package/src/team_agent/rust_core.py +0 -327
  309. package/src/team_agent/sessions/__init__.py +0 -25
  310. package/src/team_agent/sessions/capture.py +0 -144
  311. package/src/team_agent/sessions/inventory.py +0 -44
  312. package/src/team_agent/sessions/resume.py +0 -135
  313. package/src/team_agent/simple_yaml.py +0 -236
  314. package/src/team_agent/spec.py +0 -370
  315. package/src/team_agent/state.py +0 -693
  316. package/src/team_agent/status/__init__.py +0 -63
  317. package/src/team_agent/status/approvals.py +0 -52
  318. package/src/team_agent/status/compact.py +0 -158
  319. package/src/team_agent/status/constants.py +0 -18
  320. package/src/team_agent/status/inbox.py +0 -58
  321. package/src/team_agent/status/peek.py +0 -117
  322. package/src/team_agent/status/queries.py +0 -199
  323. package/src/team_agent/task_graph.py +0 -80
  324. package/src/team_agent/terminal.py +0 -57
  325. package/src/team_agent/wake.py +0 -58
  326. package/src/team_agent/watch/__init__.py +0 -145
@@ -0,0 +1,236 @@
1
+ use super::*;
2
+
3
+ const SETTLE_SPEC_TEMPLATE: &str = r#"version: 1
4
+ team:
5
+ name: "fake-e2e"
6
+ mode: "supervisor_worker"
7
+ objective: "Exercise settle."
8
+ workspace: "__WS__"
9
+ leader:
10
+ id: "leader"
11
+ role: "leader"
12
+ provider: "fake"
13
+ model: null
14
+ tools:
15
+ - "fs_read"
16
+ - "fs_list"
17
+ - "mcp_team"
18
+ context_policy:
19
+ keep_user_thread: true
20
+ receive_worker_outputs: "structured_only"
21
+ max_worker_result_tokens: 2000
22
+ agents:
23
+ - id: "fake_impl"
24
+ role: "implementation_engineer"
25
+ provider: "fake"
26
+ model: null
27
+ working_directory: "__WS__"
28
+ system_prompt:
29
+ inline: "Handle fake implementation tasks."
30
+ file: null
31
+ tools:
32
+ - "fs_read"
33
+ - "fs_write"
34
+ - "fs_list"
35
+ - "execute_bash"
36
+ - "git_diff"
37
+ - "mcp_team"
38
+ - "provider_builtin"
39
+ permission_mode: "restricted"
40
+ preferred_for:
41
+ - "implementation"
42
+ avoid_for: []
43
+ output_contract:
44
+ format: "result_envelope_v1"
45
+ required_fields:
46
+ - "task_id"
47
+ - "status"
48
+ - "summary"
49
+ - "artifacts"
50
+ routing:
51
+ default_assignee: "leader"
52
+ rules:
53
+ - id: "implementation-to-fake"
54
+ match:
55
+ type:
56
+ - "implementation"
57
+ assign_to: "fake_impl"
58
+ priority: 10
59
+ communication:
60
+ protocol: "mcp_inbox"
61
+ topology: "leader_centered"
62
+ worker_to_worker: true
63
+ ack_timeout_sec: 2
64
+ result_format: "result_envelope_v1"
65
+ message_store:
66
+ sqlite: ".team/runtime/team.db"
67
+ mirror_files: ".team/messages"
68
+ runtime:
69
+ backend: "tmux"
70
+ display_backend: "none"
71
+ session_name: "team-agent-fake-e2e"
72
+ auto_launch: true
73
+ require_user_approval_before_launch: false
74
+ max_active_agents: 1
75
+ startup_order:
76
+ - "fake_impl"
77
+ context:
78
+ state_file: "team_state.md"
79
+ artifact_dir: ".team/artifacts"
80
+ log_dir: ".team/logs"
81
+ summarization:
82
+ worker_full_logs: "retain_outside_leader_context"
83
+ state_update: "after_each_result"
84
+ tasks:
85
+ - id: "task_impl"
86
+ title: "Fake implementation"
87
+ type: "implementation"
88
+ assignee: null
89
+ deps: []
90
+ acceptance:
91
+ - "fake result collected"
92
+ status: "pending"
93
+ "#;
94
+
95
+ fn seed_settle_workspace(ws: &std::path::Path) {
96
+ std::fs::create_dir_all(ws.join(".team").join("logs")).unwrap();
97
+ std::fs::create_dir_all(ws.join(".team").join("runtime")).unwrap();
98
+ std::fs::write(
99
+ ws.join("team.spec.yaml"),
100
+ SETTLE_SPEC_TEMPLATE.replace("__WS__", &ws.to_string_lossy()),
101
+ )
102
+ .unwrap();
103
+ crate::state::persist::save_runtime_state(
104
+ ws,
105
+ &json!({
106
+ "spec_path": ws.join("team.spec.yaml").to_string_lossy(),
107
+ "session_name": "team-agent-fake-e2e",
108
+ "leader": {"id": "leader"},
109
+ "agents": {"fake_impl": {"status": "stopped", "provider": "fake"}},
110
+ "tasks": [{
111
+ "id": "task_impl",
112
+ "title": "Fake implementation",
113
+ "type": "implementation",
114
+ "assignee": null,
115
+ "deps": [],
116
+ "acceptance": ["fake result collected"],
117
+ "status": "pending"
118
+ }]
119
+ }),
120
+ )
121
+ .unwrap();
122
+ }
123
+
124
+ // Golden source:
125
+ // - cli/parser.py:177-180 registers `settle --workspace . --json`; no timeout or polling args.
126
+ // - cli/commands.py:86-87 delegates to `runtime.settle(Path(args.workspace).resolve())`.
127
+ // - diagnose/quick_start.py:269-284: `settle` synchronously calls `collect(workspace)`,
128
+ // then `status(workspace, as_json=True)`, writes `settle-<int(time.time())>.json`,
129
+ // and returns `{ok, summary, next_actions, details_log, collect}`.
130
+ // - cli/helpers.py:12-16 success `--json` uses pretty sorted JSON; human output uses dict
131
+ // insertion order from the returned dict.
132
+ //
133
+ // Golden probe:
134
+ // PYTHONPATH=/Users/alauda/Documents/code/team-agent-public/src python3 /tmp/probe_settle_cli.py
135
+ // With a fake `tmux` executable returning exit 1, golden exits 0 and reports
136
+ // summary `collected 0 result(s)`.
137
+ #[test]
138
+ fn settle_success_json_byte_shape_wraps_collect() {
139
+ let ws = tmp_workspace();
140
+ seed_settle_workspace(&ws);
141
+
142
+ let result = cmd_settle(&SettleArgs {
143
+ workspace: ws.clone(),
144
+ json: true,
145
+ })
146
+ .expect("settle should return an ok result for an empty valid workspace");
147
+
148
+ assert_eq!(result.exit, ExitCode::Ok);
149
+ let CmdOutput::Json(value) = &result.output else {
150
+ panic!("settle must return a JSON dict");
151
+ };
152
+ assert_eq!(value["ok"], json!(true));
153
+ assert_eq!(value["summary"], json!("collected 0 result(s)"));
154
+ assert_eq!(
155
+ value["next_actions"],
156
+ json!(["Review team_state.md and decide whether to continue or shutdown."])
157
+ );
158
+ assert!(
159
+ value["details_log"]
160
+ .as_str()
161
+ .is_some_and(|p| p.contains("/.team/logs/settle-") && p.ends_with(".json")),
162
+ "settle must write a settle-<timestamp>.json details log; got {value}",
163
+ );
164
+ assert_eq!(value["collect"]["ok"], json!(true));
165
+ assert_eq!(value["collect"]["collected"], json!([]));
166
+ assert_eq!(value["collect"]["collected_results"], json!([]));
167
+ assert_eq!(value["collect"]["delivered_messages"], json!([]));
168
+ assert_eq!(value["collect"]["invalid_results"], json!([]));
169
+ assert_eq!(
170
+ value["collect"]["results"],
171
+ json!({
172
+ "total": 0,
173
+ "uncollected": 0,
174
+ "collected": 0,
175
+ "invalid": 0,
176
+ "by_status": {},
177
+ })
178
+ );
179
+ assert_eq!(
180
+ value["collect"]["state_file"],
181
+ json!(ws.join("team_state.md").to_string_lossy().to_string())
182
+ );
183
+ assert_eq!(value["collect"]["coordinator"]["ok"], json!(true));
184
+ assert_eq!(value["collect"]["coordinator"]["status"], json!("started"));
185
+ assert!(
186
+ value["collect"]["coordinator"]["log"]
187
+ .as_str()
188
+ .is_some_and(|p| p.ends_with("/.team/runtime/coordinator.log")),
189
+ "collect.coordinator.log must point at .team/runtime/coordinator.log; got {value}",
190
+ );
191
+
192
+ let expected = serde_json::to_string_pretty(&crate::cli::sort_json(value)).unwrap();
193
+ assert_eq!(
194
+ emit(&result.output, true).unwrap(),
195
+ expected,
196
+ "settle --json must emit Python's json.dumps(indent=2, sort_keys=True) byte shape",
197
+ );
198
+ let _ = std::fs::remove_dir_all(&ws);
199
+ }
200
+
201
+ #[test]
202
+ fn settle_success_human_output_insertion_order() {
203
+ let ws = tmp_workspace();
204
+ seed_settle_workspace(&ws);
205
+
206
+ let result = cmd_settle(&SettleArgs {
207
+ workspace: ws.clone(),
208
+ json: false,
209
+ })
210
+ .expect("settle should return an ok result for an empty valid workspace");
211
+
212
+ let human = emit(&result.output, false).unwrap();
213
+ assert!(
214
+ human.starts_with(
215
+ "ok: True\nsummary: collected 0 result(s)\nnext_actions: [\"Review team_state.md and decide whether to continue or shutdown.\"]\ndetails_log: "
216
+ ),
217
+ "non-json settle output must preserve Python returned-dict insertion order; got {human}",
218
+ );
219
+ assert!(
220
+ human.contains("\ncollect: {\"ok\": true, \"collected\": [], \"collected_results\": []"),
221
+ "non-json settle output must render nested collect as compact JSON after details_log; got {human}",
222
+ );
223
+ let _ = std::fs::remove_dir_all(&ws);
224
+ }
225
+
226
+ // Golden source:
227
+ // - cli/parser.py:177-180 default workspace is `.`.
228
+ // Current Rust dispatch has no `settle` arm; this must be RED until the porter routes it.
229
+ #[test]
230
+ fn dispatch_routes_settle_default_workspace() {
231
+ let ws = tmp_workspace();
232
+ seed_settle_workspace(&ws);
233
+ let code = run(&["settle".to_string(), "--json".to_string()], &ws);
234
+ assert_eq!(code, ExitCode::Ok, "`settle --json` must route and exit 0 for default workspace");
235
+ let _ = std::fs::remove_dir_all(&ws);
236
+ }
@@ -0,0 +1,184 @@
1
+ use super::*;
2
+
3
+ const VALIDATE_SPEC_TEMPLATE: &str = r#"version: 1
4
+ team:
5
+ name: "fake-e2e"
6
+ mode: "supervisor_worker"
7
+ objective: "Exercise validate."
8
+ workspace: "__WS__"
9
+ leader:
10
+ id: "leader"
11
+ role: "leader"
12
+ provider: "fake"
13
+ model: null
14
+ tools:
15
+ - "fs_read"
16
+ - "fs_list"
17
+ - "mcp_team"
18
+ context_policy:
19
+ keep_user_thread: true
20
+ receive_worker_outputs: "structured_only"
21
+ max_worker_result_tokens: 2000
22
+ agents:
23
+ - id: "fake_impl"
24
+ role: "implementation_engineer"
25
+ provider: "fake"
26
+ model: null
27
+ working_directory: "__WS__"
28
+ system_prompt:
29
+ inline: "Handle fake implementation tasks."
30
+ file: null
31
+ tools:
32
+ - "fs_read"
33
+ - "fs_write"
34
+ - "fs_list"
35
+ - "execute_bash"
36
+ - "git_diff"
37
+ - "mcp_team"
38
+ - "provider_builtin"
39
+ permission_mode: "restricted"
40
+ preferred_for:
41
+ - "implementation"
42
+ avoid_for: []
43
+ output_contract:
44
+ format: "result_envelope_v1"
45
+ required_fields:
46
+ - "task_id"
47
+ - "status"
48
+ - "summary"
49
+ - "artifacts"
50
+ routing:
51
+ default_assignee: "leader"
52
+ rules:
53
+ - id: "implementation-to-fake"
54
+ match:
55
+ type:
56
+ - "implementation"
57
+ assign_to: "fake_impl"
58
+ priority: 10
59
+ communication:
60
+ protocol: "mcp_inbox"
61
+ topology: "leader_centered"
62
+ worker_to_worker: true
63
+ ack_timeout_sec: 2
64
+ result_format: "result_envelope_v1"
65
+ message_store:
66
+ sqlite: ".team/runtime/team.db"
67
+ mirror_files: ".team/messages"
68
+ runtime:
69
+ backend: "tmux"
70
+ display_backend: "none"
71
+ session_name: "team-agent-fake-e2e"
72
+ auto_launch: true
73
+ require_user_approval_before_launch: false
74
+ max_active_agents: 1
75
+ startup_order:
76
+ - "fake_impl"
77
+ context:
78
+ state_file: "team_state.md"
79
+ artifact_dir: ".team/artifacts"
80
+ log_dir: ".team/logs"
81
+ summarization:
82
+ worker_full_logs: "retain_outside_leader_context"
83
+ state_update: "after_each_result"
84
+ tasks:
85
+ - id: "task_impl"
86
+ title: "Fake implementation"
87
+ type: "implementation"
88
+ assignee: null
89
+ deps: []
90
+ acceptance:
91
+ - "fake result collected"
92
+ status: "pending"
93
+ "#;
94
+
95
+ fn write_validate_spec(ws: &std::path::Path, file_name: &str, provider: &str) -> std::path::PathBuf {
96
+ let spec = VALIDATE_SPEC_TEMPLATE
97
+ .replace("__WS__", &ws.to_string_lossy())
98
+ .replacen("provider: \"fake\"", &format!("provider: \"{provider}\""), 1);
99
+ let path = ws.join(file_name);
100
+ std::fs::write(&path, spec).unwrap();
101
+ path
102
+ }
103
+
104
+ // Golden source:
105
+ // - cli/parser.py:120-123 registers `validate [spec=team.spec.yaml] --json`.
106
+ // - cli/commands.py:38-39 delegates to `runtime.validate_file(Path(args.spec).resolve())`.
107
+ // - launch/bootstrap.py:30-43: file specs return `{ok: True, workspace: str(workspace), team: name}`.
108
+ // - cli/helpers.py:12-16 JSON emits `json.dumps(..., indent=2, ensure_ascii=False, sort_keys=True)`.
109
+ //
110
+ // Golden probe:
111
+ // PYTHONPATH=/Users/alauda/Documents/code/team-agent-public/src python3 /tmp/probe_validate_cli.py
112
+ // valid file --json rc=0 stdout:
113
+ // {
114
+ // "ok": true,
115
+ // "team": "fake-e2e",
116
+ // "workspace": "<ws>"
117
+ // }
118
+ #[test]
119
+ fn validate_valid_spec_file_json_byte_shape() {
120
+ let ws = tmp_workspace();
121
+ let spec_path = write_validate_spec(&ws, "team.spec.yaml", "fake");
122
+
123
+ let result = cmd_validate(&ValidateArgs {
124
+ spec: spec_path.clone(),
125
+ json: true,
126
+ })
127
+ .expect("valid spec must return an ok CmdResult");
128
+
129
+ assert_eq!(result.exit, ExitCode::Ok);
130
+ assert_eq!(
131
+ emit(&result.output, true).unwrap(),
132
+ format!(
133
+ "{{\n \"ok\": true,\n \"team\": \"fake-e2e\",\n \"workspace\": \"{}\"\n}}",
134
+ ws.to_string_lossy()
135
+ ),
136
+ "validate --json must match Python sort_keys+indent bytes for a valid file spec",
137
+ );
138
+ let _ = std::fs::remove_dir_all(&ws);
139
+ }
140
+
141
+ // Golden source:
142
+ // - spec.py:85-91 accumulates validation messages and raises
143
+ // `team.spec.yaml validation failed:\n- ...`.
144
+ // - spec.py semantic provider check emits `/leader/provider: unknown provider 'bogus'`.
145
+ // - cli/helpers.py:137-155 error payload insertion order is `ok,error,action,log`.
146
+ // - cli/helpers.py:128-131 prints compact JSON, not pretty/sorted JSON, for `--json` errors.
147
+ #[test]
148
+ fn validate_invalid_spec_json_error_envelope_byte_shape() {
149
+ let ws = tmp_workspace();
150
+ let spec_path = write_validate_spec(&ws, "bad.spec.yaml", "bogus");
151
+
152
+ let err = cmd_validate(&ValidateArgs {
153
+ spec: spec_path,
154
+ json: true,
155
+ })
156
+ .expect_err("invalid spec must surface a CLI/runtime validation error");
157
+
158
+ assert_eq!(
159
+ err.to_string(),
160
+ "team.spec.yaml validation failed:\n- /leader/provider: unknown provider 'bogus'",
161
+ );
162
+ let payload = err.to_payload(&ws.join(".team/logs/cli-error-123.log"), "validate");
163
+ assert_eq!(
164
+ serde_json::to_string(&payload).unwrap(),
165
+ format!(
166
+ "{{\"ok\":false,\"error\":\"team.spec.yaml validation failed:\\n- /leader/provider: unknown provider 'bogus'\",\"action\":\"run `team-agent doctor` or inspect the log path shown here\",\"log\":\"{}\"}}",
167
+ ws.join(".team/logs/cli-error-123.log").to_string_lossy()
168
+ ),
169
+ "validate --json errors must match Python compact error envelope key order and text",
170
+ );
171
+ let _ = std::fs::remove_dir_all(&ws);
172
+ }
173
+
174
+ // Golden source:
175
+ // - cli/parser.py:120-123 default spec argument is `team.spec.yaml`.
176
+ // Current Rust dispatch has no `validate` arm; this must be RED until the porter routes it.
177
+ #[test]
178
+ fn dispatch_routes_validate_default_spec() {
179
+ let ws = tmp_workspace();
180
+ let _spec_path = write_validate_spec(&ws, "team.spec.yaml", "fake");
181
+ let code = run(&["validate".to_string(), "--json".to_string()], &ws);
182
+ assert_eq!(code, ExitCode::Ok, "`validate --json` must route and exit 0 for default team.spec.yaml");
183
+ let _ = std::fs::remove_dir_all(&ws);
184
+ }