@team-agent/installer 0.5.65 → 0.5.68

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 (208) hide show
  1. package/Cargo.lock +8 -1
  2. package/Cargo.toml +1 -1
  3. package/crates/team-agent/Cargo.toml +6 -0
  4. package/crates/team-agent/src/cli/adapters.rs +6 -1
  5. package/crates/team-agent/src/cli/diagnose.rs +82 -0
  6. package/crates/team-agent/src/cli/emit.rs +3 -3
  7. package/crates/team-agent/src/cli/grok_slot.rs +299 -0
  8. package/crates/team-agent/src/cli/leader.rs +21 -7
  9. package/crates/team-agent/src/cli/leaders.rs +125 -1
  10. package/crates/team-agent/src/cli/mod.rs +20 -0
  11. package/crates/team-agent/src/cli/send/presentation.rs +7 -1
  12. package/crates/team-agent/src/cli/spec.rs +2 -0
  13. package/crates/team-agent/src/cli/status_port/compact.rs +28 -0
  14. package/crates/team-agent/src/cli/status_port/snapshot.rs +25 -1
  15. package/crates/team-agent/src/cli/tests/base.rs +26 -3
  16. package/crates/team-agent/src/cli/tests/compile.rs +1 -1
  17. package/crates/team-agent/src/cli/tests/missing_subcommands.rs +129 -19
  18. package/crates/team-agent/src/cli/tests/mod.rs +2 -2
  19. package/crates/team-agent/src/cli/tests/run_delegation.rs +1 -1
  20. package/crates/team-agent/src/cli/tests/shutdown_kill_plan.rs +387 -6
  21. package/crates/team-agent/src/cli/tests/status_send.rs +79 -10
  22. package/crates/team-agent/src/cli/tests/verb_validate.rs +1 -1
  23. package/crates/team-agent/src/communication_mode/mod.rs +6 -4
  24. package/crates/team-agent/src/compiler/tests.rs +23 -20
  25. package/crates/team-agent/src/compiler.rs +84 -5
  26. package/crates/team-agent/src/conpty/backend.rs +16 -0
  27. package/crates/team-agent/src/coordinator/backoff.rs +55 -0
  28. package/crates/team-agent/src/coordinator/conpty_shim.rs +82 -0
  29. package/crates/team-agent/src/coordinator/health.rs +173 -0
  30. package/crates/team-agent/src/coordinator/mod.rs +31 -0
  31. package/crates/team-agent/src/coordinator/orphan.rs +31 -0
  32. package/crates/team-agent/src/coordinator/runtime_detectors.rs +30 -0
  33. package/crates/team-agent/src/coordinator/runtime_observation.rs +25 -0
  34. package/crates/team-agent/src/coordinator/steps/abnormal.rs +59 -0
  35. package/crates/team-agent/src/coordinator/steps/delivery.rs +10 -0
  36. package/crates/team-agent/src/coordinator/steps/health_sync.rs +10 -0
  37. package/crates/team-agent/src/coordinator/steps/mod.rs +22 -0
  38. package/crates/team-agent/src/coordinator/steps/persist.rs +10 -0
  39. package/crates/team-agent/src/coordinator/steps/runtime_prompts.rs +10 -0
  40. package/crates/team-agent/src/coordinator/steps/session_gate.rs +10 -0
  41. package/crates/team-agent/src/coordinator/tick.rs +133 -22
  42. package/crates/team-agent/src/coordinator/types.rs +49 -0
  43. package/crates/team-agent/src/db/message_store.rs +39 -5
  44. package/crates/team-agent/src/layout/worker_env.rs +20 -3
  45. package/crates/team-agent/src/layout/worker_window_helpers.rs +2 -0
  46. package/crates/team-agent/src/leader/provider_attribution.rs +53 -0
  47. package/crates/team-agent/src/leader/registry.rs +65 -0
  48. package/crates/team-agent/src/leader/start.rs +1080 -58
  49. package/crates/team-agent/src/leader/tests/team_in_team_state_scope_red.rs +1 -1
  50. package/crates/team-agent/src/lifecycle/display.rs +56 -0
  51. package/crates/team-agent/src/lifecycle/helpers.rs +57 -0
  52. package/crates/team-agent/src/lifecycle/launch/add_agent.rs +332 -14
  53. package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +69 -2
  54. package/crates/team-agent/src/lifecycle/launch/agent_state.rs +196 -2
  55. package/crates/team-agent/src/lifecycle/launch/clone_agent.rs +101 -11
  56. package/crates/team-agent/src/lifecycle/launch/cursor_create_chat.rs +229 -0
  57. package/crates/team-agent/src/lifecycle/launch/cursor_mcp.rs +332 -0
  58. package/crates/team-agent/src/lifecycle/launch/fork_agent.rs +204 -457
  59. package/crates/team-agent/src/lifecycle/launch/fork_entry.rs +24 -0
  60. package/crates/team-agent/src/lifecycle/launch/grok_per_seat.rs +260 -0
  61. package/crates/team-agent/src/lifecycle/launch/identity.rs +146 -0
  62. package/crates/team-agent/src/lifecycle/launch/layout.rs +60 -0
  63. package/crates/team-agent/src/lifecycle/launch/leader_context.rs +112 -0
  64. package/crates/team-agent/src/lifecycle/launch/mcp_config.rs +530 -0
  65. package/crates/team-agent/src/lifecycle/launch/ownership.rs +40 -0
  66. package/crates/team-agent/src/lifecycle/launch/plan.rs +31 -0
  67. package/crates/team-agent/src/lifecycle/launch/quick_start.rs +66 -0
  68. package/crates/team-agent/src/lifecycle/launch/quick_start_transport.rs +78 -0
  69. package/crates/team-agent/src/lifecycle/launch/readiness.rs +85 -38
  70. package/crates/team-agent/src/lifecycle/launch/role_source.rs +44 -44
  71. package/crates/team-agent/src/lifecycle/launch/spawn.rs +101 -4
  72. package/crates/team-agent/src/lifecycle/launch/spec_state.rs +244 -48
  73. package/crates/team-agent/src/lifecycle/launch/state_projection.rs +109 -2
  74. package/crates/team-agent/src/lifecycle/launch/worker_env.rs +214 -1
  75. package/crates/team-agent/src/lifecycle/launch.rs +209 -43
  76. package/crates/team-agent/src/lifecycle/lock.rs +42 -1
  77. package/crates/team-agent/src/lifecycle/mod.rs +11 -0
  78. package/crates/team-agent/src/lifecycle/pane_input_lock.rs +161 -0
  79. package/crates/team-agent/src/lifecycle/profile_launch.rs +98 -0
  80. package/crates/team-agent/src/lifecycle/profile_smoke.rs +51 -1
  81. package/crates/team-agent/src/lifecycle/restart/agent.rs +213 -3
  82. package/crates/team-agent/src/lifecycle/restart/common.rs +373 -18
  83. package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +27 -0
  84. package/crates/team-agent/src/lifecycle/restart/preflight.rs +25 -0
  85. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +165 -15
  86. package/crates/team-agent/src/lifecycle/restart/remove.rs +196 -5
  87. package/crates/team-agent/src/lifecycle/restart/selection.rs +72 -0
  88. package/crates/team-agent/src/lifecycle/restart/team_state.rs +22 -0
  89. package/crates/team-agent/src/lifecycle/restart.rs +29 -0
  90. package/crates/team-agent/src/lifecycle/tests/acceptance_b_batch_red.rs +1 -1
  91. package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +3 -4
  92. package/crates/team-agent/src/lifecycle/tests/behavioral_diff_264_red.rs +1 -1
  93. package/crates/team-agent/src/lifecycle/tests/claude_compatible_config_red.rs +2 -2
  94. package/crates/team-agent/src/lifecycle/tests/claude_profile_launch_red.rs +4 -4
  95. package/crates/team-agent/src/lifecycle/tests/clone_agent_preserves_source_tools.rs +309 -0
  96. package/crates/team-agent/src/lifecycle/tests/clone_fork_copilot_perms_red.rs +159 -174
  97. package/crates/team-agent/src/lifecycle/tests/communication_mode_runtime_contract_red.rs +2 -2
  98. package/crates/team-agent/src/lifecycle/tests/copilot_provider_red.rs +15 -13
  99. package/crates/team-agent/src/lifecycle/tests/core.rs +4 -18
  100. package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +1 -1
  101. package/crates/team-agent/src/lifecycle/tests/cursor_mcp_overlay.rs +287 -0
  102. package/crates/team-agent/src/lifecycle/tests/cursor_require_explicit_model_red.rs +229 -0
  103. package/crates/team-agent/src/lifecycle/tests/cursor_restart_resume_red.rs +353 -0
  104. package/crates/team-agent/src/lifecycle/tests/display_adaptive_red.rs +1 -1
  105. package/crates/team-agent/src/lifecycle/tests/f032_startup_prompt_best_effort_red.rs +1 -1
  106. package/crates/team-agent/src/lifecycle/tests/g1_silent_faces.rs +784 -0
  107. package/crates/team-agent/src/lifecycle/tests/gate_fixtures.rs +562 -0
  108. package/crates/team-agent/src/lifecycle/tests/grok_effort_argv_red.rs +239 -0
  109. package/crates/team-agent/src/lifecycle/tests/grok_mcp_overlay_red.rs +498 -0
  110. package/crates/team-agent/src/lifecycle/tests/grok_require_explicit_model_red.rs +250 -0
  111. package/crates/team-agent/src/lifecycle/tests/grok_restart_resume_red.rs +293 -0
  112. package/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs +3 -0
  113. package/crates/team-agent/src/lifecycle/tests/host_cotenant_death_p0_contract.rs +3 -3
  114. package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +65 -40
  115. package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +20 -32
  116. package/crates/team-agent/src/lifecycle/tests/lifecycle_rollback_red.rs +17 -9
  117. package/crates/team-agent/src/lifecycle/tests/mcp_tool_name_format_red.rs +69 -0
  118. package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +24 -23
  119. package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +98 -62
  120. package/crates/team-agent/src/lifecycle/tests/quick_start_worker_readiness_red.rs +2 -2
  121. package/crates/team-agent/src/lifecycle/tests/restart_build_before_destroy_0540_contract.rs +1 -1
  122. package/crates/team-agent/src/lifecycle/tests/restart_liveness_red.rs +1 -1
  123. package/crates/team-agent/src/lifecycle/tests/restart_rebind_hotfix_252_red.rs +3 -1
  124. package/crates/team-agent/src/lifecycle/tests/restart_session_capture_red.rs +2 -2
  125. package/crates/team-agent/src/lifecycle/tests/resume_recover_red.rs +1 -1
  126. package/crates/team-agent/src/lifecycle/tests/stale_team_saveconflict_contract.rs +1 -1
  127. package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +41 -8
  128. package/crates/team-agent/src/lifecycle/tests/status_credential_redaction_contract.rs +3 -3
  129. package/crates/team-agent/src/lifecycle/tests/subprep_codex_trust_roundtrip_red.rs +1 -1
  130. package/crates/team-agent/src/lifecycle/tests/swallow_batch4_semantics_red.rs +1 -1
  131. package/crates/team-agent/src/lifecycle/tests/team_in_team_identity_scope_red.rs +1 -1
  132. package/crates/team-agent/src/lifecycle/tests/team_in_team_sibling_quick_start_red.rs +1 -1
  133. package/crates/team-agent/src/lifecycle/tests/team_in_team_state_scope_red.rs +1 -1
  134. package/crates/team-agent/src/lifecycle/tests/team_key_retirement_txn_red.rs +1 -1
  135. package/crates/team-agent/src/lifecycle/tests/test_isolation_escape_contract.rs +60 -2
  136. package/crates/team-agent/src/lifecycle/tests/upgrade_compat_0211_red.rs +1 -1
  137. package/crates/team-agent/src/lifecycle/tests/verify_rs031_window_consistency_red.rs +2 -2
  138. package/crates/team-agent/src/lifecycle/tests/worker_spawn_env_red.rs +69 -26
  139. package/crates/team-agent/src/lifecycle/tests.rs +23 -15
  140. package/crates/team-agent/src/lifecycle/types.rs +61 -2
  141. package/crates/team-agent/src/lifecycle/worker_command_context.rs +200 -33
  142. package/crates/team-agent/src/mcp_server/tests/scoped.rs +100 -1
  143. package/crates/team-agent/src/mcp_server/tests.rs +196 -2
  144. package/crates/team-agent/src/messaging/delivery.rs +405 -40
  145. package/crates/team-agent/src/messaging/helpers.rs +2 -0
  146. package/crates/team-agent/src/messaging/leader_receiver.rs +53 -1
  147. package/crates/team-agent/src/messaging/results.rs +4 -0
  148. package/crates/team-agent/src/messaging/send.rs +34 -0
  149. package/crates/team-agent/src/messaging/tests/dup_inject.rs +406 -0
  150. package/crates/team-agent/src/messaging/tests/e23.rs +9 -0
  151. package/crates/team-agent/src/messaging/tests/leader_inject_acceptance.rs +66 -0
  152. package/crates/team-agent/src/messaging/tests/main_preserved.rs +1 -1
  153. package/crates/team-agent/src/messaging/tests/mod.rs +1 -0
  154. package/crates/team-agent/src/messaging/types.rs +4 -1
  155. package/crates/team-agent/src/model/enums.rs +14 -5
  156. package/crates/team-agent/src/model/permissions.rs +3 -0
  157. package/crates/team-agent/src/model/spec.rs +129 -6
  158. package/crates/team-agent/src/model/testdata/spec_invalid_a.yaml +3 -1
  159. package/crates/team-agent/src/model/testdata/team.spec.golden.yaml +3 -1
  160. package/crates/team-agent/src/model/testdata/team.spec.yaml +3 -1
  161. package/crates/team-agent/src/os_probe.rs +73 -2
  162. package/crates/team-agent/src/provider/adapter.rs +231 -4
  163. package/crates/team-agent/src/provider/adapters/claude.rs +5 -2
  164. package/crates/team-agent/src/provider/adapters/codex.rs +5 -2
  165. package/crates/team-agent/src/provider/adapters/copilot.rs +5 -2
  166. package/crates/team-agent/src/provider/adapters/cursor_agent.rs +86 -0
  167. package/crates/team-agent/src/provider/adapters/grok.rs +157 -0
  168. package/crates/team-agent/src/provider/adapters/mod.rs +2 -0
  169. package/crates/team-agent/src/provider/bypass_flags.rs +124 -0
  170. package/crates/team-agent/src/provider/classify.rs +4 -2
  171. package/crates/team-agent/src/provider/faults.rs +2 -1
  172. package/crates/team-agent/src/provider/mod.rs +13 -0
  173. package/crates/team-agent/src/provider/session/capture.rs +158 -20
  174. package/crates/team-agent/src/provider/session/context_fork/claude.rs +38 -1
  175. package/crates/team-agent/src/provider/session/context_fork/codex.rs +72 -1
  176. package/crates/team-agent/src/provider/session/context_fork/outcome.rs +57 -1
  177. package/crates/team-agent/src/provider/session/context_fork.rs +77 -3
  178. package/crates/team-agent/src/provider/session/mod.rs +18 -0
  179. package/crates/team-agent/src/provider/session/resume.rs +57 -0
  180. package/crates/team-agent/src/provider/session_scan/claude.rs +125 -1
  181. package/crates/team-agent/src/provider/session_scan/codex.rs +94 -1
  182. package/crates/team-agent/src/provider/session_scan/common.rs +204 -2
  183. package/crates/team-agent/src/provider/session_scan/copilot.rs +33 -1
  184. package/crates/team-agent/src/provider/session_scan/cursor.rs +538 -0
  185. package/crates/team-agent/src/provider/session_scan/grok.rs +288 -0
  186. package/crates/team-agent/src/provider/session_scan.rs +8 -0
  187. package/crates/team-agent/src/provider/submit_now.rs +94 -0
  188. package/crates/team-agent/src/provider/tests/adapter.rs +304 -0
  189. package/crates/team-agent/src/provider/types.rs +4 -2
  190. package/crates/team-agent/src/provider/wire.rs +23 -1
  191. package/crates/team-agent/src/state/persist.rs +301 -8
  192. package/crates/team-agent/src/state/repository.rs +5 -0
  193. package/crates/team-agent/src/tmux_backend/tests.rs +1737 -42
  194. package/crates/team-agent/src/tmux_backend.rs +1083 -75
  195. package/crates/team-agent/src/transport/test_support.rs +20 -0
  196. package/crates/team-agent/src/transport/tests/wire.rs +28 -2
  197. package/crates/team-agent/src/transport.rs +265 -1
  198. package/npm/install.mjs +129 -73
  199. package/package.json +4 -4
  200. package/skills/team-agent/SKILL.md +33 -238
  201. package/skills/team-agent/command-coverage.json +31 -0
  202. package/crates/team-agent/src/lifecycle/launch/approval.rs +0 -134
  203. package/crates/team-agent/src/lifecycle/launch/fork_agent/completion.rs +0 -59
  204. package/crates/team-agent/src/lifecycle/launch/fork_finalize.rs +0 -483
  205. package/crates/team-agent/src/lifecycle/launch/fork_pending.rs +0 -109
  206. package/crates/team-agent/src/lifecycle/launch/fork_state.rs +0 -447
  207. package/crates/team-agent/src/lifecycle/tests/codex_mcp_approval_inheritance_red.rs +0 -1187
  208. package/crates/team-agent/src/lifecycle/tests/worker_dangerous_bypass_argv_red.rs +0 -327
