@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
@@ -1,332 +0,0 @@
1
- use std::process::Command;
2
-
3
- #[derive(Debug, Clone, PartialEq, Eq)]
4
- pub struct Target {
5
- pub pane_id: String,
6
- pub session_name: String,
7
- pub window_index: String,
8
- pub window_name: String,
9
- pub pane_index: String,
10
- pub pane_tty: String,
11
- pub pane_current_command: String,
12
- pub pane_active: bool,
13
- }
14
-
15
- impl Target {
16
- pub fn fingerprint(&self) -> String {
17
- format!(
18
- "{}|{}|{}|{}",
19
- self.session_name, self.window_index, self.pane_index, self.pane_tty
20
- )
21
- }
22
- }
23
-
24
- #[derive(Debug, Clone, PartialEq, Eq)]
25
- pub enum TargetResolution {
26
- Resolved(Target),
27
- Ambiguous(Vec<Target>),
28
- Missing,
29
- }
30
-
31
- #[derive(Debug, Clone, PartialEq, Eq)]
32
- pub enum DeliveryStatus {
33
- Accepted,
34
- TargetResolved,
35
- Injected,
36
- Visible,
37
- Failed,
38
- Ambiguous,
39
- }
40
-
41
- impl DeliveryStatus {
42
- pub fn as_str(&self) -> &'static str {
43
- match self {
44
- DeliveryStatus::Accepted => "accepted",
45
- DeliveryStatus::TargetResolved => "target_resolved",
46
- DeliveryStatus::Injected => "injected",
47
- DeliveryStatus::Visible => "visible",
48
- DeliveryStatus::Failed => "failed",
49
- DeliveryStatus::Ambiguous => "ambiguous",
50
- }
51
- }
52
-
53
- pub fn can_transition_to(&self, next: &DeliveryStatus) -> bool {
54
- matches!(
55
- (self, next),
56
- (DeliveryStatus::Accepted, DeliveryStatus::TargetResolved)
57
- | (DeliveryStatus::Accepted, DeliveryStatus::Failed)
58
- | (DeliveryStatus::Accepted, DeliveryStatus::Ambiguous)
59
- | (DeliveryStatus::TargetResolved, DeliveryStatus::Injected)
60
- | (DeliveryStatus::TargetResolved, DeliveryStatus::Failed)
61
- | (DeliveryStatus::TargetResolved, DeliveryStatus::Ambiguous)
62
- | (DeliveryStatus::Injected, DeliveryStatus::Visible)
63
- | (DeliveryStatus::Injected, DeliveryStatus::Failed)
64
- | (DeliveryStatus::Visible, DeliveryStatus::Failed)
65
- )
66
- }
67
- }
68
-
69
- #[derive(Debug, Clone, PartialEq, Eq)]
70
- pub struct DeliveryError {
71
- pub code: String,
72
- pub message: String,
73
- }
74
-
75
- pub fn list_tmux_targets() -> Result<Vec<Target>, String> {
76
- let format = "#{pane_id}\t#{session_name}\t#{window_index}\t#{window_name}\t#{pane_index}\t#{pane_tty}\t#{pane_current_command}\t#{pane_active}";
77
- let output = Command::new("tmux")
78
- .args(["list-panes", "-a", "-F", format])
79
- .output()
80
- .map_err(|err| format!("tmux list-panes failed: {err}"))?;
81
- if !output.status.success() {
82
- return Err(String::from_utf8_lossy(&output.stderr).trim().to_string());
83
- }
84
- Ok(String::from_utf8_lossy(&output.stdout)
85
- .lines()
86
- .filter_map(parse_target_line)
87
- .collect())
88
- }
89
-
90
- pub fn parse_target_line(line: &str) -> Option<Target> {
91
- let parts: Vec<&str> = line.split('\t').collect();
92
- if parts.len() != 8 {
93
- return None;
94
- }
95
- Some(Target {
96
- pane_id: parts[0].to_string(),
97
- session_name: parts[1].to_string(),
98
- window_index: parts[2].to_string(),
99
- window_name: parts[3].to_string(),
100
- pane_index: parts[4].to_string(),
101
- pane_tty: parts[5].to_string(),
102
- pane_current_command: parts[6].to_string(),
103
- pane_active: parts[7] == "1",
104
- })
105
- }
106
-
107
- pub fn resolve_target(candidates: Vec<Target>, expected_fingerprint: Option<&str>) -> TargetResolution {
108
- if let Some(fingerprint) = expected_fingerprint {
109
- let matched: Vec<Target> = candidates
110
- .iter()
111
- .cloned()
112
- .filter(|target| target.fingerprint() == fingerprint)
113
- .collect();
114
- if matched.len() == 1 {
115
- return TargetResolution::Resolved(matched[0].clone());
116
- }
117
- if matched.len() > 1 {
118
- return TargetResolution::Ambiguous(matched);
119
- }
120
- }
121
- let usable: Vec<Target> = candidates
122
- .into_iter()
123
- .filter(|target| {
124
- let cmd = target
125
- .pane_current_command
126
- .rsplit('/')
127
- .next()
128
- .unwrap_or(&target.pane_current_command);
129
- matches!(cmd, "codex" | "node" | "nodejs")
130
- })
131
- .collect();
132
- match usable.len() {
133
- 0 => TargetResolution::Missing,
134
- 1 => TargetResolution::Resolved(usable[0].clone()),
135
- _ => TargetResolution::Ambiguous(usable),
136
- }
137
- }
138
-
139
- pub fn render_message(sender: &str, task_id: Option<&str>, content: &str, token: &str) -> String {
140
- let mut header = format!("Team Agent message from {}", sender);
141
- if let Some(task) = task_id {
142
- if !task.is_empty() {
143
- header.push_str(" for ");
144
- header.push_str(task);
145
- }
146
- }
147
- format!("{header}:\n\n{content}\n\n[team-agent-token:{token}]")
148
- }
149
-
150
- pub fn redact_secrets(input: &str) -> String {
151
- let mut out = Vec::new();
152
- for raw in input.split_whitespace() {
153
- let lower = raw.to_ascii_lowercase();
154
- let redacted = lower.contains("api_key")
155
- || lower.contains("apikey")
156
- || lower.contains("token=")
157
- || lower.contains("secret")
158
- || lower == "bearer"
159
- || raw.starts_with("sk-")
160
- || looks_base64_secret(raw);
161
- out.push(if redacted { "[REDACTED]" } else { raw });
162
- }
163
- out.join(" ")
164
- }
165
-
166
- pub fn looks_base64_secret(value: &str) -> bool {
167
- value.len() >= 32
168
- && value
169
- .chars()
170
- .all(|ch| ch.is_ascii_alphanumeric() || matches!(ch, '+' | '/' | '=' | '_' | '-'))
171
- }
172
-
173
- #[derive(Debug, Clone, PartialEq, Eq)]
174
- pub struct Profile {
175
- pub provider: String,
176
- pub model: String,
177
- pub auth_mode: String,
178
- pub profile: String,
179
- pub credential_ref: Option<String>,
180
- }
181
-
182
- pub fn validate_profile(profile: &Profile) -> Result<(), Vec<String>> {
183
- let mut errors = Vec::new();
184
- if !matches!(
185
- profile.auth_mode.as_str(),
186
- "subscription" | "official_api" | "compatible_api"
187
- ) {
188
- errors.push("auth_mode must be subscription, official_api, or compatible_api".to_string());
189
- }
190
- if profile.provider.is_empty() {
191
- errors.push("provider must not be empty".to_string());
192
- }
193
- if profile.model.is_empty() {
194
- errors.push("model must not be empty".to_string());
195
- }
196
- if profile.profile.is_empty() {
197
- errors.push("profile must not be empty".to_string());
198
- }
199
- for value in [
200
- &profile.provider,
201
- &profile.model,
202
- &profile.auth_mode,
203
- &profile.profile,
204
- ] {
205
- if contains_inline_secret(value) {
206
- errors.push("profile metadata contains a probable inline secret".to_string());
207
- break;
208
- }
209
- }
210
- if errors.is_empty() {
211
- Ok(())
212
- } else {
213
- Err(errors)
214
- }
215
- }
216
-
217
- pub fn contains_inline_secret(value: &str) -> bool {
218
- contains_secret_assignment(value)
219
- || contains_bearer_secret(value)
220
- || value
221
- .split_whitespace()
222
- .any(|chunk| chunk.starts_with("sk-") || looks_base64_secret(chunk))
223
- || value.starts_with("sk-")
224
- || looks_base64_secret(value)
225
- }
226
-
227
- fn contains_secret_assignment(value: &str) -> bool {
228
- for line in value.lines() {
229
- for separator in ['=', ':'] {
230
- let Some((key, raw)) = line.split_once(separator) else {
231
- continue;
232
- };
233
- let normalized: String = key
234
- .to_ascii_lowercase()
235
- .chars()
236
- .filter(|ch| ch.is_ascii_alphanumeric())
237
- .collect();
238
- if !matches!(
239
- normalized.as_str(),
240
- "apikey" | "token" | "secret" | "password" | "credential"
241
- ) {
242
- continue;
243
- }
244
- let candidate = raw.trim().trim_matches(|ch| ch == '"' || ch == '\'');
245
- if candidate.starts_with("sk-") || candidate.len() >= 8 || looks_base64_secret(candidate) {
246
- return true;
247
- }
248
- }
249
- }
250
- false
251
- }
252
-
253
- fn contains_bearer_secret(value: &str) -> bool {
254
- let mut previous_was_bearer = false;
255
- for chunk in value.split_whitespace() {
256
- if previous_was_bearer && chunk.len() >= 16 && chunk.chars().all(|ch| {
257
- ch.is_ascii_alphanumeric() || matches!(ch, '.' | '_' | '~' | '+' | '/' | '=' | '-')
258
- }) {
259
- return true;
260
- }
261
- previous_was_bearer = chunk.eq_ignore_ascii_case("bearer");
262
- }
263
- false
264
- }
265
-
266
- pub fn json_escape(input: &str) -> String {
267
- let mut out = String::new();
268
- for ch in input.chars() {
269
- match ch {
270
- '"' => out.push_str("\\\""),
271
- '\\' => out.push_str("\\\\"),
272
- '\n' => out.push_str("\\n"),
273
- '\r' => out.push_str("\\r"),
274
- '\t' => out.push_str("\\t"),
275
- ch if ch.is_control() => out.push_str(&format!("\\u{:04x}", ch as u32)),
276
- ch => out.push(ch),
277
- }
278
- }
279
- out
280
- }
281
-
282
- #[cfg(test)]
283
- mod tests {
284
- use super::*;
285
-
286
- #[test]
287
- fn parses_target_and_fingerprint() {
288
- let target = parse_target_line("%1\ts\t2\tw\t0\t/dev/ttys001\tnode\t1").unwrap();
289
- assert_eq!(target.pane_id, "%1");
290
- assert_eq!(target.fingerprint(), "s|2|0|/dev/ttys001");
291
- }
292
-
293
- #[test]
294
- fn delivery_state_transitions_are_explicit() {
295
- assert!(DeliveryStatus::Accepted.can_transition_to(&DeliveryStatus::TargetResolved));
296
- assert!(DeliveryStatus::TargetResolved.can_transition_to(&DeliveryStatus::Injected));
297
- assert!(DeliveryStatus::Injected.can_transition_to(&DeliveryStatus::Visible));
298
- assert!(!DeliveryStatus::Accepted.can_transition_to(&DeliveryStatus::Visible));
299
- }
300
-
301
- #[test]
302
- fn renders_human_readable_message() {
303
- let rendered = render_message("worker", Some("task_a"), "done", "msg_1");
304
- assert!(rendered.contains("Team Agent message from worker for task_a:"));
305
- assert!(rendered.contains("[team-agent-token:msg_1]"));
306
- }
307
-
308
- #[test]
309
- fn redacts_common_secret_shapes() {
310
- let redacted = redact_secrets("Authorization Bearer sk-test abcdefghijklmnopqrstuvwxyz123456");
311
- assert!(redacted.contains("[REDACTED]"));
312
- assert!(!redacted.contains("sk-test"));
313
- }
314
-
315
- #[test]
316
- fn inline_secret_scan_allows_ordinary_token_prose() {
317
- assert!(!contains_inline_secret("Use the visible token in logs for delivery evidence."));
318
- assert!(contains_inline_secret("API_KEY=sk-inline-secret"));
319
- }
320
-
321
- #[test]
322
- fn profile_rejects_inline_secret() {
323
- let profile = Profile {
324
- provider: "codex".to_string(),
325
- model: "gpt-5.5".to_string(),
326
- auth_mode: "subscription".to_string(),
327
- profile: "sk-inline-secret".to_string(),
328
- credential_ref: None,
329
- };
330
- assert!(validate_profile(&profile).is_err());
331
- }
332
- }
@@ -1,152 +0,0 @@
1
- use std::env;
2
- use std::io::{self, Read};
3
-
4
- use team_agent_core::{
5
- contains_inline_secret, json_escape, list_tmux_targets, redact_secrets, render_message,
6
- validate_profile, Profile,
7
- };
8
-
9
- fn main() {
10
- let args: Vec<String> = env::args().collect();
11
- let command = args.get(1).map(String::as_str).unwrap_or("");
12
- let result = match command {
13
- "list-targets" => list_targets(),
14
- "render-message" => render_message_cmd(),
15
- "redact" => redact_cmd(),
16
- "validate-profile" => validate_profile_cmd(),
17
- _ => Err(format!(
18
- "unknown command {command:?}; expected list-targets, render-message, redact, validate-profile"
19
- )),
20
- };
21
- match result {
22
- Ok(json) => println!("{json}"),
23
- Err(error) => {
24
- println!(
25
- "{{\"ok\":false,\"error\":\"{}\"}}",
26
- json_escape(error.trim())
27
- );
28
- std::process::exit(1);
29
- }
30
- }
31
- }
32
-
33
- fn read_stdin() -> Result<String, String> {
34
- let mut input = String::new();
35
- io::stdin()
36
- .read_to_string(&mut input)
37
- .map_err(|err| format!("stdin read failed: {err}"))?;
38
- Ok(input)
39
- }
40
-
41
- fn list_targets() -> Result<String, String> {
42
- let targets = list_tmux_targets()?;
43
- let mut items = Vec::new();
44
- for target in targets {
45
- items.push(format!(
46
- "{{\"pane_id\":\"{}\",\"session_name\":\"{}\",\"window_index\":\"{}\",\"window_name\":\"{}\",\"pane_index\":\"{}\",\"pane_tty\":\"{}\",\"pane_current_command\":\"{}\",\"pane_active\":{},\"fingerprint\":\"{}\"}}",
47
- json_escape(&target.pane_id),
48
- json_escape(&target.session_name),
49
- json_escape(&target.window_index),
50
- json_escape(&target.window_name),
51
- json_escape(&target.pane_index),
52
- json_escape(&target.pane_tty),
53
- json_escape(&target.pane_current_command),
54
- target.pane_active,
55
- json_escape(&target.fingerprint())
56
- ));
57
- }
58
- Ok(format!("{{\"ok\":true,\"targets\":[{}]}}", items.join(",")))
59
- }
60
-
61
- fn render_message_cmd() -> Result<String, String> {
62
- let input = read_stdin()?;
63
- let sender = extract_string(&input, "from")
64
- .or_else(|| extract_string(&input, "sender"))
65
- .unwrap_or_else(|| "unknown".to_string());
66
- let task_id = extract_string(&input, "task_id");
67
- let content = extract_string(&input, "content").unwrap_or_default();
68
- let token = extract_string(&input, "message_id").unwrap_or_else(|| "missing".to_string());
69
- let rendered = render_message(&sender, task_id.as_deref(), &content, &token);
70
- Ok(format!(
71
- "{{\"ok\":true,\"text\":\"{}\",\"token\":\"{}\"}}",
72
- json_escape(&rendered),
73
- json_escape(&token)
74
- ))
75
- }
76
-
77
- fn redact_cmd() -> Result<String, String> {
78
- let input = read_stdin()?;
79
- let text = extract_string(&input, "text").unwrap_or(input);
80
- Ok(format!(
81
- "{{\"ok\":true,\"text\":\"{}\"}}",
82
- json_escape(&redact_secrets(&text))
83
- ))
84
- }
85
-
86
- fn validate_profile_cmd() -> Result<String, String> {
87
- let input = read_stdin()?;
88
- let profile = Profile {
89
- provider: extract_string(&input, "provider").unwrap_or_default(),
90
- model: extract_string(&input, "model").unwrap_or_default(),
91
- auth_mode: extract_string(&input, "auth_mode").unwrap_or_default(),
92
- profile: extract_string(&input, "profile").unwrap_or_default(),
93
- credential_ref: extract_string(&input, "credential_ref"),
94
- };
95
- let mut errors = match validate_profile(&profile) {
96
- Ok(()) => Vec::new(),
97
- Err(errors) => errors,
98
- };
99
- if contains_inline_secret(&input) {
100
- errors.push("input contains a probable inline secret".to_string());
101
- }
102
- if errors.is_empty() {
103
- Ok("{\"ok\":true,\"errors\":[]}".to_string())
104
- } else {
105
- let encoded: Vec<String> = errors
106
- .into_iter()
107
- .map(|err| format!("\"{}\"", json_escape(&err)))
108
- .collect();
109
- Ok(format!("{{\"ok\":false,\"errors\":[{}]}}", encoded.join(",")))
110
- }
111
- }
112
-
113
- fn extract_string(input: &str, key: &str) -> Option<String> {
114
- let needle = format!("\"{key}\"");
115
- let key_pos = input.find(&needle)?;
116
- let rest = &input[key_pos + needle.len()..];
117
- let colon = rest.find(':')?;
118
- let value = rest[colon + 1..].trim_start();
119
- if !value.starts_with('"') {
120
- return None;
121
- }
122
- parse_json_string(value)
123
- }
124
-
125
- fn parse_json_string(input: &str) -> Option<String> {
126
- let mut out = String::new();
127
- let mut chars = input.chars();
128
- if chars.next()? != '"' {
129
- return None;
130
- }
131
- let mut escaped = false;
132
- for ch in chars {
133
- if escaped {
134
- match ch {
135
- '"' => out.push('"'),
136
- '\\' => out.push('\\'),
137
- 'n' => out.push('\n'),
138
- 'r' => out.push('\r'),
139
- 't' => out.push('\t'),
140
- other => out.push(other),
141
- }
142
- escaped = false;
143
- continue;
144
- }
145
- match ch {
146
- '\\' => escaped = true,
147
- '"' => return Some(out),
148
- other => out.push(other),
149
- }
150
- }
151
- None
152
- }
package/pyproject.toml DELETED
@@ -1,18 +0,0 @@
1
- [project]
2
- name = "teamspec-agent-mode"
3
- version = "0.1.4"
4
- description = "Spec-first CLI-native team agent runtime for Claude Code, Codex CLI, and Gemini CLI workers."
5
- readme = "README.md"
6
- requires-python = ">=3.10"
7
- dependencies = []
8
-
9
- [project.optional-dependencies]
10
- test = []
11
-
12
- [project.scripts]
13
- team-agent = "team_agent.cli:main"
14
- team_orchestrator = "team_agent.mcp_server:main"
15
- team-agent-coordinator = "team_agent.coordinator:main"
16
-
17
- [tool.team-agent]
18
- run = "PYTHONPATH=src python3 -m team_agent"
@@ -1,88 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import argparse
4
- import glob
5
- import os
6
- import shutil
7
- import subprocess
8
- from pathlib import Path
9
-
10
-
11
- def main() -> None:
12
- parser = argparse.ArgumentParser(description="Install local team-agent wrapper commands")
13
- parser.add_argument("--prefix", default=str(Path.home() / ".local"), help="Install prefix; bin/ is created under it")
14
- parser.add_argument("--python", help="Python executable to embed in wrappers; defaults to TEAM_AGENT_PYTHON, python3, then python")
15
- args = parser.parse_args()
16
- repo = Path(__file__).resolve().parents[1]
17
- python = _resolve_python(args.python)
18
- bin_dir = Path(args.prefix) / "bin"
19
- bin_dir.mkdir(parents=True, exist_ok=True)
20
- _write_wrapper(bin_dir / "team-agent", repo, "team_agent", python)
21
- _write_wrapper(bin_dir / "team_orchestrator", repo, "team_agent.mcp_server", python)
22
- _write_wrapper(bin_dir / "team-agent-coordinator", repo, "team_agent.coordinator", python)
23
- print(f"installed: {bin_dir / 'team-agent'}")
24
- print(f"installed: {bin_dir / 'team_orchestrator'}")
25
- print(f"installed: {bin_dir / 'team-agent-coordinator'}")
26
- print(f"python: {python}")
27
- print(f"ensure PATH contains: {bin_dir}")
28
-
29
-
30
- def _resolve_python(explicit: str | None) -> str:
31
- candidates = _python_candidates(explicit)
32
- for candidate in candidates:
33
- if not candidate:
34
- continue
35
- resolved = shutil.which(candidate) if os.path.basename(candidate) == candidate else candidate
36
- if not resolved:
37
- continue
38
- proc = subprocess.run(
39
- [
40
- resolved,
41
- "-c",
42
- "import sys; raise SystemExit(0 if sys.version_info >= (3, 10) else 1)",
43
- ],
44
- text=True,
45
- capture_output=True,
46
- check=False,
47
- )
48
- if proc.returncode == 0:
49
- return resolved
50
- raise SystemExit("No usable Python >= 3.10 found. Set TEAM_AGENT_PYTHON or pass --python.")
51
-
52
-
53
- def _python_candidates(explicit: str | None) -> list[str]:
54
- candidates = [
55
- explicit,
56
- os.environ.get("TEAM_AGENT_PYTHON"),
57
- "python3",
58
- "python",
59
- "/opt/homebrew/bin/python3",
60
- "/usr/local/bin/python3",
61
- "/usr/bin/python3",
62
- "/opt/homebrew/opt/python@3/bin/python3",
63
- "/usr/local/opt/python@3/bin/python3",
64
- ]
65
- candidates.extend(glob.glob("/opt/homebrew/opt/python@*/bin/python3*"))
66
- candidates.extend(glob.glob("/usr/local/opt/python@*/bin/python3*"))
67
- seen: set[str] = set()
68
- result: list[str] = []
69
- for item in candidates:
70
- if not item or item in seen:
71
- continue
72
- seen.add(item)
73
- result.append(item)
74
- return result
75
-
76
-
77
- def _write_wrapper(path: Path, repo: Path, module: str, python: str) -> None:
78
- path.write_text(
79
- "#!/usr/bin/env sh\n"
80
- f'PYTHON_BIN="${{TEAM_AGENT_PYTHON:-{python}}}"\n'
81
- f'PYTHONPATH="{repo / "src"}" exec "$PYTHON_BIN" -m {module} "$@"\n',
82
- encoding="utf-8",
83
- )
84
- path.chmod(path.stat().st_mode | 0o755)
85
-
86
-
87
- if __name__ == "__main__":
88
- main()
@@ -1,83 +0,0 @@
1
- #!/usr/bin/env python3
2
- from __future__ import annotations
3
-
4
- import argparse
5
- import os
6
- import subprocess
7
- import sys
8
- from pathlib import Path
9
-
10
-
11
- REGRESSION_TESTS = [
12
- "tests.run_tests.RuntimeTests.test_send_default_timeout_reports_submitted_unverified",
13
- "tests.run_tests.RuntimeTests.test_message_fragment_matching_ignores_generic_header",
14
- "tests.run_tests.RuntimeTests.test_wait_for_message_ready_does_not_accept_old_header",
15
- "tests.run_tests.RuntimeTests.test_wait_for_message_ready_accepts_only_new_pasted_prompt",
16
- "tests.run_tests.RuntimeTests.test_worker_delivery_retries_paste_until_message_ready",
17
- "tests.run_tests.RuntimeTests.test_worker_pasted_content_prompt_retries_enter_until_submitted",
18
- "tests.run_tests.RuntimeTests.test_worker_pasted_content_prompt_reports_unverified_when_enter_does_not_submit",
19
- "tests.run_tests.RuntimeTests.test_delivery_claim_prevents_duplicate_worker_injection",
20
- "tests.run_tests.RuntimeTests.test_approvals_returns_structured_prompt_without_terminal_page",
21
- "tests.run_tests.RuntimeTests.test_coordinator_auto_approves_internal_mcp_prompt_with_retry_verification",
22
- "tests.run_tests.RuntimeTests.test_coordinator_auto_approves_claude_internal_mcp_prompt",
23
- "tests.run_tests.RuntimeTests.test_stale_approval_prompt_in_scrollback_is_not_current_approval",
24
- "tests.run_tests.RuntimeTests.test_ghostty_display_session_is_linked_and_window_selected",
25
- "tests.run_tests.RuntimeTests.test_shutdown_closes_ghostty_display_session_before_base_session_without_pid",
26
- "tests.run_tests.RuntimeTests.test_restart_resumes_known_sessions_and_fresh_spawns_missing_sessions",
27
- "tests.run_tests.RuntimeTests.test_restart_first_resume_exit_fallback_recreates_session_and_opens_display",
28
- "tests.run_tests.RuntimeTests.test_start_agent_repairs_missing_worker_window_without_restart",
29
- "tests.run_tests.RuntimeTests.test_start_agent_falls_back_to_fresh_when_resume_window_exits",
30
- "tests.run_tests.RuntimeTests.test_broadcast_sends_only_to_current_team_and_excludes_sender",
31
- "tests.run_tests.RuntimeTests.test_status_and_collect_expose_uncollected_report_result",
32
- "tests.run_tests.RuntimeTests.test_collect_accepts_message_scoped_report_result",
33
- "tests.run_tests.RuntimeTests.test_report_result_queues_leader_notification_without_blocking_mcp",
34
- "tests.run_tests.RuntimeTests.test_mcp_send_message_accepts_thin_args_and_returns_compact_result",
35
- "tests.run_tests.RuntimeTests.test_mcp_send_message_accepts_broadcast_target",
36
- "tests.run_tests.RuntimeTests.test_mcp_send_message_without_env_infers_worker_before_leader_send",
37
- "tests.run_tests.RuntimeTests.test_mcp_report_result_without_env_infers_task_and_agent",
38
- "tests.run_tests.RuntimeTests.test_mcp_report_result_normalizes_common_loose_shapes",
39
- "tests.run_tests.RuntimeTests.test_compile_system_prompt_prepends_teammate_runtime_contract",
40
- "tests.run_tests.RuntimeTests.test_codex_default_command_avoids_dangerous_bypass",
41
- "tests.run_tests.RuntimeTests.test_launch_inherits_leader_dangerous_permissions_in_dry_run",
42
- "tests.run_tests.RuntimeTests.test_launch_passes_inherited_dangerous_permissions_to_worker_runtime",
43
- "tests.run_tests.RuntimeTests.test_restart_passes_inherited_dangerous_permissions_to_resume_and_fresh_workers",
44
- "tests.run_tests.RuntimeTests.test_quick_start_refuses_to_overwrite_existing_context_without_fresh",
45
- "tests.run_tests.RuntimeTests.test_quick_start_team_id_stores_loose_docs_outside_current",
46
- "tests.run_tests.RuntimeTests.test_start_writes_compiled_spec_inside_selected_team_dir",
47
- "tests.run_tests.RuntimeTests.test_preflight_uses_selected_team_profile_dir_not_current",
48
- "tests.run_tests.RuntimeTests.test_restart_requires_team_selector_when_multiple_snapshots_exist",
49
- "tests.run_tests.RuntimeTests.test_leader_start_plan_creates_tmux_session_outside_tmux_and_passes_args",
50
- "tests.run_tests.RuntimeTests.test_leader_start_plan_inside_tmux_execs_provider_in_current_pane",
51
- "tests.run_tests.RuntimeTests.test_launch_requires_current_tmux_leader_for_real_workers",
52
- "tests.run_tests.RuntimeTests.test_resolve_leader_scans_workspace_when_tool_shell_has_wrong_tmux_client",
53
- "tests.run_tests.RuntimeTests.test_resolve_leader_reports_ambiguous_workspace_panes",
54
- "tests.run_tests.CliContractTests.test_leader_commands_pass_provider_flags_without_argparse_consuming_them",
55
- "tests.run_tests.CliContractTests.test_npx_installer_installs_runtime_wrappers_and_skills",
56
- "tests.run_tests.CliContractTests.test_skill_blackbox_lint",
57
- ]
58
-
59
-
60
- def main() -> int:
61
- parser = argparse.ArgumentParser(description="Run the fixed Team Agent regression asset.")
62
- parser.add_argument("--iterations", type=int, default=1, help="repeat the regression batch N times")
63
- parser.add_argument("--list", action="store_true", help="print the selected unittest ids and exit")
64
- args = parser.parse_args()
65
- if args.iterations < 1:
66
- parser.error("--iterations must be >= 1")
67
- if args.list:
68
- print("\n".join(REGRESSION_TESTS))
69
- return 0
70
-
71
- repo = Path(__file__).resolve().parents[1]
72
- env = os.environ.copy()
73
- env["PYTHONPATH"] = str(repo / "src") + os.pathsep + env.get("PYTHONPATH", "")
74
- for index in range(1, args.iterations + 1):
75
- print(f"[team-agent-regression] iteration {index}/{args.iterations}", flush=True)
76
- proc = subprocess.run([sys.executable, "-m", "unittest", *REGRESSION_TESTS], cwd=repo, env=env, check=False)
77
- if proc.returncode != 0:
78
- return proc.returncode
79
- return 0
80
-
81
-
82
- if __name__ == "__main__":
83
- raise SystemExit(main())
@@ -1,3 +0,0 @@
1
- """TeamSpec Agent Mode runtime."""
2
-
3
- __version__ = "0.1.4"
@@ -1,5 +0,0 @@
1
- from team_agent.cli import main
2
-
3
-
4
- if __name__ == "__main__":
5
- main()