@team-agent/installer 0.2.11 → 0.3.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 (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 +1077 -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 +1141 -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 +436 -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 +1063 -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 +525 -0
  59. package/crates/team-agent/src/leader/rediscover.rs +1099 -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 +234 -0
  64. package/crates/team-agent/src/leader/tests/identity.rs +206 -0
  65. package/crates/team-agent/src/leader/tests/idle.rs +271 -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 +253 -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 +487 -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 +1833 -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 +933 -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 +685 -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 +159 -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 +388 -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 +542 -0
  110. package/crates/team-agent/src/messaging/helpers.rs +209 -0
  111. package/crates/team-agent/src/messaging/leader_receiver.rs +340 -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 +537 -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 +582 -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 +656 -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 +586 -0
  172. package/crates/team-agent/src/tmux_backend.rs +758 -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 +90 -106
  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
@@ -1,213 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import os
4
- import uuid
5
- from pathlib import Path
6
- from typing import Any, Protocol
7
-
8
- from team_agent.state import load_runtime_state, select_runtime_state
9
-
10
-
11
- COMMS_BOUNDARY_TEXT = (
12
- "validates live pane binding consistency. Does NOT perform live runtime message round-trip. "
13
- "comms contract suite deferred to 0.2.9 (test files not shipped). (zero token, zero pollution)"
14
- )
15
-
16
-
17
- class CommsSelftestDriver(Protocol):
18
- """Injectable boundary for tests; production reads state only."""
19
-
20
-
21
- def run_comms_selftest(
22
- workspace: Path,
23
- *,
24
- team: str | None = None,
25
- gate: str | None = None,
26
- response_sla_sec: float = 20.0,
27
- probe_content: str | None = None,
28
- driver: CommsSelftestDriver | None = None,
29
- ) -> dict[str, Any]:
30
- del gate, response_sla_sec, probe_content
31
- workspace = workspace.resolve()
32
- driver = driver or _DefaultCommsSelftestDriver()
33
- run_id = _driver_call(driver, "run_id", default=None) or _driver_value(driver, "run_id", default=None) or uuid.uuid4().hex[:12]
34
- checks = {
35
- "receiver_binding": _receiver_binding_check(workspace, team, driver),
36
- "contract_suite": _contract_suite_check(workspace, driver),
37
- "provider_sdk_calls": _provider_sdk_calls_check(driver),
38
- }
39
- ok = all(_check_pass(check) for check in checks.values())
40
- return {
41
- "ok": ok,
42
- "status": "pass" if ok else "fail",
43
- "run_id": run_id,
44
- "scope": "binding_consistency",
45
- "boundary": COMMS_BOUNDARY_TEXT,
46
- "checks": checks,
47
- }
48
-
49
-
50
- def evaluate_idle_behavior(
51
- workspace: Path,
52
- *,
53
- agent_id: str,
54
- claimed_status: str,
55
- response_sla_sec: float = 20.0,
56
- token: str | None = None,
57
- driver: CommsSelftestDriver | None = None,
58
- ) -> dict[str, Any]:
59
- run_id = uuid.uuid4().hex[:12]
60
- probe_token = token or f"idle-challenge-{run_id}"
61
- driver = driver or _DefaultCommsSelftestDriver()
62
- result = _driver_call(
63
- driver,
64
- "evaluate_idle_behavior",
65
- workspace.resolve(),
66
- agent_id=agent_id,
67
- claimed_status=claimed_status,
68
- response_sla_sec=response_sla_sec,
69
- token=probe_token,
70
- default=None,
71
- )
72
- if isinstance(result, dict):
73
- return _normalize_idle_result(result, probe_token)
74
- idle_execution = _driver_value(driver, "idle_execution", default=None)
75
- if idle_execution is not None:
76
- execution = str(idle_execution.get("status") if isinstance(idle_execution, dict) else idle_execution)
77
- return {
78
- "ok": execution not in {"timeout", "fail", "failed"},
79
- "agent_id": agent_id,
80
- "claimed_status": claimed_status,
81
- "token": probe_token,
82
- "status": "pass" if execution not in {"timeout", "fail", "failed"} else "fail",
83
- "execution_ack": execution,
84
- "classification_accuracy": "pass" if execution not in {"timeout", "fail", "failed"} else "fail",
85
- }
86
- status = str(claimed_status or "").upper()
87
- return {
88
- "ok": status in {"IDLE", "WORKING", "RUNNING"},
89
- "agent_id": agent_id,
90
- "claimed_status": claimed_status,
91
- "token": probe_token,
92
- "status": "not_challenged",
93
- "execution_ack": "pass" if status in {"IDLE", "WORKING", "RUNNING"} else "timeout",
94
- }
95
-
96
-
97
- def _receiver_binding_check(workspace: Path, team: str | None, driver: CommsSelftestDriver) -> dict[str, Any]:
98
- override = _driver_call(driver, "receiver_binding", workspace, team=team, default=None)
99
- if isinstance(override, dict):
100
- out = dict(override)
101
- out.setdefault("status", "pass" if out.get("ok", True) else "fail")
102
- out.setdefault("verifies", "binding_consistency")
103
- out.setdefault("proof", "state_read")
104
- out.setdefault("state_read_observed", True)
105
- return out
106
- state = _selftest_state(workspace, team, driver)
107
- receiver = state.get("leader_receiver") if isinstance(state.get("leader_receiver"), dict) else {}
108
- owner = state.get("team_owner") if isinstance(state.get("team_owner"), dict) else {}
109
- receiver_pane = str(receiver.get("pane_id") or "")
110
- owner_pane = str(owner.get("pane_id") or "")
111
- caller_pane = str(_driver_call(driver, "current_pane_id", default=None) or os.environ.get("TMUX_PANE") or "")
112
- mismatches: list[str] = []
113
- if owner_pane and receiver_pane and owner_pane != receiver_pane:
114
- mismatches.append("owner_receiver_pane_mismatch")
115
- if caller_pane and owner_pane and caller_pane != owner_pane:
116
- mismatches.append("caller_owner_pane_mismatch")
117
- if caller_pane and receiver_pane and caller_pane != receiver_pane:
118
- mismatches.append("caller_receiver_pane_mismatch")
119
- return {
120
- "status": "fail" if mismatches else "pass",
121
- "verifies": "binding_consistency",
122
- "proof": "state_read",
123
- "state_read_observed": True,
124
- "pane_id": receiver_pane,
125
- "owner_pane_id": owner_pane,
126
- "caller_pane_id": caller_pane,
127
- "mismatches": mismatches,
128
- "configured": bool(receiver_pane),
129
- }
130
-
131
-
132
- def _contract_suite_check(workspace: Path, driver: CommsSelftestDriver) -> dict[str, Any]:
133
- del workspace, driver
134
- return {
135
- "status": "deferred",
136
- "deferred_to": "0.2.9",
137
- "reason": "contract test files not shipped with package",
138
- "message": "comms contract verification deferred to 0.2.9; contract test files not shipped with package",
139
- }
140
-
141
-
142
- def _provider_sdk_calls_check(driver: CommsSelftestDriver) -> dict[str, Any]:
143
- calls = _driver_value(driver, "provider_sdk_calls", default=None)
144
- if not isinstance(calls, dict):
145
- calls = {"anthropic": 0, "openai": 0, "httpx": 0}
146
- calls = {name: int(calls.get(name, 0) or 0) for name in ("anthropic", "openai", "httpx")}
147
- return {
148
- "status": "fail" if any(calls.values()) else "pass",
149
- "verifies": "no_provider_sdk_calls",
150
- "calls": calls,
151
- }
152
-
153
-
154
- def _selftest_state(workspace: Path, team: str | None, driver: CommsSelftestDriver) -> dict[str, Any]:
155
- override = _driver_call(driver, "select_runtime_state", workspace, team=team, default=None)
156
- if isinstance(override, dict):
157
- return dict(override)
158
- override = _driver_call(driver, "load_runtime_state", workspace, default=None)
159
- if isinstance(override, dict):
160
- return dict(override)
161
- override = _driver_value(driver, "state", default=None)
162
- if isinstance(override, dict):
163
- return dict(override)
164
- override = _driver_value(driver, "state_before", default=None)
165
- if isinstance(override, dict):
166
- return dict(override)
167
- return select_runtime_state(workspace, team)
168
-
169
-
170
- def _check_pass(value: Any) -> bool:
171
- if not isinstance(value, dict):
172
- return False
173
- if value.get("status") == "deferred":
174
- return True
175
- return value.get("status") in {"pass", "not_implemented"} and _has_required_evidence(value)
176
-
177
-
178
- def _has_required_evidence(value: dict[str, Any]) -> bool:
179
- verifies = value.get("verifies")
180
- if verifies == "binding_consistency":
181
- return value.get("proof") == "state_read" and value.get("state_read_observed") is True
182
- if verifies == "no_provider_sdk_calls":
183
- calls = value.get("calls") if isinstance(value.get("calls"), dict) else {}
184
- return all(int(calls.get(name, 0) or 0) == 0 for name in ("anthropic", "openai", "httpx"))
185
- return value.get("status") == "pass"
186
-
187
-
188
- def _normalize_idle_result(result: dict[str, Any], token: str) -> dict[str, Any]:
189
- out = dict(result)
190
- out.setdefault("token", token)
191
- if "execution_ack" not in out:
192
- if out.get("ok") is False or out.get("status") in {"timeout", "busy", "fail"}:
193
- out["execution_ack"] = "timeout"
194
- else:
195
- out["execution_ack"] = "pass"
196
- return out
197
-
198
-
199
- def _driver_call(driver: CommsSelftestDriver | None, name: str, *args: Any, default: Any = None, **kwargs: Any) -> Any:
200
- fn = getattr(driver, name, None)
201
- if not callable(fn):
202
- return default
203
- return fn(*args, **kwargs)
204
-
205
-
206
- def _driver_value(driver: CommsSelftestDriver | None, name: str, default: Any = None) -> Any:
207
- if driver is None:
208
- return default
209
- return getattr(driver, name, default)
210
-
211
-
212
- class _DefaultCommsSelftestDriver:
213
- pass
@@ -1,241 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from pathlib import Path
4
- from typing import Any
5
-
6
- from team_agent.diagnose.checks import (
7
- compact_model_checks,
8
- model_checks_for_agents,
9
- profile_checks_for_agents,
10
- )
11
- from team_agent.events import EventLog
12
- from team_agent.message_store import MessageStore
13
- from team_agent.paths import logs_dir, runtime_dir
14
- from team_agent.profiles import compact_profile_check
15
- from team_agent.spec import load_spec, workspace_from_spec
16
- from team_agent.state import load_runtime_state
17
-
18
-
19
- def diagnose(workspace: Path) -> dict[str, Any]:
20
- from team_agent.runtime import (
21
- _capture_has_team_orchestrator_mcp_prompt,
22
- _leader_receiver_is_direct,
23
- _tmux_session_exists,
24
- _tmux_window_exists,
25
- _validate_leader_receiver,
26
- get_adapter,
27
- run_cmd,
28
- status,
29
- )
30
- _ = EventLog # imported for symmetry / future use
31
- state = load_runtime_state(workspace)
32
- spec_path = Path(state.get("spec_path", workspace / "team.spec.yaml"))
33
- spec = load_spec(spec_path) if spec_path.exists() else {}
34
- store = MessageStore(workspace)
35
- issues: list[dict[str, Any]] = []
36
- suggested_repairs: list[dict[str, Any]] = [
37
- {
38
- "kind": "mcp_approval_prompt",
39
- "action": "If a worker pane asks to allow team_orchestrator, select Allow for this session; then run team-agent collect.",
40
- },
41
- {
42
- "kind": "codex_command_approval_prompt",
43
- "action": "If a worker pane asks to run a shell command, approve only after checking the command; long servers should use pid/log/health-check protocol.",
44
- },
45
- {
46
- "kind": "interrupted_worker",
47
- "action": "Send: Continue from the current interrupted prompt. Do not redo completed work. Do the next bounded step, then report result_envelope_v1.",
48
- },
49
- {
50
- "kind": "leader_receiver",
51
- "action": "Worker-to-leader status requires a direct tmux leader receiver. Run team-agent attach-leader --workspace . --provider codex, or pass --pane <pane_id>.",
52
- },
53
- {
54
- "kind": "process_list_unavailable",
55
- "action": "If pgrep/lsof fail, use pid files, logs, and health-check URLs; record the environment blocker instead of retrying process-list commands.",
56
- },
57
- ]
58
- session_name = state.get("session_name")
59
- if session_name and not _tmux_session_exists(session_name):
60
- issues.append(
61
- {
62
- "kind": "tmux_session_missing",
63
- "session": session_name,
64
- "reason": "tmux has no matching session",
65
- "suggestion": "Run team-agent launch again or inspect .team/logs/events.jsonl for the shutdown/failure event.",
66
- }
67
- )
68
- leader_receiver = state.get("leader_receiver", {})
69
- if not _leader_receiver_is_direct(leader_receiver):
70
- issues.append(
71
- {
72
- "kind": "leader_not_attached",
73
- "mode": leader_receiver.get("mode", "fallback_inbox" if leader_receiver else "none"),
74
- "suggestion": "Run team-agent attach-leader --workspace . --provider codex, or pass --pane <pane_id> for the existing Codex leader pane.",
75
- }
76
- )
77
- else:
78
- validation = _validate_leader_receiver(leader_receiver)
79
- if not validation["ok"]:
80
- issues.append(
81
- {
82
- "kind": validation["reason"],
83
- "target": leader_receiver.get("pane_id"),
84
- "provider": leader_receiver.get("provider"),
85
- "error": validation.get("error"),
86
- "suggestion": "Run team-agent attach-leader --workspace . --provider codex again with a live Codex pane.",
87
- }
88
- )
89
- elif validation.get("warning"):
90
- issues.append(
91
- {
92
- "kind": "leader_command_unexpected",
93
- "target": leader_receiver.get("pane_id"),
94
- "provider": leader_receiver.get("provider"),
95
- "command": validation.get("pane", {}).get("pane_current_command"),
96
- "warning": validation["warning"],
97
- "suggestion": "If this is not the real Codex leader pane, rerun attach-leader with --pane <pane_id>.",
98
- }
99
- )
100
- for agent in spec.get("agents", []):
101
- adapter = get_adapter(agent["provider"])
102
- if not adapter.is_installed():
103
- issues.append(
104
- {
105
- "kind": "provider_missing",
106
- "agent_id": agent["id"],
107
- "provider": agent["provider"],
108
- "command": adapter.command_name,
109
- "suggestion": f"Install {adapter.command_name} and authenticate it before launch.",
110
- }
111
- )
112
- mcp_path = runtime_dir(workspace) / "mcp" / f"{agent['id']}.json"
113
- if not mcp_path.exists():
114
- issues.append(
115
- {
116
- "kind": "mcp_not_installed",
117
- "agent_id": agent["id"],
118
- "provider": agent["provider"],
119
- "path": str(mcp_path),
120
- "suggestion": "Run team-agent launch to regenerate provider MCP config.",
121
- }
122
- )
123
- agent_state = state.get("agents", {}).get(agent["id"], {})
124
- if agent_state.get("status") == "interrupted":
125
- issues.append(
126
- {
127
- "kind": "worker_interrupted",
128
- "agent_id": agent["id"],
129
- "suggestion": "Send the standard recovery prompt instead of redispatching the full task.",
130
- }
131
- )
132
- window = agent_state.get("window", agent["id"])
133
- if session_name and _tmux_window_exists(session_name, window):
134
- proc = run_cmd(["tmux", "capture-pane", "-p", "-S", "-80", "-t", f"{session_name}:{window}"], timeout=5)
135
- output = proc.stdout if proc.returncode == 0 else ""
136
- if _capture_has_team_orchestrator_mcp_prompt(output):
137
- issues.append(
138
- {
139
- "kind": "mcp_approval_prompt",
140
- "agent_id": agent["id"],
141
- "suggestion": "Team Agent will auto-approve allowlisted internal MCP prompts; if still blocked, inspect team-agent approvals.",
142
- }
143
- )
144
- if "Would you like to run the following command" in output:
145
- issues.append(
146
- {
147
- "kind": "codex_command_approval_prompt",
148
- "agent_id": agent["id"],
149
- "suggestion": "Review and approve or reject the command in the worker pane; do not keep waiting silently.",
150
- }
151
- )
152
- if "Conversation interrupted" in output:
153
- issues.append(
154
- {
155
- "kind": "worker_interrupted",
156
- "agent_id": agent["id"],
157
- "suggestion": "Send the standard recovery prompt instead of redispatching the full task.",
158
- }
159
- )
160
- timeout_sec = int(spec.get("communication", {}).get("ack_timeout_sec", 60)) if spec else 60
161
- failed_messages = store.fail_timeouts(timeout_sec)
162
- for message_id in failed_messages:
163
- issues.append(
164
- {
165
- "kind": "message_ack_timeout",
166
- "message_id": message_id,
167
- "suggestion": "Check target worker status and scrollback; message stayed unacknowledged past timeout.",
168
- }
169
- )
170
- return {
171
- "ok": not issues,
172
- "issues": issues,
173
- "suggested_repairs": suggested_repairs,
174
- "runtime": status(workspace, as_json=True),
175
- "event_log": str(logs_dir(workspace) / "events.jsonl"),
176
- }
177
-
178
-
179
- def doctor(spec_path: Path | None = None) -> dict[str, Any]:
180
- from team_agent.runtime import _attach_team_profile_dirs, coordinator_health, get_adapter, shutil_which
181
- providers = ["codex"]
182
- spec = None
183
- workspace = Path.cwd()
184
- if spec_path:
185
- spec = load_spec(spec_path)
186
- workspace = workspace_from_spec(spec, spec_path)
187
- _attach_team_profile_dirs(spec, spec_path, workspace)
188
- providers = sorted({a["provider"] for a in spec.get("agents", []) if a["provider"] != "fake"})
189
- checks: dict[str, Any] = {
190
- "tmux": {
191
- "installed": bool(shutil_which("tmux")),
192
- "path": shutil_which("tmux"),
193
- },
194
- "workspace": str(workspace),
195
- "workspace_is_git_repo": (workspace / ".git").exists(),
196
- "providers": {},
197
- "mcp": {
198
- "server_command": shutil_which("team_orchestrator"),
199
- "local_module": True,
200
- },
201
- "coordinator": coordinator_health(workspace),
202
- }
203
- for provider in providers:
204
- adapter = get_adapter(provider)
205
- checks["providers"][provider] = {
206
- "command": adapter.command_name,
207
- "installed": adapter.is_installed(),
208
- "version": adapter.version(),
209
- "auth": adapter.auth_hint(),
210
- }
211
- model_checks = model_checks_for_agents(spec.get("agents", []), workspace) if spec else []
212
- if spec:
213
- checks["models"] = compact_model_checks(model_checks)
214
- profile_checks = profile_checks_for_agents(workspace, spec.get("agents", []))
215
- checks["profiles"] = [compact_profile_check(item) for item in profile_checks]
216
- missing_required = [
217
- provider for provider, result in checks["providers"].items() if not result["installed"] and spec_path
218
- ]
219
- missing_auth = [
220
- provider
221
- for provider, result in checks["providers"].items()
222
- if spec_path and result.get("auth", {}).get("status") == "missing"
223
- ]
224
- invalid_models = [item for item in model_checks if item.get("ok") is False]
225
- invalid_profiles = [item for item in checks.get("profiles", []) if item.get("ok") is False]
226
- checks["ok"] = (
227
- checks["tmux"]["installed"]
228
- and not missing_required
229
- and not missing_auth
230
- and not invalid_models
231
- and not invalid_profiles
232
- )
233
- if missing_required:
234
- checks["missing_required_providers"] = missing_required
235
- if missing_auth:
236
- checks["missing_provider_auth"] = missing_auth
237
- if invalid_models:
238
- checks["invalid_models"] = compact_model_checks(invalid_models)
239
- if invalid_profiles:
240
- checks["invalid_profiles"] = invalid_profiles
241
- return checks