@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,80 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import Any
4
-
5
- TASK_STATUSES = {
6
- "pending",
7
- "ready",
8
- "running",
9
- "blocked",
10
- "needs_retry",
11
- "done",
12
- "failed",
13
- "cancelled",
14
- }
15
-
16
- TERMINAL_TASK_STATUSES = {"done", "failed", "cancelled"}
17
-
18
-
19
- def find_dependency_cycle(tasks: list[dict[str, Any]]) -> list[str]:
20
- graph = {t.get("id"): list(t.get("deps", [])) for t in tasks if t.get("id")}
21
- visiting: set[str] = set()
22
- visited: set[str] = set()
23
- stack: list[str] = []
24
-
25
- def visit(node: str) -> list[str] | None:
26
- if node in visited:
27
- return None
28
- if node in visiting:
29
- if node in stack:
30
- return stack[stack.index(node) :] + [node]
31
- return [node, node]
32
- visiting.add(node)
33
- stack.append(node)
34
- for dep in graph.get(node, []):
35
- if dep in graph:
36
- cycle = visit(dep)
37
- if cycle:
38
- return cycle
39
- stack.pop()
40
- visiting.remove(node)
41
- visited.add(node)
42
- return None
43
-
44
- for node in graph:
45
- cycle = visit(node)
46
- if cycle:
47
- return cycle
48
- return []
49
-
50
-
51
- def ready_tasks(tasks: list[dict[str, Any]]) -> list[dict[str, Any]]:
52
- by_id = {t["id"]: t for t in tasks}
53
- ready: list[dict[str, Any]] = []
54
- for task in tasks:
55
- if task.get("status", "pending") not in {"pending", "ready", "needs_retry"}:
56
- continue
57
- deps_done = all(by_id.get(dep, {}).get("status") == "done" for dep in task.get("deps", []))
58
- if deps_done:
59
- ready.append(task)
60
- return ready
61
-
62
-
63
- def update_task_status(
64
- tasks: list[dict[str, Any]],
65
- task_id: str,
66
- status: str,
67
- summary: str | None = None,
68
- artifact_refs: list[dict[str, Any]] | None = None,
69
- ) -> None:
70
- if status not in TASK_STATUSES:
71
- raise ValueError(f"Unknown task status: {status}")
72
- for task in tasks:
73
- if task.get("id") == task_id:
74
- task["status"] = status
75
- if summary is not None:
76
- task["last_result_summary"] = summary
77
- if artifact_refs is not None:
78
- task["artifact_refs"] = artifact_refs
79
- return
80
- raise KeyError(f"Unknown task id: {task_id}")
@@ -1,57 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import shutil
4
- import subprocess
5
- from typing import Callable
6
-
7
-
8
- RunCommand = Callable[[list[str], int], subprocess.CompletedProcess[str]]
9
- SessionExists = Callable[[str | None], bool]
10
-
11
-
12
- def run_cmd(args: list[str], timeout: int = 20) -> subprocess.CompletedProcess[str]:
13
- return subprocess.run(args, text=True, capture_output=True, timeout=timeout, check=False)
14
-
15
-
16
- def shutil_which(command: str) -> str | None:
17
- return shutil.which(command)
18
-
19
-
20
- def tmux_session_exists(session_name: str | None, *, run: RunCommand = run_cmd) -> bool:
21
- if not session_name:
22
- return False
23
- proc = run(["tmux", "has-session", "-t", session_name], timeout=5)
24
- return proc.returncode == 0
25
-
26
-
27
- def tmux_window_exists(session_name: str | None, window: str | None, *, run: RunCommand = run_cmd) -> bool:
28
- if not session_name or not window:
29
- return False
30
- proc = run(["tmux", "list-windows", "-t", session_name, "-F", "#{window_name}"], timeout=5)
31
- if proc.returncode != 0:
32
- return False
33
- return window in proc.stdout.splitlines()
34
-
35
-
36
- def tmux_start_command_for_agent_window(
37
- session_name: str,
38
- window_name: str,
39
- command: str,
40
- *,
41
- session_exists: SessionExists = tmux_session_exists,
42
- ) -> tuple[list[str], str]:
43
- if session_exists(session_name):
44
- return ["tmux", "new-window", "-t", session_name, "-n", window_name, "sh", "-lc", command], "new-window"
45
- return ["tmux", "new-session", "-d", "-s", session_name, "-n", window_name, "sh", "-lc", command], "new-session"
46
-
47
-
48
- def tmux_stdout_last_line(stdout: str) -> str | None:
49
- lines = [line.strip() for line in stdout.splitlines() if line.strip()]
50
- return lines[-1] if lines else None
51
-
52
-
53
- def tmux_truthy(value: str) -> int:
54
- try:
55
- return 1 if int(value) > 0 else 0
56
- except (TypeError, ValueError):
57
- return 1 if value and value != "0" else 0
@@ -1,58 +0,0 @@
1
- """Provider-neutral wake layer (Gap 32 §2): decide WHEN to re-read a session
2
- file, never HOW to parse it. No polling loop, no screen, no provider names.
3
-
4
- Two cheap, passive sources:
5
- - a file-change watch (the caller wires FSEvents/inotify/kqueue and calls
6
- ``on_file_changed``) — naturally per-session (one file per node);
7
- - an mtime gate — only re-read the tail when the file changed since the last
8
- classification, or when it has been quiet past the debounce window.
9
- """
10
-
11
- from __future__ import annotations
12
-
13
- from typing import Any
14
-
15
-
16
- def should_reread(
17
- *,
18
- last_mtime: float | None,
19
- current_mtime: float | None,
20
- last_classified_mtime: float | None,
21
- now: float,
22
- debounce_seconds: float,
23
- ) -> dict[str, Any]:
24
- """Return whether a fresh tail-read is warranted and why.
25
-
26
- A read is warranted when the file changed since we last classified it, or
27
- when it has been silent longer than the debounce window and we have not yet
28
- classified at this mtime (so an idle-close that we already saw is not
29
- re-read forever).
30
- """
31
- if current_mtime is None:
32
- return {"reread": False, "reason": "no_file"}
33
- if last_classified_mtime is None:
34
- return {"reread": True, "reason": "never_classified"}
35
- if current_mtime != last_classified_mtime:
36
- return {"reread": True, "reason": "file_changed"}
37
- silent_for = max(0.0, now - current_mtime)
38
- if silent_for >= debounce_seconds:
39
- return {"reread": False, "reason": "quiescent_already_classified"}
40
- return {"reread": False, "reason": "unchanged"}
41
-
42
-
43
- def on_file_changed(watch_state: dict[str, Any] | None, *, node_id: str, mtime: float) -> dict[str, Any]:
44
- """Record a file-change wake for a node (the push path)."""
45
- state = dict(watch_state or {})
46
- pending = set(state.get("pending") or [])
47
- pending.add(node_id)
48
- state["pending"] = sorted(pending)
49
- state.setdefault("mtimes", {})[node_id] = mtime
50
- return state
51
-
52
-
53
- def take_pending(watch_state: dict[str, Any] | None) -> tuple[list[str], dict[str, Any]]:
54
- """Drain the set of nodes whose files changed since the last drain."""
55
- state = dict(watch_state or {})
56
- pending = sorted(state.get("pending") or [])
57
- state["pending"] = []
58
- return pending, state
@@ -1,145 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import json
4
- import time
5
- from dataclasses import dataclass, field
6
- from pathlib import Path
7
- from typing import Any, Callable
8
-
9
- from team_agent.message_store import MessageStore
10
- from team_agent.paths import logs_dir, runtime_dir
11
- from team_agent.status.queries import result_summary_from_row
12
-
13
-
14
- @dataclass
15
- class WatchCursor:
16
- event_offset: int = 0
17
- seen_result_ids: set[str] = field(default_factory=set)
18
- initialized: bool = False
19
- archive_signature: tuple[int, int] | None = None
20
-
21
-
22
- ROTATION_MARKER = "[watch] log rotated; archived segment events.jsonl.1 not replayed — historical replay deferred to a future --replay flag"
23
-
24
-
25
- def run_watch(
26
- workspace: Path,
27
- *,
28
- team: str | None = None,
29
- interval: float = 0.5,
30
- output: Callable[[str], None] = print,
31
- sleep: Callable[[float], None] = time.sleep,
32
- ) -> None:
33
- cursor = WatchCursor()
34
- while True:
35
- for line in collect_watch_lines(workspace, cursor, team=team):
36
- output(line)
37
- sleep(interval)
38
-
39
-
40
- def collect_watch_lines(workspace: Path, cursor: WatchCursor, *, team: str | None = None) -> list[str]:
41
- lines = _collect_event_lines(workspace, cursor, team=team)
42
- lines.extend(_collect_result_lines(workspace, cursor, team=team))
43
- return lines
44
-
45
-
46
- def render_event_line(event: dict[str, Any]) -> str | None:
47
- kind = event.get("event")
48
- if kind == "result_received":
49
- return _result_line(event.get("agent_id"), event.get("summary"))
50
- if kind in {"leader_receiver.injected", "leader_receiver.submitted"}:
51
- return f"leader_receiver.injected: {_message_snippet(event)} -> {_recipient(event)}"
52
- if kind == "send.failed":
53
- return f"send.failed: {_recipient(event)} reason={_clean(event.get('reason') or event.get('error') or '-')}"
54
- if kind == "leader_receiver.rebind_required":
55
- pane = event.get("old_pane_id") or event.get("pane_id") or event.get("target") or "-"
56
- reason = event.get("reason") or event.get("rediscovery_status") or "-"
57
- return f"leader_receiver.rebind_required: pane={pane} reason={_clean(reason)}"
58
- if kind == "leader.api_error":
59
- error_class = event.get("error_class") or "Unknown"
60
- provider = event.get("provider") or "-"
61
- snippet = _clean(event.get("matched_pattern_snippet") or event.get("snippet") or "-")
62
- return f"leader.api_error: {error_class} provider={provider} snippet={snippet}"
63
- return None
64
-
65
-
66
- def _collect_event_lines(workspace: Path, cursor: WatchCursor, *, team: str | None = None) -> list[str]:
67
- path = logs_dir(workspace) / "events.jsonl"
68
- archive_signature = _archive_signature(path.with_name("events.jsonl.1"))
69
- lines: list[str] = []
70
- if not cursor.initialized:
71
- cursor.archive_signature = archive_signature
72
- cursor.initialized = True
73
- elif archive_signature and archive_signature != cursor.archive_signature:
74
- lines.append(ROTATION_MARKER)
75
- cursor.archive_signature = archive_signature
76
- cursor.event_offset = 0
77
- if not path.exists():
78
- return lines
79
- size = path.stat().st_size
80
- if cursor.event_offset > size:
81
- if ROTATION_MARKER not in lines:
82
- lines.append(ROTATION_MARKER)
83
- cursor.event_offset = 0
84
- with path.open("r", encoding="utf-8") as handle:
85
- handle.seek(cursor.event_offset)
86
- for raw in handle:
87
- try:
88
- event = json.loads(raw)
89
- except json.JSONDecodeError:
90
- continue
91
- if team and _event_team_id(event) != team:
92
- continue
93
- rendered = render_event_line(event)
94
- if rendered:
95
- lines.append(rendered)
96
- cursor.event_offset = handle.tell()
97
- return lines
98
-
99
-
100
- def _collect_result_lines(workspace: Path, cursor: WatchCursor, *, team: str | None = None) -> list[str]:
101
- if not (runtime_dir(workspace) / "team.db").exists():
102
- return []
103
- store = MessageStore(workspace)
104
- lines: list[str] = []
105
- for row in store.latest_results(limit=20, owner_team_id=team):
106
- result_id = str(row.get("result_id") or "")
107
- if not result_id or result_id in cursor.seen_result_ids:
108
- continue
109
- cursor.seen_result_ids.add(result_id)
110
- summary = result_summary_from_row(row) or {}
111
- lines.append(_result_line(summary.get("agent_id"), summary.get("summary")))
112
- return lines
113
-
114
-
115
- def _result_line(agent_id: Any, summary: Any) -> str:
116
- return f"result_received: {agent_id or '-'} -> {_clean(summary or '-')[:80]}"
117
-
118
-
119
- def _message_snippet(event: dict[str, Any]) -> str:
120
- message_id = str(event.get("message_id") or event.get("msg_id") or "-")
121
- return message_id[:12] if message_id != "-" else "-"
122
-
123
-
124
- def _recipient(event: dict[str, Any]) -> str:
125
- return str(event.get("recipient") or event.get("to") or event.get("target") or "-")
126
-
127
-
128
- def _clean(value: Any) -> str:
129
- return " ".join(str(value).split())
130
-
131
-
132
- def _event_team_id(event: dict[str, Any]) -> str | None:
133
- value = event.get("team_id") or event.get("owner_team_id") or event.get("team")
134
- return str(value) if value else None
135
-
136
-
137
- def _archive_signature(path: Path) -> tuple[int, int] | None:
138
- try:
139
- stat = path.stat()
140
- except FileNotFoundError:
141
- return None
142
- return (stat.st_size, stat.st_mtime_ns)
143
-
144
-
145
- __all__ = ["ROTATION_MARKER", "WatchCursor", "collect_watch_lines", "render_event_line", "run_watch"]