@team-agent/installer 0.5.2 → 0.5.4
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.
- package/Cargo.lock +3 -1
- package/Cargo.toml +1 -1
- package/crates/team-agent/Cargo.toml +20 -0
- package/crates/team-agent/src/cli/diagnose.rs +191 -31
- package/crates/team-agent/src/cli/emit.rs +5 -0
- package/crates/team-agent/src/cli/mod.rs +213 -89
- package/crates/team-agent/src/cli/tests/named_address.rs +4 -0
- package/crates/team-agent/src/codex_app_server.rs +62 -1
- package/crates/team-agent/src/conpty/backend.rs +120 -8
- package/crates/team-agent/src/coordinator/backoff.rs +88 -2
- package/crates/team-agent/src/coordinator/conpty_shim.rs +730 -0
- package/crates/team-agent/src/coordinator/health.rs +97 -11
- package/crates/team-agent/src/coordinator/mod.rs +8 -0
- package/crates/team-agent/src/coordinator/tests/daemon.rs +2 -1
- package/crates/team-agent/src/coordinator/tests/tick_core.rs +6 -0
- package/crates/team-agent/src/coordinator/tick.rs +13 -0
- package/crates/team-agent/src/diagnose/orphans.rs +18 -7
- package/crates/team-agent/src/leader/provider_attribution.rs +19 -34
- package/crates/team-agent/src/leader/tests/lease_api.rs +7 -0
- package/crates/team-agent/src/lib.rs +14 -1
- package/crates/team-agent/src/lifecycle/launch.rs +89 -92
- package/crates/team-agent/src/lifecycle/lock.rs +40 -33
- package/crates/team-agent/src/lifecycle/restart/agent.rs +25 -19
- package/crates/team-agent/src/lifecycle/restart/common.rs +53 -2
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +108 -6
- package/crates/team-agent/src/lifecycle/restart/selection.rs +47 -18
- package/crates/team-agent/src/lifecycle/restart.rs +16 -6
- package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +7 -0
- package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +287 -53
- package/crates/team-agent/src/lifecycle/tests/restart.rs +144 -5
- package/crates/team-agent/src/lifecycle/types.rs +1 -0
- package/crates/team-agent/src/mcp_server/wire.rs +6 -7
- package/crates/team-agent/src/messaging/tests/runtime.rs +5 -0
- package/crates/team-agent/src/packaging/tests.rs +41 -6
- package/crates/team-agent/src/packaging/types.rs +31 -3
- package/crates/team-agent/src/platform/argv.rs +324 -0
- package/crates/team-agent/src/platform/errors.rs +95 -0
- package/crates/team-agent/src/platform/file_lock.rs +418 -0
- package/crates/team-agent/src/platform/mod.rs +66 -0
- package/crates/team-agent/src/platform/process.rs +555 -0
- package/crates/team-agent/src/provider/adapter.rs +103 -41
- package/crates/team-agent/src/provider/session/capture.rs +328 -66
- package/crates/team-agent/src/provider/session/resume.rs +30 -28
- package/crates/team-agent/src/provider/session_scan/common.rs +117 -1
- package/crates/team-agent/src/provider/session_scan/copilot.rs +1 -0
- package/crates/team-agent/src/provider/session_scan.rs +1 -0
- package/crates/team-agent/src/state/persist.rs +222 -25
- package/crates/team-agent/src/state/projection.rs +59 -4
- package/crates/team-agent/src/tmux_backend.rs +63 -13
- package/crates/team-agent/src/transport_factory.rs +124 -5
- package/package.json +4 -4
|
@@ -17,6 +17,7 @@ use super::StateError;
|
|
|
17
17
|
use crate::state::persist::{
|
|
18
18
|
load_runtime_state, save_runtime_state_with_deleted_agents,
|
|
19
19
|
save_runtime_state_with_lifecycle_topology_authority,
|
|
20
|
+
save_runtime_state_with_lifecycle_topology_authority_and_capture_backfill_skip,
|
|
20
21
|
save_runtime_state_with_team_tombstone_lifecycle_topology_authority,
|
|
21
22
|
save_runtime_state_with_team_tombstoned_agents,
|
|
22
23
|
};
|
|
@@ -595,7 +596,7 @@ pub(crate) fn save_team_scoped_state_with_tombstone_lifecycle_topology_authority
|
|
|
595
596
|
team_state: &Value,
|
|
596
597
|
agent_ids: &[&str],
|
|
597
598
|
) -> Result<(), StateError> {
|
|
598
|
-
save_team_scoped_state_with_merge_options(workspace, team_state, &[], agent_ids, agent_ids)
|
|
599
|
+
save_team_scoped_state_with_merge_options(workspace, team_state, &[], agent_ids, &[], agent_ids)
|
|
599
600
|
}
|
|
600
601
|
|
|
601
602
|
pub(crate) fn save_team_scoped_state_with_lifecycle_topology_authority(
|
|
@@ -603,7 +604,23 @@ pub(crate) fn save_team_scoped_state_with_lifecycle_topology_authority(
|
|
|
603
604
|
team_state: &Value,
|
|
604
605
|
agent_ids: &[&str],
|
|
605
606
|
) -> Result<(), StateError> {
|
|
606
|
-
save_team_scoped_state_with_merge_options(workspace, team_state, &[], &[], agent_ids)
|
|
607
|
+
save_team_scoped_state_with_merge_options(workspace, team_state, &[], &[], &[], agent_ids)
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
pub(crate) fn save_team_scoped_state_with_lifecycle_topology_authority_and_capture_backfill_skip(
|
|
611
|
+
workspace: &Path,
|
|
612
|
+
team_state: &Value,
|
|
613
|
+
skip_capture_backfill_agent_ids: &[&str],
|
|
614
|
+
topology_agent_ids: &[&str],
|
|
615
|
+
) -> Result<(), StateError> {
|
|
616
|
+
save_team_scoped_state_with_merge_options(
|
|
617
|
+
workspace,
|
|
618
|
+
team_state,
|
|
619
|
+
&[],
|
|
620
|
+
&[],
|
|
621
|
+
skip_capture_backfill_agent_ids,
|
|
622
|
+
topology_agent_ids,
|
|
623
|
+
)
|
|
607
624
|
}
|
|
608
625
|
|
|
609
626
|
fn save_team_scoped_state_with_merge_exceptions(
|
|
@@ -618,6 +635,7 @@ fn save_team_scoped_state_with_merge_exceptions(
|
|
|
618
635
|
deleted_agent_ids,
|
|
619
636
|
tombstoned_agent_ids,
|
|
620
637
|
&[],
|
|
638
|
+
&[],
|
|
621
639
|
)
|
|
622
640
|
}
|
|
623
641
|
|
|
@@ -626,6 +644,7 @@ fn save_team_scoped_state_with_merge_options(
|
|
|
626
644
|
team_state: &Value,
|
|
627
645
|
deleted_agent_ids: &[&str],
|
|
628
646
|
tombstoned_agent_ids: &[&str],
|
|
647
|
+
skip_capture_backfill_agent_ids: &[&str],
|
|
629
648
|
topology_agent_ids: &[&str],
|
|
630
649
|
) -> Result<(), StateError> {
|
|
631
650
|
let target_key = team_state_key(team_state);
|
|
@@ -669,12 +688,30 @@ fn save_team_scoped_state_with_merge_options(
|
|
|
669
688
|
topology_agent_ids,
|
|
670
689
|
);
|
|
671
690
|
}
|
|
691
|
+
if !skip_capture_backfill_agent_ids.is_empty() {
|
|
692
|
+
return save_runtime_state_with_lifecycle_topology_authority_and_capture_backfill_skip(
|
|
693
|
+
workspace,
|
|
694
|
+
&merged,
|
|
695
|
+
&target_key,
|
|
696
|
+
skip_capture_backfill_agent_ids,
|
|
697
|
+
topology_agent_ids,
|
|
698
|
+
);
|
|
699
|
+
}
|
|
672
700
|
return save_runtime_state_with_lifecycle_topology_authority(
|
|
673
701
|
workspace,
|
|
674
702
|
&merged,
|
|
675
703
|
topology_agent_ids,
|
|
676
704
|
);
|
|
677
705
|
}
|
|
706
|
+
if !skip_capture_backfill_agent_ids.is_empty() {
|
|
707
|
+
return save_runtime_state_with_lifecycle_topology_authority_and_capture_backfill_skip(
|
|
708
|
+
workspace,
|
|
709
|
+
&merged,
|
|
710
|
+
&target_key,
|
|
711
|
+
skip_capture_backfill_agent_ids,
|
|
712
|
+
&[],
|
|
713
|
+
);
|
|
714
|
+
}
|
|
678
715
|
if tombstoned_agent_ids.is_empty() {
|
|
679
716
|
return save_runtime_state_with_deleted_agents(workspace, &merged, deleted_agent_ids);
|
|
680
717
|
}
|
|
@@ -709,10 +746,28 @@ fn save_team_scoped_state_with_merge_options(
|
|
|
709
746
|
}
|
|
710
747
|
if tombstoned_agent_ids.is_empty() {
|
|
711
748
|
if !topology_agent_ids.is_empty() {
|
|
712
|
-
|
|
749
|
+
if !skip_capture_backfill_agent_ids.is_empty() {
|
|
750
|
+
save_runtime_state_with_lifecycle_topology_authority_and_capture_backfill_skip(
|
|
751
|
+
workspace,
|
|
752
|
+
&Value::Object(merged),
|
|
753
|
+
&target_key,
|
|
754
|
+
skip_capture_backfill_agent_ids,
|
|
755
|
+
topology_agent_ids,
|
|
756
|
+
)
|
|
757
|
+
} else {
|
|
758
|
+
save_runtime_state_with_lifecycle_topology_authority(
|
|
759
|
+
workspace,
|
|
760
|
+
&Value::Object(merged),
|
|
761
|
+
topology_agent_ids,
|
|
762
|
+
)
|
|
763
|
+
}
|
|
764
|
+
} else if !skip_capture_backfill_agent_ids.is_empty() {
|
|
765
|
+
save_runtime_state_with_lifecycle_topology_authority_and_capture_backfill_skip(
|
|
713
766
|
workspace,
|
|
714
767
|
&Value::Object(merged),
|
|
715
|
-
|
|
768
|
+
&target_key,
|
|
769
|
+
skip_capture_backfill_agent_ids,
|
|
770
|
+
&[],
|
|
716
771
|
)
|
|
717
772
|
} else {
|
|
718
773
|
save_runtime_state_with_deleted_agents(
|
|
@@ -18,6 +18,13 @@
|
|
|
18
18
|
use std::collections::BTreeMap;
|
|
19
19
|
use std::hash::{Hash, Hasher};
|
|
20
20
|
use std::io::{Read, Write};
|
|
21
|
+
// 0.5.x Windows portability Batch 1: gate the sole Unix API surface
|
|
22
|
+
// in this concrete tmux backend (FileTypeExt::is_socket + libc::geteuid
|
|
23
|
+
// tmux-socket-root derivation). The rest of the file is Command::new
|
|
24
|
+
// "tmux" shellouts that compile on Windows but return runtime errors
|
|
25
|
+
// honestly (tmux binary absent → typed subprocess error).
|
|
26
|
+
// Truth source: `.team/artifacts/0.5.x-windows-portability-survey-design.md` §Batch 1.
|
|
27
|
+
#[cfg(unix)]
|
|
21
28
|
use std::os::unix::fs::FileTypeExt;
|
|
22
29
|
use std::path::{Path, PathBuf};
|
|
23
30
|
use std::process::Stdio;
|
|
@@ -489,10 +496,24 @@ pub(crate) fn socket_path_for_name(socket_name: &str) -> Option<PathBuf> {
|
|
|
489
496
|
if let Some(existing) = existing_socket_path_for_name(socket_name) {
|
|
490
497
|
return Some(existing);
|
|
491
498
|
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
499
|
+
// Batch 1: tmux uses `/tmp/tmux-<uid>/` on Unix; on Windows this
|
|
500
|
+
// helper is dead code (Command::new "tmux" fails at spawn time
|
|
501
|
+
// before this path is dereferenced). N38 typed unsupported honored
|
|
502
|
+
// at the shellout boundary.
|
|
503
|
+
#[cfg(unix)]
|
|
504
|
+
{
|
|
505
|
+
let uid = unsafe { libc::geteuid() };
|
|
506
|
+
let default_root = PathBuf::from(format!("/tmp/tmux-{uid}"));
|
|
507
|
+
let default_root = default_root.canonicalize().unwrap_or(default_root);
|
|
508
|
+
Some(default_root.join(socket_name))
|
|
509
|
+
}
|
|
510
|
+
#[cfg(not(unix))]
|
|
511
|
+
{
|
|
512
|
+
// Windows: tmux socket-root derivation is meaningless. Return
|
|
513
|
+
// None so the caller sees the honest "no such socket" branch.
|
|
514
|
+
let _ = socket_name;
|
|
515
|
+
None
|
|
516
|
+
}
|
|
496
517
|
}
|
|
497
518
|
|
|
498
519
|
fn existing_socket_path_for_name(socket_name: &str) -> Option<PathBuf> {
|
|
@@ -582,14 +603,25 @@ pub(crate) fn attach_commands_for_windows<'a>(
|
|
|
582
603
|
}
|
|
583
604
|
|
|
584
605
|
pub(crate) fn tmux_socket_roots() -> Vec<PathBuf> {
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
606
|
+
// Batch 1: `/tmp/tmux-<uid>` root enumeration is Unix-only tmux
|
|
607
|
+
// convention. On Windows return empty so the caller loops zero
|
|
608
|
+
// times (honest "no tmux socket roots" — tmux is not deployed on
|
|
609
|
+
// native Windows without WSL, and WSL is out of scope).
|
|
610
|
+
#[cfg(unix)]
|
|
611
|
+
{
|
|
612
|
+
let uid = unsafe { libc::geteuid() };
|
|
613
|
+
let mut roots = vec![PathBuf::from(format!("/tmp/tmux-{uid}"))];
|
|
614
|
+
if let Some(tmpdir) = std::env::var_os("TMPDIR") {
|
|
615
|
+
roots.push(PathBuf::from(tmpdir).join(format!("tmux-{uid}")));
|
|
616
|
+
}
|
|
617
|
+
roots.sort();
|
|
618
|
+
roots.dedup();
|
|
619
|
+
roots
|
|
620
|
+
}
|
|
621
|
+
#[cfg(not(unix))]
|
|
622
|
+
{
|
|
623
|
+
Vec::new()
|
|
589
624
|
}
|
|
590
|
-
roots.sort();
|
|
591
|
-
roots.dedup();
|
|
592
|
-
roots
|
|
593
625
|
}
|
|
594
626
|
|
|
595
627
|
pub(crate) fn tmux_socket_endpoints() -> Vec<String> {
|
|
@@ -602,7 +634,20 @@ pub(crate) fn tmux_socket_endpoints() -> Vec<String> {
|
|
|
602
634
|
let Ok(file_type) = entry.file_type() else {
|
|
603
635
|
continue;
|
|
604
636
|
};
|
|
605
|
-
|
|
637
|
+
// Batch 1: `FileTypeExt::is_socket` is Unix-only. Dead code
|
|
638
|
+
// on Windows because `tmux_socket_roots()` returns empty
|
|
639
|
+
// there (no /tmp/tmux-<uid> convention). We still cfg the
|
|
640
|
+
// method call so `cargo check --target x86_64-pc-windows-msvc`
|
|
641
|
+
// sees no `std::os::unix::fs::FileTypeExt` reference.
|
|
642
|
+
#[cfg(unix)]
|
|
643
|
+
{
|
|
644
|
+
if !file_type.is_socket() {
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
#[cfg(not(unix))]
|
|
649
|
+
{
|
|
650
|
+
let _ = file_type;
|
|
606
651
|
continue;
|
|
607
652
|
}
|
|
608
653
|
let path = entry.path();
|
|
@@ -2249,5 +2294,10 @@ fn non_empty(raw: &str) -> Option<&str> {
|
|
|
2249
2294
|
}
|
|
2250
2295
|
}
|
|
2251
2296
|
|
|
2252
|
-
|
|
2297
|
+
// 0.5.x Windows portability Batch 5: the `tmux_backend/tests.rs`
|
|
2298
|
+
// module uses `std::os::unix::net::UnixListener` for its mock
|
|
2299
|
+
// runner + verifies Unix-specific socket-root derivation. Since the
|
|
2300
|
+
// tmux backend itself only functions on Unix (design § Route B —
|
|
2301
|
+
// tmux is a Unix concept), the test module stays Unix-only.
|
|
2302
|
+
#[cfg(all(test, unix))]
|
|
2253
2303
|
mod tests;
|
|
@@ -351,12 +351,61 @@ fn build_conpty(
|
|
|
351
351
|
// the same source of truth the tmux short-socket derivation uses,
|
|
352
352
|
// so the shim + tmux socket see identical workspace identity.
|
|
353
353
|
let workspace_hash = crate::tmux_backend::workspace_short_hash_pub(input.workspace);
|
|
354
|
-
//
|
|
355
|
-
//
|
|
356
|
-
//
|
|
357
|
-
|
|
358
|
-
let backend = ConPtyBackend::new(workspace_hash, team_key);
|
|
354
|
+
// `mut` because the Windows branch below may reassign after a
|
|
355
|
+
// successful pipe connect + `with_pipe_client` handshake. On
|
|
356
|
+
// Unix the binding stays as-constructed.
|
|
357
|
+
#[cfg_attr(not(windows), allow(unused_mut))]
|
|
358
|
+
let mut backend = ConPtyBackend::new(workspace_hash.clone(), team_key);
|
|
359
359
|
let mut notices = Vec::new();
|
|
360
|
+
// 0.5.x CR C-5 fix (leader msg_a89b5a03bbf0): factory returns to
|
|
361
|
+
// pure assembly. `build_conpty` used to call
|
|
362
|
+
// `NamedPipeClient::connect(_, 2000)` inline when
|
|
363
|
+
// `conpty_pipe_ready(input)` said state hinted the shim was up.
|
|
364
|
+
// That was a real CR C-5 violation — every `status`/`diagnose`
|
|
365
|
+
// resolve on Windows could block 2 seconds probing a
|
|
366
|
+
// non-existent pipe.
|
|
367
|
+
//
|
|
368
|
+
// Post-fix: the factory only STASHES the pipe hint via
|
|
369
|
+
// `ConPtyBackend::with_pipe_hint(pipe_name)`. The backend's
|
|
370
|
+
// `ensure_pipe_client` performs the connect + Hello lazily on
|
|
371
|
+
// the first Op that needs the pipe. Callers that don't need
|
|
372
|
+
// the pipe (status, resolve-only paths) never pay the connect
|
|
373
|
+
// cost.
|
|
374
|
+
//
|
|
375
|
+
// The Batch 6 direct-handoff path (`lifecycle/launch.rs`
|
|
376
|
+
// quick-start conpty) stays byte-compatible: it hands its
|
|
377
|
+
// Hello-connected client to `with_pipe_client` AFTER
|
|
378
|
+
// `resolve_transport` returns, and the client just becomes the
|
|
379
|
+
// backend's initial cache value so lazy connect is a no-op on
|
|
380
|
+
// the first Op.
|
|
381
|
+
#[cfg(windows)]
|
|
382
|
+
{
|
|
383
|
+
if let Some(state) = input.state {
|
|
384
|
+
if let Some(pipe_name) = state
|
|
385
|
+
.pointer("/transport/shim/pipe_name")
|
|
386
|
+
.and_then(|v| v.as_str())
|
|
387
|
+
{
|
|
388
|
+
backend = backend.with_pipe_hint(pipe_name);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
// Non-state env override still respected (test/diagnostic
|
|
392
|
+
// path). When set, derive the hint from workspace_hash +
|
|
393
|
+
// team_key so `dispatch` can lazily connect the first Op.
|
|
394
|
+
if std::env::var("TEAM_AGENT_FORCE_CONPTY_PIPE_CONNECT")
|
|
395
|
+
.map(|v| v == "1")
|
|
396
|
+
.unwrap_or(false)
|
|
397
|
+
&& backend.pipe_hint_ref().is_none()
|
|
398
|
+
{
|
|
399
|
+
let pipe_name = conpty_transport::pipe_name_for(&workspace_hash, team_key);
|
|
400
|
+
backend = backend.with_pipe_hint(pipe_name);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// Suppress unused warnings on Unix where the cfg(windows) block
|
|
404
|
+
// above compiles to nothing.
|
|
405
|
+
#[cfg(not(windows))]
|
|
406
|
+
{
|
|
407
|
+
let _ = &workspace_hash;
|
|
408
|
+
}
|
|
360
409
|
// C-3: if state has BOTH `transport.kind=conpty` and a legacy
|
|
361
410
|
// `tmux_endpoint`, tell the caller so they emit
|
|
362
411
|
// `transport.legacy_tmux_endpoint_ignored`. Same shape for the
|
|
@@ -608,6 +657,76 @@ mod tests {
|
|
|
608
657
|
assert!(resolved.notices.is_empty());
|
|
609
658
|
}
|
|
610
659
|
|
|
660
|
+
// 0.5.x Windows portability Batch 5: pipe_ready gate — without a
|
|
661
|
+
// shim.pipe_ready hint (or the force-env override) the factory
|
|
662
|
+
// must NOT attempt a connect. Cross-platform test — the
|
|
663
|
+
// `conpty_pipe_ready` gate is only referenced inside cfg(windows)
|
|
664
|
+
// but the observable behavior (no notice, no wired client) is
|
|
665
|
+
// identical on Unix.
|
|
666
|
+
#[test]
|
|
667
|
+
fn conpty_without_pipe_ready_hint_emits_no_pipe_client_notice() {
|
|
668
|
+
let workspace = ws();
|
|
669
|
+
let state = serde_json::json!({ "transport": { "kind": "conpty" } });
|
|
670
|
+
let input = TransportFactoryInput::new(&workspace, TransportPurpose::LifecycleWorker)
|
|
671
|
+
.with_team_key(Some("team-a"))
|
|
672
|
+
.with_state(Some(&state));
|
|
673
|
+
let resolved = resolve_transport(input).expect("must succeed");
|
|
674
|
+
assert_eq!(resolved.kind, BackendKind::ConPty);
|
|
675
|
+
// No pipe-client notice must appear regardless of platform:
|
|
676
|
+
// on Unix the block is cfg'd out; on Windows the gate is
|
|
677
|
+
// closed because no `transport.shim.pipe_ready = true` in
|
|
678
|
+
// state.
|
|
679
|
+
for notice in &resolved.notices {
|
|
680
|
+
assert_ne!(
|
|
681
|
+
notice.event, "transport.conpty_pipe_client_unwired",
|
|
682
|
+
"no pipe-client notice without a pipe_ready hint"
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// 0.5.x CR C-5 fix (leader msg_a89b5a03bbf0): factory returns to
|
|
688
|
+
// pure assembly. The `transport.conpty_pipe_client_unwired`
|
|
689
|
+
// notice is REMOVED from `build_conpty` — connect is deferred to
|
|
690
|
+
// the backend's `ensure_pipe_client` lazy path, which surfaces
|
|
691
|
+
// failures as `TransportError::MuxUnavailable` at Op call time
|
|
692
|
+
// (not at resolve time).
|
|
693
|
+
//
|
|
694
|
+
// Cross-platform: resolve NEVER emits pipe-client notices on
|
|
695
|
+
// either platform now. This test locks that invariant so a
|
|
696
|
+
// future revert would fire loudly.
|
|
697
|
+
#[test]
|
|
698
|
+
fn conpty_resolve_emits_no_pipe_client_notice_after_c5_fix() {
|
|
699
|
+
let workspace = ws();
|
|
700
|
+
let state = serde_json::json!({
|
|
701
|
+
"transport": {
|
|
702
|
+
"kind": "conpty",
|
|
703
|
+
"shim": {
|
|
704
|
+
"pipe_name": r"\\.\pipe\team-agent-conpty-test-team-a",
|
|
705
|
+
"pipe_ready": true
|
|
706
|
+
},
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
let input = TransportFactoryInput::new(&workspace, TransportPurpose::LifecycleWorker)
|
|
710
|
+
.with_team_key(Some("team-a"))
|
|
711
|
+
.with_state(Some(&state));
|
|
712
|
+
let resolved = resolve_transport(input).expect("must succeed");
|
|
713
|
+
assert_eq!(resolved.kind, BackendKind::ConPty);
|
|
714
|
+
let pipe_notices: Vec<_> = resolved
|
|
715
|
+
.notices
|
|
716
|
+
.iter()
|
|
717
|
+
.filter(|n| n.event == "transport.conpty_pipe_client_unwired")
|
|
718
|
+
.collect();
|
|
719
|
+
assert!(
|
|
720
|
+
pipe_notices.is_empty(),
|
|
721
|
+
"CR C-5 fix: resolve must not emit pipe-client notices \
|
|
722
|
+
(connect deferred to backend lazy path). Found: {:?}",
|
|
723
|
+
pipe_notices
|
|
724
|
+
.iter()
|
|
725
|
+
.map(|n| &n.event)
|
|
726
|
+
.collect::<Vec<_>>()
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
|
|
611
730
|
// Wire-string invariants for RequestedTransportBackend so a rename
|
|
612
731
|
// in Rust cannot silently drift the CLI accept-list.
|
|
613
732
|
#[test]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@team-agent/installer",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "npx installer for Team Agent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"codex",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"team-agent-installer": "npm/install.mjs"
|
|
21
21
|
},
|
|
22
22
|
"optionalDependencies": {
|
|
23
|
-
"@team-agent/cli-darwin-arm64": "0.5.
|
|
24
|
-
"@team-agent/cli-darwin-x64": "0.5.
|
|
25
|
-
"@team-agent/cli-linux-x64": "0.5.
|
|
23
|
+
"@team-agent/cli-darwin-arm64": "0.5.4",
|
|
24
|
+
"@team-agent/cli-darwin-x64": "0.5.4",
|
|
25
|
+
"@team-agent/cli-linux-x64": "0.5.4"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"postinstall": "node npm/bincheck.mjs",
|