@@ -1,8 +1,26 @@
1
+ //! ---
2
+ //! purpose: MCP no-compaction contract test with fixture-owned workspace and path provenance
3
+ //! contract:
4
+ //! provides:
5
+ //! - name: mcp_state_fixture
6
+ //! what: supplies explicit process-owned workspace and state-file paths without mutating process-global environment
7
+ //! - name: mcp_state_path_provenance
8
+ //! what: records raw/canonical workspace, resolved state path, and filesystem ownership facts
9
+ //! depends:
10
+ //! - crate::mcp_server::lifecycle_tools::state_status
11
+ //! - crate::state::selector
12
+ //! boundary:
13
+ //! - the owned no-compaction test writes only within its fixture root
14
+ //! - this suite does not alter persistence semantics
15
+ //! maturity: wired
16
+ //! ---
1
17
  //! step 14a · mcp_server::tests — WAVE-2 RED contracts (Python v0.2.11 golden).
2
18
  #![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
3
19
 
4
20
  use super::*;
5
21
  use serde_json::json;
22
+ use sha2::{Digest, Sha256};
23
+ use std::path::{Path, PathBuf};
6
24
 
7
25
  // ── helpers ──────────────────────────────────────────────────────────────
8
26
 
@@ -27,8 +45,7 @@ fn unique_ws(tag: &str) -> std::path::PathBuf {
27
45
  static N: AtomicU64 = AtomicU64::new(0);
28
46
  loop {
29
47
  let n = N.fetch_add(1, Ordering::Relaxed);
30
- let p =
31
- std::env::temp_dir().join(format!("ta-rs-mcp-{tag}-{}-{n}", std::process::id()));
48
+ let p = std::env::temp_dir().join(format!("ta-rs-mcp-{tag}-{}-{n}", std::process::id()));
32
49
  match std::fs::create_dir(&p) {
33
50
  Ok(()) => return p,
34
51
  Err(error) if error.kind() == ErrorKind::AlreadyExists => {}
@@ -37,6 +54,183 @@ fn unique_ws(tag: &str) -> std::path::PathBuf {
37
54
  }
38
55
  }
39
56
 
57
+ static MCP_FIXTURE_SEQ: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
58
+
59
+ /// One process-owned root for update_state tests. All paths are passed explicitly
60
+ /// to the code under test; the fixture never changes process-global environment.
61
+ struct McpStateFixture {
62
+ root: PathBuf,
63
+ workspace: PathBuf,
64
+ receipt: PathBuf,
65
+ }
66
+
67
+ impl McpStateFixture {
68
+ fn new(_tag: &str) -> Self {
69
+ let seq = MCP_FIXTURE_SEQ.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
70
+ let base = if cfg!(target_os = "macos") {
71
+ PathBuf::from("/private/tmp")
72
+ } else {
73
+ PathBuf::from("/tmp")
74
+ };
75
+ let raw_root = base.join(format!("ta-mcp-{}-{seq}", std::process::id()));
76
+ std::fs::create_dir(&raw_root).unwrap();
77
+ let root = std::fs::canonicalize(raw_root).unwrap();
78
+ let workspace = root.join("workspace");
79
+ let receipt = root
80
+ .parent()
81
+ .unwrap()
82
+ .join(format!("ta-mcp-receipt-{}-{seq}.json", std::process::id()));
83
+ std::fs::create_dir(&workspace).unwrap();
84
+
85
+ let fixture = Self {
86
+ root,
87
+ workspace,
88
+ receipt,
89
+ };
90
+ fixture.seed_spec("team_state.md");
91
+ crate::state::repository::StateRepository::new(&fixture.workspace)
92
+ .save(
93
+ crate::state::repository::StateWriteIntent::FakeE2eSeed,
94
+ &json!({
95
+ "session_name": "mcp-fixture",
96
+ "active_team_key": "current",
97
+ "agents": {},
98
+ "tasks": []
99
+ }),
100
+ )
101
+ .unwrap();
102
+ fixture
103
+ }
104
+
105
+ fn seed_spec(&self, state_file: &str) {
106
+ std::fs::write(
107
+ self.workspace.join("team.spec.yaml"),
108
+ format!(
109
+ "team:\n name: mcp-fixture\n objective: path contract\nagents: []\ntasks: []\ncontext:\n state_file: {state_file}\n"
110
+ ),
111
+ )
112
+ .unwrap();
113
+ }
114
+
115
+ fn state_file(&self, relative: &str) -> PathBuf {
116
+ self.workspace.join(relative)
117
+ }
118
+
119
+ fn record_provenance(&self, raw_workspace: &Path, state_file: &Path) -> PathBuf {
120
+ let canonical_workspace =
121
+ crate::model::paths::canonical_run_workspace(raw_workspace).unwrap();
122
+ assert!(self.under_root(raw_workspace));
123
+ assert!(self.under_root(&canonical_workspace));
124
+ assert!(self.under_root(state_file));
125
+ let team_dir = self.workspace.join(".team");
126
+ let runtime_dir = team_dir.join("runtime");
127
+ let runtime_state = crate::state::persist::runtime_state_path(&self.workspace);
128
+ let paths = [
129
+ ("root", self.root.as_path()),
130
+ ("raw_workspace", raw_workspace),
131
+ ("canonical_workspace", canonical_workspace.as_path()),
132
+ ("team_dir", team_dir.as_path()),
133
+ ("runtime_dir", runtime_dir.as_path()),
134
+ ("state_parent", state_file.parent().unwrap()),
135
+ ("runtime_state", runtime_state.as_path()),
136
+ ];
137
+ let mut facts = paths
138
+ .into_iter()
139
+ .map(|(name, path)| {
140
+ let metadata = std::fs::symlink_metadata(path).unwrap();
141
+ json!({
142
+ "name": name,
143
+ "path": path.display().to_string(),
144
+ "uid": metadata_uid(&metadata),
145
+ "mode": metadata_mode(&metadata),
146
+ "device": metadata_device(&metadata)
147
+ })
148
+ })
149
+ .collect::<Vec<_>>();
150
+ if let Ok(metadata) = std::fs::symlink_metadata(state_file) {
151
+ facts.push(json!({
152
+ "name": "state_file",
153
+ "path": state_file.display().to_string(),
154
+ "uid": metadata_uid(&metadata),
155
+ "mode": metadata_mode(&metadata),
156
+ "device": metadata_device(&metadata)
157
+ }));
158
+ }
159
+ let payload = json!({
160
+ "raw_workspace": raw_workspace.display().to_string(),
161
+ "canonical_workspace": canonical_workspace.display().to_string(),
162
+ "resolved_state_file": state_file.display().to_string(),
163
+ "runtime_state_path": runtime_state.display().to_string(),
164
+ "facts": facts
165
+ });
166
+ let payload_bytes = serde_json::to_vec(&payload).unwrap();
167
+ let payload_sha256 = format!("{:x}", Sha256::digest(&payload_bytes));
168
+ let receipt = json!({
169
+ "schema": "mcp-state-provenance-v1",
170
+ "payload": payload,
171
+ "payload_sha256": payload_sha256
172
+ });
173
+ let receipt_bytes = serde_json::to_vec_pretty(&receipt).unwrap();
174
+ use std::io::Write;
175
+ let mut file = std::fs::OpenOptions::new()
176
+ .write(true)
177
+ .create_new(true)
178
+ .open(&self.receipt)
179
+ .unwrap();
180
+ file.write_all(&receipt_bytes).unwrap();
181
+ file.sync_all().unwrap();
182
+ self.receipt.clone()
183
+ }
184
+
185
+ fn under_root(&self, path: &Path) -> bool {
186
+ let candidate = if path.exists() {
187
+ std::fs::canonicalize(path).unwrap()
188
+ } else {
189
+ path.to_path_buf()
190
+ };
191
+ candidate.starts_with(&self.root)
192
+ }
193
+ }
194
+
195
+ impl Drop for McpStateFixture {
196
+ fn drop(&mut self) {
197
+ let _ = std::fs::remove_dir_all(&self.root);
198
+ }
199
+ }
200
+
201
+ #[cfg(unix)]
202
+ fn metadata_uid(metadata: &std::fs::Metadata) -> u32 {
203
+ use std::os::unix::fs::MetadataExt;
204
+ metadata.uid()
205
+ }
206
+
207
+ #[cfg(not(unix))]
208
+ fn metadata_uid(_: &std::fs::Metadata) -> u32 {
209
+ 0
210
+ }
211
+
212
+ #[cfg(unix)]
213
+ fn metadata_mode(metadata: &std::fs::Metadata) -> u32 {
214
+ use std::os::unix::fs::MetadataExt;
215
+ metadata.mode()
216
+ }
217
+
218
+ #[cfg(not(unix))]
219
+ fn metadata_mode(_: &std::fs::Metadata) -> u32 {
220
+ 0
221
+ }
222
+
223
+ #[cfg(unix)]
224
+ fn metadata_device(metadata: &std::fs::Metadata) -> u64 {
225
+ use std::os::unix::fs::MetadataExt;
226
+ metadata.dev()
227
+ }
228
+
229
+ #[cfg(not(unix))]
230
+ fn metadata_device(_: &std::fs::Metadata) -> u64 {
231
+ 0
232
+ }
233
+
40
234
  include!("tests/normalize.rs");
41
235
  include!("tests/wire.rs");
42
236
  include!("tests/send.rs");