@team-agent/installer 0.5.73 → 0.5.74

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 (30) hide show
  1. package/Cargo.lock +1 -1
  2. package/Cargo.toml +1 -1
  3. package/crates/team-agent/src/cli/adapters.rs +19 -13
  4. package/crates/team-agent/src/cli/emit.rs +6 -3
  5. package/crates/team-agent/src/cli/mod.rs +151 -0
  6. package/crates/team-agent/src/cli/tests/leader_watch.rs +28 -0
  7. package/crates/team-agent/src/cli/tests/run_delegation.rs +3 -0
  8. package/crates/team-agent/src/cli/types.rs +6 -0
  9. package/crates/team-agent/src/compiler.rs +14 -1
  10. package/crates/team-agent/src/leader/lease.rs +106 -21
  11. package/crates/team-agent/src/leader/registry.rs +0 -89
  12. package/crates/team-agent/src/lifecycle/launch/quick_start.rs +457 -73
  13. package/crates/team-agent/src/lifecycle/launch/quick_start_transport.rs +16 -6
  14. package/crates/team-agent/src/lifecycle/launch/state_projection.rs +5 -3
  15. package/crates/team-agent/src/lifecycle/restart/common.rs +0 -11
  16. package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +60 -0
  17. package/crates/team-agent/src/lifecycle/tests/pi_compiler_red.rs +31 -0
  18. package/crates/team-agent/src/lifecycle/tests/pi_dual_entry_red.rs +25 -23
  19. package/crates/team-agent/src/messaging/delivery.rs +26 -8
  20. package/crates/team-agent/src/messaging/tests/runtime.rs +234 -0
  21. package/crates/team-agent/src/model/spec.rs +81 -7
  22. package/crates/team-agent/src/provider/adapters/pi.rs +14 -0
  23. package/crates/team-agent/src/state/persist.rs +272 -3
  24. package/crates/team-agent/src/state/repository.rs +9 -2
  25. package/crates/team-agent/src/tmux_backend/tests.rs +64 -0
  26. package/crates/team-agent/src/tmux_backend.rs +57 -0
  27. package/package.json +4 -4
  28. package/skills/team-agent/SKILL.md +3 -0
  29. package/skills/team-agent/command-coverage.json +21 -0
  30. package/skills/team-agent/references/team-agent-operator.md +9 -2
@@ -243,12 +243,6 @@ pub fn register_binding_from_state_best_effort(
243
243
  );
244
244
  let event_log = crate::event_log::EventLog::new(workspace);
245
245
  let write_result = write_entry_best_effort(&entry);
246
- // Fresh quick-start is acquisition-only: it must never displace another
247
- // same-pane row. Its caller performs a validated-LIVE check before this
248
- // write; manual/restart ownership paths keep existing behavior.
249
- if write_result.is_some() && source != "quick-start" {
250
- let _ = mark_displaced_same_pane_entries_unbound(&entry);
251
- }
252
246
  let status = if let Some(path) = &write_result {
253
247
  let _ = event_log.write(
254
248
  EVENT_REGISTERED,
@@ -281,68 +275,6 @@ pub fn register_binding_from_state_best_effort(
281
275
  })
282
276
  }
283
277
 
284
- /// Stored registry status after another workspace claimed the same pane.
285
- pub const REGISTRY_STATUS_UNBOUND: &str = "unbound";
286
-
287
- /// When workspace B claims a pane, every other attached registry row that
288
- /// still names that pane is no longer deliverable. Mark those rows unbound.
289
- /// Does not change pane-side authorization storage.
290
- pub fn mark_displaced_same_pane_entries_unbound(winner: &LeaderRegistryEntry) -> Vec<PathBuf> {
291
- let Some(winner_pane) = winner
292
- .channel
293
- .get("pane_id")
294
- .and_then(Value::as_str)
295
- .filter(|pane| !pane.is_empty())
296
- else {
297
- return Vec::new();
298
- };
299
- let winner_socket = winner
300
- .channel
301
- .get("tmux_socket")
302
- .and_then(Value::as_str)
303
- .filter(|socket| !socket.is_empty());
304
- let mut displaced = Vec::new();
305
- for (path, mut entry) in read_all_entries() {
306
- if entry.workspace_hash == winner.workspace_hash && entry.team_key == winner.team_key {
307
- continue;
308
- }
309
- if entry.status != "attached" {
310
- continue;
311
- }
312
- let Some(pane) = entry
313
- .channel
314
- .get("pane_id")
315
- .and_then(Value::as_str)
316
- .filter(|pane| !pane.is_empty())
317
- else {
318
- continue;
319
- };
320
- if pane != winner_pane {
321
- continue;
322
- }
323
- let Some(socket) = entry
324
- .channel
325
- .get("tmux_socket")
326
- .and_then(Value::as_str)
327
- .filter(|socket| !socket.is_empty())
328
- else {
329
- continue;
330
- };
331
- let Some(winner_socket) = winner_socket else {
332
- continue;
333
- };
334
- if socket != winner_socket {
335
- continue;
336
- }
337
- entry.status = REGISTRY_STATUS_UNBOUND.to_string();
338
- entry.updated_at = chrono::Utc::now().to_rfc3339();
339
- if write_entry_best_effort(&entry).is_some() {
340
- displaced.push(path);
341
- }
342
- }
343
- displaced
344
- }
345
-
346
278
  fn entry_filename(entry: &LeaderRegistryEntry) -> String {
347
279
  format!("{}__{}.json", entry.workspace_hash, entry.team_key)
348
280
  }
@@ -546,27 +478,6 @@ pub fn list_validated_with_gc() -> Vec<(LeaderRegistryEntry, &'static str, Optio
546
478
  out
547
479
  }
548
480
 
549
- /// Refuse a fresh quick-start binding when the caller pane already backs a
550
- /// canonically LIVE receiver for another workspace/team. This is read-only:
551
- /// quick-start never displaces or takes over an existing binding.
552
- #[must_use]
553
- pub(crate) fn live_same_pane_binding_elsewhere(
554
- pane_id: &str,
555
- workspace: &Path,
556
- team_key: &str,
557
- ) -> bool {
558
- let workspace = std::fs::canonicalize(workspace).unwrap_or_else(|_| workspace.to_path_buf());
559
- list_validated_no_gc().into_iter().any(|(entry, status, _)| {
560
- status == "LIVE"
561
- && entry
562
- .channel
563
- .get("pane_id")
564
- .and_then(Value::as_str)
565
- == Some(pane_id)
566
- && (entry.workspace != workspace || entry.team_key != team_key)
567
- })
568
- }
569
-
570
481
  /// Same as `list_validated_with_gc` but preserves all entries. `send
571
482
  /// --to-leader` needs to see stale entries so it can refuse with
572
483
  /// `registry_stale` (and never silently fall through to