@team-agent/installer 0.2.11 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +744 -0
- package/Cargo.toml +34 -0
- package/crates/team-agent/Cargo.toml +33 -0
- package/crates/team-agent/src/cli/adapters.rs +1343 -0
- package/crates/team-agent/src/cli/diagnose.rs +554 -0
- package/crates/team-agent/src/cli/emit.rs +1077 -0
- package/crates/team-agent/src/cli/helpers.rs +88 -0
- package/crates/team-agent/src/cli/leader.rs +216 -0
- package/crates/team-agent/src/cli/mod.rs +1141 -0
- package/crates/team-agent/src/cli/profile.rs +306 -0
- package/crates/team-agent/src/cli/send.rs +215 -0
- package/crates/team-agent/src/cli/status.rs +179 -0
- package/crates/team-agent/src/cli/status_port.rs +502 -0
- package/crates/team-agent/src/cli/tests/base.rs +616 -0
- package/crates/team-agent/src/cli/tests/compile.rs +96 -0
- package/crates/team-agent/src/cli/tests/divergence.rs +509 -0
- package/crates/team-agent/src/cli/tests/lane_c.rs +333 -0
- package/crates/team-agent/src/cli/tests/leader_watch.rs +395 -0
- package/crates/team-agent/src/cli/tests/main_preserved.rs +675 -0
- package/crates/team-agent/src/cli/tests/missing_subcommands.rs +390 -0
- package/crates/team-agent/src/cli/tests/mod.rs +97 -0
- package/crates/team-agent/src/cli/tests/peer_allow.rs +137 -0
- package/crates/team-agent/src/cli/tests/repair_state_byte_lock.rs +302 -0
- package/crates/team-agent/src/cli/tests/run_delegation.rs +305 -0
- package/crates/team-agent/src/cli/tests/status_send.rs +385 -0
- package/crates/team-agent/src/cli/tests/verb_profile.rs +182 -0
- package/crates/team-agent/src/cli/tests/verb_settle.rs +236 -0
- package/crates/team-agent/src/cli/tests/verb_validate.rs +184 -0
- package/crates/team-agent/src/cli/types.rs +605 -0
- package/crates/team-agent/src/compiler/tests.rs +701 -0
- package/crates/team-agent/src/compiler.rs +489 -0
- package/crates/team-agent/src/coordinator/backoff.rs +153 -0
- package/crates/team-agent/src/coordinator/health.rs +436 -0
- package/crates/team-agent/src/coordinator/mod.rs +80 -0
- package/crates/team-agent/src/coordinator/orphan.rs +179 -0
- package/crates/team-agent/src/coordinator/tests/abnormal.rs +255 -0
- package/crates/team-agent/src/coordinator/tests/basics.rs +262 -0
- package/crates/team-agent/src/coordinator/tests/daemon.rs +323 -0
- package/crates/team-agent/src/coordinator/tests/health_sync.rs +263 -0
- package/crates/team-agent/src/coordinator/tests/main_preserved.rs +136 -0
- package/crates/team-agent/src/coordinator/tests/mod.rs +310 -0
- package/crates/team-agent/src/coordinator/tests/spine.rs +261 -0
- package/crates/team-agent/src/coordinator/tests/takeover.rs +227 -0
- package/crates/team-agent/src/coordinator/tests/tick_core.rs +256 -0
- package/crates/team-agent/src/coordinator/tests/watch.rs +167 -0
- package/crates/team-agent/src/coordinator/tick.rs +2032 -0
- package/crates/team-agent/src/coordinator/types.rs +584 -0
- package/crates/team-agent/src/db/migration.rs +716 -0
- package/crates/team-agent/src/db/mod.rs +23 -0
- package/crates/team-agent/src/db/schema.rs +378 -0
- package/crates/team-agent/src/event_log.rs +375 -0
- package/crates/team-agent/src/fake_worker.rs +253 -0
- package/crates/team-agent/src/leader/helpers.rs +190 -0
- package/crates/team-agent/src/leader/inject.rs +33 -0
- package/crates/team-agent/src/leader/lease.rs +1063 -0
- package/crates/team-agent/src/leader/mod.rs +99 -0
- package/crates/team-agent/src/leader/owner_bind.rs +292 -0
- package/crates/team-agent/src/leader/rediscover/tests.rs +525 -0
- package/crates/team-agent/src/leader/rediscover.rs +1099 -0
- package/crates/team-agent/src/leader/start.rs +273 -0
- package/crates/team-agent/src/leader/takeover.rs +235 -0
- package/crates/team-agent/src/leader/tests/basics.rs +183 -0
- package/crates/team-agent/src/leader/tests/byte_findings.rs +234 -0
- package/crates/team-agent/src/leader/tests/identity.rs +206 -0
- package/crates/team-agent/src/leader/tests/idle.rs +271 -0
- package/crates/team-agent/src/leader/tests/lease_api.rs +225 -0
- package/crates/team-agent/src/leader/tests/lease_claim.rs +253 -0
- package/crates/team-agent/src/leader/tests/mod.rs +125 -0
- package/crates/team-agent/src/leader/tests/rediscover.rs +351 -0
- package/crates/team-agent/src/leader/tests/wake_start_owner.rs +204 -0
- package/crates/team-agent/src/leader/types.rs +487 -0
- package/crates/team-agent/src/lib.rs +85 -0
- package/crates/team-agent/src/lifecycle/display.rs +228 -0
- package/crates/team-agent/src/lifecycle/helpers.rs +112 -0
- package/crates/team-agent/src/lifecycle/launch/plan.rs +227 -0
- package/crates/team-agent/src/lifecycle/launch.rs +1833 -0
- package/crates/team-agent/src/lifecycle/mod.rs +62 -0
- package/crates/team-agent/src/lifecycle/restart/agent.rs +533 -0
- package/crates/team-agent/src/lifecycle/restart/common.rs +517 -0
- package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +41 -0
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +268 -0
- package/crates/team-agent/src/lifecycle/restart/remove.rs +780 -0
- package/crates/team-agent/src/lifecycle/restart/selection.rs +208 -0
- package/crates/team-agent/src/lifecycle/restart/team_state.rs +242 -0
- package/crates/team-agent/src/lifecycle/restart.rs +76 -0
- package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +455 -0
- package/crates/team-agent/src/lifecycle/tests/core.rs +989 -0
- package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +583 -0
- package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +933 -0
- package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +265 -0
- package/crates/team-agent/src/lifecycle/tests.rs +27 -0
- package/crates/team-agent/src/lifecycle/types.rs +685 -0
- package/crates/team-agent/src/main.rs +41 -0
- package/crates/team-agent/src/mcp_server/helpers.rs +228 -0
- package/crates/team-agent/src/mcp_server/mod.rs +183 -0
- package/crates/team-agent/src/mcp_server/normalize.rs +312 -0
- package/crates/team-agent/src/mcp_server/tests/golden.rs +283 -0
- package/crates/team-agent/src/mcp_server/tests/normalize.rs +244 -0
- package/crates/team-agent/src/mcp_server/tests/scoped.rs +189 -0
- package/crates/team-agent/src/mcp_server/tests/send.rs +222 -0
- package/crates/team-agent/src/mcp_server/tests/tools.rs +158 -0
- package/crates/team-agent/src/mcp_server/tests/wire.rs +159 -0
- package/crates/team-agent/src/mcp_server/tests.rs +38 -0
- package/crates/team-agent/src/mcp_server/tools.rs +603 -0
- package/crates/team-agent/src/mcp_server/types.rs +421 -0
- package/crates/team-agent/src/mcp_server/wire.rs +388 -0
- package/crates/team-agent/src/message_store.rs +767 -0
- package/crates/team-agent/src/messaging/activity.rs +433 -0
- package/crates/team-agent/src/messaging/delivery.rs +542 -0
- package/crates/team-agent/src/messaging/helpers.rs +209 -0
- package/crates/team-agent/src/messaging/leader_receiver.rs +340 -0
- package/crates/team-agent/src/messaging/mod.rs +147 -0
- package/crates/team-agent/src/messaging/peers.rs +32 -0
- package/crates/team-agent/src/messaging/results.rs +537 -0
- package/crates/team-agent/src/messaging/scheduler.rs +344 -0
- package/crates/team-agent/src/messaging/selftest.rs +100 -0
- package/crates/team-agent/src/messaging/send.rs +582 -0
- package/crates/team-agent/src/messaging/tests/basic.rs +357 -0
- package/crates/team-agent/src/messaging/tests/main_preserved.rs +122 -0
- package/crates/team-agent/src/messaging/tests/mod.rs +293 -0
- package/crates/team-agent/src/messaging/tests/runtime.rs +1422 -0
- package/crates/team-agent/src/messaging/tests/spine.rs +437 -0
- package/crates/team-agent/src/messaging/trust.rs +192 -0
- package/crates/team-agent/src/messaging/types.rs +355 -0
- package/crates/team-agent/src/messaging/watchers.rs +591 -0
- package/crates/team-agent/src/model/enums.rs +311 -0
- package/crates/team-agent/src/model/errors.rs +17 -0
- package/crates/team-agent/src/model/ids.rs +155 -0
- package/crates/team-agent/src/model/mod.rs +22 -0
- package/crates/team-agent/src/model/paths.rs +228 -0
- package/crates/team-agent/src/model/permissions.rs +567 -0
- package/crates/team-agent/src/model/routing.rs +340 -0
- package/crates/team-agent/src/model/spec.rs +680 -0
- package/crates/team-agent/src/model/task_graph.rs +380 -0
- package/crates/team-agent/src/model/testdata/fuzz.golden.yaml +43 -0
- package/crates/team-agent/src/model/testdata/fuzz.yaml +43 -0
- package/crates/team-agent/src/model/testdata/spec_invalid_a.yaml +207 -0
- package/crates/team-agent/src/model/testdata/team.spec.golden.yaml +206 -0
- package/crates/team-agent/src/model/testdata/team.spec.yaml +206 -0
- package/crates/team-agent/src/model/yaml/tests.rs +288 -0
- package/crates/team-agent/src/model/yaml.rs +800 -0
- package/crates/team-agent/src/packaging/install.rs +305 -0
- package/crates/team-agent/src/packaging/migrate.rs +30 -0
- package/crates/team-agent/src/packaging/mod.rs +82 -0
- package/crates/team-agent/src/packaging/repair.rs +24 -0
- package/crates/team-agent/src/packaging/tests.rs +829 -0
- package/crates/team-agent/src/packaging/types.rs +369 -0
- package/crates/team-agent/src/provider/adapter.rs +801 -0
- package/crates/team-agent/src/provider/approvals/mod.rs +2 -0
- package/crates/team-agent/src/provider/approvals/parsing.rs +452 -0
- package/crates/team-agent/src/provider/approvals/runtime_prompts.rs +163 -0
- package/crates/team-agent/src/provider/classify.rs +456 -0
- package/crates/team-agent/src/provider/faults.rs +136 -0
- package/crates/team-agent/src/provider/helpers.rs +41 -0
- package/crates/team-agent/src/provider/mod.rs +53 -0
- package/crates/team-agent/src/provider/startup_prompt.rs +423 -0
- package/crates/team-agent/src/provider/tests/adapter.rs +239 -0
- package/crates/team-agent/src/provider/tests/classify.rs +240 -0
- package/crates/team-agent/src/provider/tests/faults.rs +120 -0
- package/crates/team-agent/src/provider/tests/idle.rs +208 -0
- package/crates/team-agent/src/provider/tests/wire.rs +213 -0
- package/crates/team-agent/src/provider/tests.rs +31 -0
- package/crates/team-agent/src/provider/types.rs +424 -0
- package/crates/team-agent/src/state/identity.rs +656 -0
- package/crates/team-agent/src/state/mod.rs +58 -0
- package/crates/team-agent/src/state/owner_gate.rs +423 -0
- package/crates/team-agent/src/state/persist.rs +712 -0
- package/crates/team-agent/src/state/projection.rs +657 -0
- package/crates/team-agent/src/state/selector.rs +105 -0
- package/crates/team-agent/src/state/testdata/state-rich.canonical.json +133 -0
- package/crates/team-agent/src/tmux_backend/tests.rs +586 -0
- package/crates/team-agent/src/tmux_backend.rs +758 -0
- package/crates/team-agent/src/transport/test_support.rs +252 -0
- package/crates/team-agent/src/transport/tests/behavior.rs +327 -0
- package/crates/team-agent/src/transport/tests/mod.rs +199 -0
- package/crates/team-agent/src/transport/tests/wire.rs +527 -0
- package/crates/team-agent/src/transport.rs +774 -0
- package/npm/install.mjs +90 -106
- package/package.json +15 -13
- package/crates/team-agent-core/Cargo.toml +0 -12
- package/crates/team-agent-core/src/lib.rs +0 -332
- package/crates/team-agent-core/src/main.rs +0 -152
- package/pyproject.toml +0 -18
- package/scripts/install.py +0 -88
- package/scripts/run_regression_tests.py +0 -83
- package/src/team_agent/__init__.py +0 -3
- package/src/team_agent/__main__.py +0 -5
- package/src/team_agent/_legacy_pane_discovery.py +0 -186
- package/src/team_agent/abnormal_track.py +0 -253
- package/src/team_agent/approvals/__init__.py +0 -65
- package/src/team_agent/approvals/constants.py +0 -6
- package/src/team_agent/approvals/parsing.py +0 -176
- package/src/team_agent/approvals/runtime_prompts.py +0 -171
- package/src/team_agent/approvals/status.py +0 -176
- package/src/team_agent/cli/__init__.py +0 -137
- package/src/team_agent/cli/commands.py +0 -481
- package/src/team_agent/cli/e2e.py +0 -202
- package/src/team_agent/cli/helpers.py +0 -226
- package/src/team_agent/cli/parser.py +0 -540
- package/src/team_agent/compiler.py +0 -334
- package/src/team_agent/coordinator/__init__.py +0 -53
- package/src/team_agent/coordinator/__main__.py +0 -119
- package/src/team_agent/coordinator/lifecycle.py +0 -411
- package/src/team_agent/coordinator/metadata.py +0 -61
- package/src/team_agent/coordinator/paths.py +0 -17
- package/src/team_agent/diagnose/__init__.py +0 -48
- package/src/team_agent/diagnose/checks.py +0 -101
- package/src/team_agent/diagnose/comms.py +0 -213
- package/src/team_agent/diagnose/health.py +0 -241
- package/src/team_agent/diagnose/orphan_cleanup.py +0 -364
- package/src/team_agent/diagnose/preflight.py +0 -194
- package/src/team_agent/diagnose/quick_start.py +0 -324
- package/src/team_agent/display/__init__.py +0 -92
- package/src/team_agent/display/adaptive.py +0 -511
- package/src/team_agent/display/backend.py +0 -46
- package/src/team_agent/display/close.py +0 -154
- package/src/team_agent/display/ghostty.py +0 -77
- package/src/team_agent/display/rebuild.py +0 -102
- package/src/team_agent/display/tiling.py +0 -156
- package/src/team_agent/display/worker_window.py +0 -114
- package/src/team_agent/display/workspace.py +0 -382
- package/src/team_agent/errors.py +0 -10
- package/src/team_agent/events.py +0 -84
- package/src/team_agent/fake_worker.py +0 -80
- package/src/team_agent/idle_predicate.py +0 -218
- package/src/team_agent/idle_takeover.py +0 -59
- package/src/team_agent/idle_takeover_wiring.py +0 -114
- package/src/team_agent/launch/__init__.py +0 -41
- package/src/team_agent/launch/bootstrap.py +0 -85
- package/src/team_agent/launch/config.py +0 -106
- package/src/team_agent/launch/core.py +0 -301
- package/src/team_agent/launch/requirements.py +0 -57
- package/src/team_agent/leader/__init__.py +0 -926
- package/src/team_agent/leader_binding.py +0 -183
- package/src/team_agent/lifecycle/__init__.py +0 -5
- package/src/team_agent/lifecycle/agents.py +0 -278
- package/src/team_agent/lifecycle/operations.py +0 -411
- package/src/team_agent/lifecycle/paste_buffer_hygiene.py +0 -39
- package/src/team_agent/lifecycle/start.py +0 -363
- package/src/team_agent/mcp_server/__init__.py +0 -42
- package/src/team_agent/mcp_server/__main__.py +0 -7
- package/src/team_agent/mcp_server/contracts.py +0 -148
- package/src/team_agent/mcp_server/normalize.py +0 -257
- package/src/team_agent/mcp_server/server.py +0 -150
- package/src/team_agent/mcp_server/tools.py +0 -352
- package/src/team_agent/message_store/__init__.py +0 -23
- package/src/team_agent/message_store/agent_health.py +0 -113
- package/src/team_agent/message_store/core.py +0 -497
- package/src/team_agent/message_store/leader_notification_log.py +0 -198
- package/src/team_agent/message_store/result_watchers.py +0 -251
- package/src/team_agent/message_store/schema.py +0 -308
- package/src/team_agent/message_store/schema_migration.py +0 -448
- package/src/team_agent/messaging/__init__.py +0 -1
- package/src/team_agent/messaging/activity_detector.py +0 -262
- package/src/team_agent/messaging/delivery.py +0 -504
- package/src/team_agent/messaging/deps.py +0 -247
- package/src/team_agent/messaging/idle_alerts.py +0 -423
- package/src/team_agent/messaging/internal_delivery.py +0 -46
- package/src/team_agent/messaging/leader.py +0 -497
- package/src/team_agent/messaging/leader_api_errors.py +0 -216
- package/src/team_agent/messaging/leader_panes.py +0 -673
- package/src/team_agent/messaging/owner_bypass.py +0 -29
- package/src/team_agent/messaging/result_delivery.py +0 -539
- package/src/team_agent/messaging/results.py +0 -447
- package/src/team_agent/messaging/scheduler.py +0 -450
- package/src/team_agent/messaging/send.py +0 -532
- package/src/team_agent/messaging/session_drift.py +0 -94
- package/src/team_agent/messaging/tmux_io.py +0 -506
- package/src/team_agent/messaging/tmux_prompt.py +0 -338
- package/src/team_agent/messaging/trust_auto_answer.py +0 -52
- package/src/team_agent/orchestrator/__init__.py +0 -376
- package/src/team_agent/orchestrator/plan.py +0 -122
- package/src/team_agent/orchestrator/state.py +0 -128
- package/src/team_agent/paths.py +0 -45
- package/src/team_agent/permissions.py +0 -123
- package/src/team_agent/profiles/__init__.py +0 -82
- package/src/team_agent/profiles/constants.py +0 -19
- package/src/team_agent/profiles/core.py +0 -407
- package/src/team_agent/profiles/helpers.py +0 -69
- package/src/team_agent/profiles/provider_env.py +0 -188
- package/src/team_agent/profiles/smoke.py +0 -201
- package/src/team_agent/provider_cli/__init__.py +0 -43
- package/src/team_agent/provider_cli/adapter.py +0 -172
- package/src/team_agent/provider_cli/base.py +0 -48
- package/src/team_agent/provider_cli/claude.py +0 -503
- package/src/team_agent/provider_cli/codex.py +0 -336
- package/src/team_agent/provider_cli/copilot.py +0 -8
- package/src/team_agent/provider_cli/fake.py +0 -39
- package/src/team_agent/provider_cli/gemini.py +0 -95
- package/src/team_agent/provider_cli/opencode.py +0 -8
- package/src/team_agent/provider_cli/prompt.py +0 -62
- package/src/team_agent/provider_cli/registry.py +0 -18
- package/src/team_agent/provider_cli/unsupported.py +0 -32
- package/src/team_agent/provider_state/README.md +0 -78
- package/src/team_agent/provider_state/__init__.py +0 -91
- package/src/team_agent/provider_state/claude.py +0 -86
- package/src/team_agent/provider_state/codex.py +0 -84
- package/src/team_agent/provider_state/common.py +0 -207
- package/src/team_agent/provider_state/registry.py +0 -118
- package/src/team_agent/providers.py +0 -163
- package/src/team_agent/quality_gates.py +0 -104
- package/src/team_agent/restart/__init__.py +0 -34
- package/src/team_agent/restart/orchestration.py +0 -554
- package/src/team_agent/restart/selection.py +0 -89
- package/src/team_agent/restart/snapshot.py +0 -70
- package/src/team_agent/routing.py +0 -84
- package/src/team_agent/runtime.py +0 -1243
- package/src/team_agent/rust_core.py +0 -327
- package/src/team_agent/sessions/__init__.py +0 -25
- package/src/team_agent/sessions/capture.py +0 -144
- package/src/team_agent/sessions/inventory.py +0 -44
- package/src/team_agent/sessions/resume.py +0 -135
- package/src/team_agent/simple_yaml.py +0 -236
- package/src/team_agent/spec.py +0 -370
- package/src/team_agent/state.py +0 -693
- package/src/team_agent/status/__init__.py +0 -63
- package/src/team_agent/status/approvals.py +0 -52
- package/src/team_agent/status/compact.py +0 -158
- package/src/team_agent/status/constants.py +0 -18
- package/src/team_agent/status/inbox.py +0 -58
- package/src/team_agent/status/peek.py +0 -117
- package/src/team_agent/status/queries.py +0 -199
- package/src/team_agent/task_graph.py +0 -80
- package/src/team_agent/terminal.py +0 -57
- package/src/team_agent/wake.py +0 -58
- package/src/team_agent/watch/__init__.py +0 -145
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
//! step 14a · mcp_server::types — wire enums / envelopes / normalized-result carriers.
|
|
2
|
+
|
|
3
|
+
use serde::{Deserialize, Serialize};
|
|
4
|
+
use serde_json::Value;
|
|
5
|
+
use thiserror::Error;
|
|
6
|
+
|
|
7
|
+
// ── REUSE: step 2 model (ids + normalized-envelope value enums) ─────────────
|
|
8
|
+
use crate::model::enums::{ChangeKind, ResultStatus, RiskSeverity, TestStatus};
|
|
9
|
+
use crate::model::ids::{AgentId, TaskId, TeamKey};
|
|
10
|
+
|
|
11
|
+
use super::helpers::tool_error_reason_wire;
|
|
12
|
+
|
|
13
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
14
|
+
// ERRORS — McpError is the server-level surface; ToolError is the wire envelope.
|
|
15
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
16
|
+
|
|
17
|
+
/// Server/handler-level error (lib boundary, `thiserror`). Distinct from the
|
|
18
|
+
/// per-tool wire envelope [`ToolError`]: this is for I/O / state / delegate
|
|
19
|
+
/// failures that propagate up through `Result`. `handle_mcp`'s `tools/call` path
|
|
20
|
+
/// converts a caught argument/runtime failure into a [`ToolError`] envelope rather
|
|
21
|
+
/// than an `McpError`, mirroring `server.py:69-72`.
|
|
22
|
+
#[derive(Debug, Error)]
|
|
23
|
+
pub enum McpError {
|
|
24
|
+
/// JSON parse of an stdin line failed (`json.loads` raise; surfaced on stdout
|
|
25
|
+
/// as a `-32000`/`-32700` frame per `server.py:135-149`).
|
|
26
|
+
#[error("json: {0}")]
|
|
27
|
+
Json(#[from] serde_json::Error),
|
|
28
|
+
/// State read/write failed (delegated to step 5 persist).
|
|
29
|
+
#[error("state: {0}")]
|
|
30
|
+
State(#[from] crate::state::StateError),
|
|
31
|
+
/// Message store failed (delegated to step 7).
|
|
32
|
+
#[error("message_store: {0}")]
|
|
33
|
+
MessageStore(#[from] crate::message_store::MessageStoreError),
|
|
34
|
+
/// Event log append failed (delegated to step 4).
|
|
35
|
+
#[error("event_log: {0}")]
|
|
36
|
+
EventLog(#[from] crate::event_log::EventLogError),
|
|
37
|
+
/// A delegated messaging op failed (step 11).
|
|
38
|
+
#[error("messaging: {0}")]
|
|
39
|
+
Messaging(#[from] crate::messaging::MessagingError),
|
|
40
|
+
/// stdio transport I/O (read line / write frame / flush).
|
|
41
|
+
#[error("io: {0}")]
|
|
42
|
+
Io(#[from] std::io::Error),
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
46
|
+
// WIRE ENUMS (§19) —散字符串 → 穷尽 enum;契约字节级真相由这些派生。
|
|
47
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
48
|
+
|
|
49
|
+
/// The 12 MCP tool names (`server.py:19-43` if-chain = 字符串打地鼠). Exhaustive
|
|
50
|
+
/// match; unknown → [`ToolErrorReason::UnknownTool`]. [`tools_contract`] (the
|
|
51
|
+
/// `TOOLS` wire list returned by `tools/list`) MUST be derived from this enum so
|
|
52
|
+
/// name/inputSchema stay byte-identical to `contracts.py`.
|
|
53
|
+
///
|
|
54
|
+
/// [`tools_contract`]: super::tools_contract
|
|
55
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
56
|
+
#[serde(rename_all = "snake_case")]
|
|
57
|
+
pub enum McpTool {
|
|
58
|
+
AssignTask,
|
|
59
|
+
SendMessage,
|
|
60
|
+
ReportResult,
|
|
61
|
+
UpdateState,
|
|
62
|
+
GetTeamStatus,
|
|
63
|
+
StopAgent,
|
|
64
|
+
ResetAgent,
|
|
65
|
+
AddAgent,
|
|
66
|
+
ForkAgent,
|
|
67
|
+
RequestHuman,
|
|
68
|
+
StuckList,
|
|
69
|
+
StuckCancel,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
impl McpTool {
|
|
73
|
+
/// Wire name (`assign_task` … `stuck_cancel`) — the byte-stable string used in
|
|
74
|
+
/// `tools/list` and `tools/call`. Parse failure ⇒ [`ToolErrorReason::UnknownTool`].
|
|
75
|
+
pub fn wire_name(self) -> &'static str {
|
|
76
|
+
match self {
|
|
77
|
+
McpTool::AssignTask => "assign_task",
|
|
78
|
+
McpTool::SendMessage => "send_message",
|
|
79
|
+
McpTool::ReportResult => "report_result",
|
|
80
|
+
McpTool::UpdateState => "update_state",
|
|
81
|
+
McpTool::GetTeamStatus => "get_team_status",
|
|
82
|
+
McpTool::StopAgent => "stop_agent",
|
|
83
|
+
McpTool::ResetAgent => "reset_agent",
|
|
84
|
+
McpTool::AddAgent => "add_agent",
|
|
85
|
+
McpTool::ForkAgent => "fork_agent",
|
|
86
|
+
McpTool::RequestHuman => "request_human",
|
|
87
|
+
McpTool::StuckList => "stuck_list",
|
|
88
|
+
McpTool::StuckCancel => "stuck_cancel",
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/// Parse a wire tool name into the enum; `None` for an unknown tool (caller maps
|
|
93
|
+
/// to [`ToolErrorReason::UnknownTool`], matching `server.py:43`).
|
|
94
|
+
pub fn parse(name: &str) -> Option<Self> {
|
|
95
|
+
match name {
|
|
96
|
+
"assign_task" => Some(McpTool::AssignTask),
|
|
97
|
+
"send_message" => Some(McpTool::SendMessage),
|
|
98
|
+
"report_result" => Some(McpTool::ReportResult),
|
|
99
|
+
"update_state" => Some(McpTool::UpdateState),
|
|
100
|
+
"get_team_status" => Some(McpTool::GetTeamStatus),
|
|
101
|
+
"stop_agent" => Some(McpTool::StopAgent),
|
|
102
|
+
"reset_agent" => Some(McpTool::ResetAgent),
|
|
103
|
+
"add_agent" => Some(McpTool::AddAgent),
|
|
104
|
+
"fork_agent" => Some(McpTool::ForkAgent),
|
|
105
|
+
"request_human" => Some(McpTool::RequestHuman),
|
|
106
|
+
"stuck_list" => Some(McpTool::StuckList),
|
|
107
|
+
"stuck_cancel" => Some(McpTool::StuckCancel),
|
|
108
|
+
_ => None,
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/// JSON-RPC method (`server.py:46-91`). `notifications/*` → no reply; unknown →
|
|
114
|
+
/// `-32601`.
|
|
115
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
116
|
+
pub enum RpcMethod {
|
|
117
|
+
Initialize,
|
|
118
|
+
ToolsList,
|
|
119
|
+
ToolsCall,
|
|
120
|
+
/// `notifications/<rest>` — [`handle_mcp`] returns `None`, loop continues.
|
|
121
|
+
///
|
|
122
|
+
/// [`handle_mcp`]: super::handle_mcp
|
|
123
|
+
Notification(String),
|
|
124
|
+
/// Anything else → `-32601 unknown method`.
|
|
125
|
+
Unknown(String),
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
impl RpcMethod {
|
|
129
|
+
/// Classify a raw `method` string (`server.py:47-49,87`). `notifications/foo` →
|
|
130
|
+
/// `Notification("foo")` (or full suffix); empty/absent handled by the caller.
|
|
131
|
+
pub fn classify(method: &str) -> Self {
|
|
132
|
+
match method {
|
|
133
|
+
"initialize" => RpcMethod::Initialize,
|
|
134
|
+
"tools/list" => RpcMethod::ToolsList,
|
|
135
|
+
"tools/call" => RpcMethod::ToolsCall,
|
|
136
|
+
m if m.starts_with("notifications/") => {
|
|
137
|
+
RpcMethod::Notification(m.trim_start_matches("notifications/").to_string())
|
|
138
|
+
}
|
|
139
|
+
other => RpcMethod::Unknown(other.to_string()),
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/// Tool error reason (`server.py:43,69-72`, `tools.py:211`). `reason == error_code`
|
|
145
|
+
/// in the wire envelope; this also maps to the JSON-RPC code on the non-tool path.
|
|
146
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
147
|
+
#[serde(rename_all = "snake_case")]
|
|
148
|
+
pub enum ToolErrorReason {
|
|
149
|
+
/// Unknown tool name in `dispatch` (`server.py:43`).
|
|
150
|
+
UnknownTool,
|
|
151
|
+
/// `TypeError/ValueError/KeyError/AttributeError` caught (`server.py:69-70`).
|
|
152
|
+
InvalidToolArguments,
|
|
153
|
+
/// Any other exception caught (`server.py:71-72`).
|
|
154
|
+
InternalRuntimeError,
|
|
155
|
+
/// Cross-team peer addressed without `scope="workspace"` (`tools.py:211`).
|
|
156
|
+
PeerNotInScope,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/// Send scope (`tools.py:165-173`). `Workspace` is the only cross-team opt-in;
|
|
160
|
+
/// absent/`team` resolves to the spawn-time owner team. The `scope` field on
|
|
161
|
+
/// `mcp.scope_resolved` is one of these.
|
|
162
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
163
|
+
#[serde(rename_all = "snake_case")]
|
|
164
|
+
pub enum Scope {
|
|
165
|
+
Team,
|
|
166
|
+
Workspace,
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
170
|
+
// WIRE ENVELOPES (byte-stable) — request/response + tool result/error.
|
|
171
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
172
|
+
|
|
173
|
+
/// A JSON-RPC request id: int, string, or null/absent (`request.get("id")`).
|
|
174
|
+
/// Serialized verbatim into the response `id` field.
|
|
175
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
176
|
+
#[serde(untagged)]
|
|
177
|
+
pub enum RpcId {
|
|
178
|
+
Int(i64),
|
|
179
|
+
Str(String),
|
|
180
|
+
Number(serde_json::Number),
|
|
181
|
+
/// `null` / absent — echoed back as `null`.
|
|
182
|
+
Null,
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/// A JSON-RPC 2.0 response frame (`server.py:52-91`). Exactly one of `result` /
|
|
186
|
+
/// `error` is set. `handle_mcp` returns `Option<RpcResponse>`; `None` ⇒
|
|
187
|
+
/// notifications path (no frame written).
|
|
188
|
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
189
|
+
pub struct RpcResponse {
|
|
190
|
+
/// Always `"2.0"`.
|
|
191
|
+
pub jsonrpc: String,
|
|
192
|
+
pub id: RpcId,
|
|
193
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
194
|
+
pub result: Option<Value>,
|
|
195
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
196
|
+
pub error: Option<RpcError>,
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/// JSON-RPC error object (`server.py:90,142`). `-32601` unknown method, `-32000`
|
|
200
|
+
/// stdin-loop catch-all, `-32700` parse error.
|
|
201
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
202
|
+
pub struct RpcError {
|
|
203
|
+
pub code: i64,
|
|
204
|
+
pub message: String,
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/// The `tools/call` result wrapper (`server.py:74-86`): `{content:[{type:"text",
|
|
208
|
+
/// text:<json>}], isError:<bool>}`. `text` is the JSON-encoded [`ToolResult`]; the
|
|
209
|
+
/// `is_error` flag mirrors `result.get("ok") is False`.
|
|
210
|
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
211
|
+
pub struct ToolCallResult {
|
|
212
|
+
pub content: Vec<ToolCallContent>,
|
|
213
|
+
#[serde(rename = "isError")]
|
|
214
|
+
pub is_error: bool,
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/// One `content[]` block — always `{type:"text", text:<json>}` here.
|
|
218
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
219
|
+
pub struct ToolCallContent {
|
|
220
|
+
#[serde(rename = "type")]
|
|
221
|
+
pub kind: String,
|
|
222
|
+
pub text: String,
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/// A successful tool result body — the compacted delegate result
|
|
226
|
+
/// (`normalize._compact_tool_result`, `normalize.py:6-64`). The whitelist-key
|
|
227
|
+
/// compaction (ok/error key sets + `fanout_*` extras + `acknowledged_count`) lives
|
|
228
|
+
/// in [`compact_tool_result`]; this struct carries the post-compaction object.
|
|
229
|
+
/// `ok` defaults to `true` (an empty compaction yields `{"ok": true}`).
|
|
230
|
+
///
|
|
231
|
+
/// [`compact_tool_result`]: super::compact_tool_result
|
|
232
|
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
233
|
+
pub struct ToolOk {
|
|
234
|
+
/// The compacted, byte-stable result object (whitelist keys only).
|
|
235
|
+
#[serde(flatten)]
|
|
236
|
+
pub fields: serde_json::Map<String, Value>,
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/// The tool error envelope (`server.py:98-106`). **Redundant keys are load-bearing**:
|
|
240
|
+
/// `reason == error_code` and `message == error` are byte-stable downstream
|
|
241
|
+
/// contracts and MUST be serialized verbatim (not deduped). `ok` is always `false`.
|
|
242
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
243
|
+
pub struct ToolError {
|
|
244
|
+
/// The reason; serialized into BOTH `reason` and `error_code`.
|
|
245
|
+
pub reason: ToolErrorReason,
|
|
246
|
+
/// Exception class name (`exc_type`): `"UnknownTool"`, `"ValueError"`, …
|
|
247
|
+
/// Public-message scrub (`_public_exception_message`, ≤200 chars, newlines → space).
|
|
248
|
+
pub exc_type: String,
|
|
249
|
+
/// The public message; serialized into BOTH `message` and `error`.
|
|
250
|
+
pub message: String,
|
|
251
|
+
/// Extra envelope keys (e.g. the `_refuse_cross_team_peer` `status:"refused"` +
|
|
252
|
+
/// `hint`, `tools.py:208-213`) preserved alongside the canonical keys.
|
|
253
|
+
pub extra: serde_json::Map<String, Value>,
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
impl ToolError {
|
|
257
|
+
/// Build the `{ok:false, reason, error_code, exc_type, message, error, **extra}`
|
|
258
|
+
/// JSON object with the redundant keys filled byte-for-byte (`server.py:98-106`).
|
|
259
|
+
pub fn to_envelope(&self) -> Value {
|
|
260
|
+
let reason = tool_error_reason_wire(self.reason);
|
|
261
|
+
let mut obj = serde_json::Map::new();
|
|
262
|
+
obj.insert("ok".to_string(), Value::Bool(false));
|
|
263
|
+
obj.insert("reason".to_string(), Value::String(reason.to_string()));
|
|
264
|
+
obj.insert("error_code".to_string(), Value::String(reason.to_string()));
|
|
265
|
+
obj.insert("exc_type".to_string(), Value::String(self.exc_type.clone()));
|
|
266
|
+
obj.insert("message".to_string(), Value::String(self.message.clone()));
|
|
267
|
+
obj.insert("error".to_string(), Value::String(self.message.clone()));
|
|
268
|
+
for (k, v) in &self.extra {
|
|
269
|
+
obj.insert(k.clone(), v.clone());
|
|
270
|
+
}
|
|
271
|
+
Value::Object(obj)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/// `_tool_error_result(reason, message, exc_type)` (`server.py:98-106`) for the
|
|
275
|
+
/// `unknown_tool` / `peer_not_in_scope` non-exception paths.
|
|
276
|
+
pub fn new(reason: ToolErrorReason, message: impl Into<String>, exc_type: impl Into<String>) -> Self {
|
|
277
|
+
Self {
|
|
278
|
+
reason,
|
|
279
|
+
exc_type: exc_type.into(),
|
|
280
|
+
message: message.into(),
|
|
281
|
+
extra: serde_json::Map::new(),
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/// `_public_exception_message(exc)` (`server.py:109-111`): strip newlines, trim,
|
|
286
|
+
/// truncate to 200 chars; empty → the exception type name.
|
|
287
|
+
pub fn public_exception_message(raw: &str, exc_type: &str) -> String {
|
|
288
|
+
let cleaned = raw.replace(['\n', '\r'], " ");
|
|
289
|
+
let trimmed = cleaned.trim();
|
|
290
|
+
let base = if trimmed.is_empty() { exc_type } else { trimmed };
|
|
291
|
+
base.chars().take(200).collect()
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/// A tool handler outcome (`dispatch` return). Maps to `result.get("ok") is False`:
|
|
296
|
+
/// `Ok` ⇒ `isError:false`, `Err(ToolError)` ⇒ `isError:true`. This is the
|
|
297
|
+
/// contract-callable shape — handlers below return it (or a richer typed wrapper).
|
|
298
|
+
pub type ToolResult = Result<ToolOk, ToolError>;
|
|
299
|
+
|
|
300
|
+
/// `send_message` outcome (`tools.py:176-183`). A worker recipient with a
|
|
301
|
+
/// message_id → async `accepted` carrying the byte-stable poll hint; leader / `*` /
|
|
302
|
+
/// broadcast → the compacted delegate result.
|
|
303
|
+
#[derive(Debug, Clone, PartialEq)]
|
|
304
|
+
pub enum SendOutcome {
|
|
305
|
+
/// `{status:"accepted", delivery_pending:true, poll_via:"team-agent inbox <id>",
|
|
306
|
+
/// message_id:<id>}` — worker recipient, `tools.py:177-182`.
|
|
307
|
+
WorkerAccepted {
|
|
308
|
+
message_id: String,
|
|
309
|
+
/// Byte-stable `"team-agent inbox <message_id>"`.
|
|
310
|
+
poll_via: String,
|
|
311
|
+
},
|
|
312
|
+
/// Compacted delegate result (leader / `*` / broadcast / fanout).
|
|
313
|
+
Direct(ToolOk),
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
impl SendOutcome {
|
|
317
|
+
/// Render the outcome into its wire JSON object (`tools.py:177-183`). Folds into
|
|
318
|
+
/// the [`ToolResult`] `Ok` body.
|
|
319
|
+
pub fn to_value(&self) -> Value {
|
|
320
|
+
match self {
|
|
321
|
+
SendOutcome::WorkerAccepted { message_id, poll_via } => {
|
|
322
|
+
let mut obj = serde_json::Map::new();
|
|
323
|
+
obj.insert("status".to_string(), Value::String("accepted".to_string()));
|
|
324
|
+
obj.insert("delivery_pending".to_string(), Value::Bool(true));
|
|
325
|
+
obj.insert("poll_via".to_string(), Value::String(poll_via.clone()));
|
|
326
|
+
obj.insert("message_id".to_string(), Value::String(message_id.clone()));
|
|
327
|
+
Value::Object(obj)
|
|
328
|
+
}
|
|
329
|
+
SendOutcome::Direct(ok) => Value::Object(ok.fields.clone()),
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
335
|
+
// NORMALIZED RESULT ENVELOPE (normalize.py:67-258) — typed carriers of the
|
|
336
|
+
// asserted values. Contracts call the normalize fns and assert these enums/structs.
|
|
337
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
338
|
+
|
|
339
|
+
/// A normalized result envelope (`_normalize_report_envelope`, `normalize.py:67-80`).
|
|
340
|
+
/// `schema_version` is fixed `"result_envelope_v1"`; `task_id`/`agent_id` fall back
|
|
341
|
+
/// to `"manual"`/`"unknown"`. `status` is the regularized [`ResultStatus`] (step 2).
|
|
342
|
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
343
|
+
pub struct NormalizedReportEnvelope {
|
|
344
|
+
pub schema_version: String,
|
|
345
|
+
pub task_id: TaskId,
|
|
346
|
+
pub agent_id: AgentId,
|
|
347
|
+
pub status: ResultStatus,
|
|
348
|
+
pub summary: String,
|
|
349
|
+
pub changes: Vec<NormalizedChange>,
|
|
350
|
+
pub tests: Vec<NormalizedTest>,
|
|
351
|
+
pub risks: Vec<NormalizedRisk>,
|
|
352
|
+
pub artifacts: Vec<NormalizedArtifact>,
|
|
353
|
+
pub next_actions: Vec<NormalizedNextAction>,
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/// `changes[]` (`normalize.py:126-142`): path + regularized [`ChangeKind`] +
|
|
357
|
+
/// description (falls back to the envelope summary).
|
|
358
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
359
|
+
pub struct NormalizedChange {
|
|
360
|
+
pub path: String,
|
|
361
|
+
pub kind: ChangeKind,
|
|
362
|
+
pub description: String,
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/// `tests[]` (`normalize.py:180-196`): command + regularized [`TestStatus`] +
|
|
366
|
+
/// optional detail.
|
|
367
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
368
|
+
pub struct NormalizedTest {
|
|
369
|
+
pub command: String,
|
|
370
|
+
pub status: TestStatus,
|
|
371
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
372
|
+
pub detail: Option<String>,
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/// `risks[]` (`normalize.py:215-230`): regularized [`RiskSeverity`] (out-of-set →
|
|
376
|
+
/// `Low`) + description.
|
|
377
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
378
|
+
pub struct NormalizedRisk {
|
|
379
|
+
pub severity: RiskSeverity,
|
|
380
|
+
pub description: String,
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/// `artifacts[]` (`normalize.py:233-245`): path + description (defaults to path).
|
|
384
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
385
|
+
pub struct NormalizedArtifact {
|
|
386
|
+
pub path: String,
|
|
387
|
+
pub description: String,
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/// `next_actions[]` (`normalize.py:248-257`): description only.
|
|
391
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
392
|
+
pub struct NormalizedNextAction {
|
|
393
|
+
pub description: String,
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/// `get_visible_peers` result (`tools.py:226-247`): the C16 scope-filtered peer list.
|
|
397
|
+
/// Other teams and dead/stopped agents are filtered server-side and never named.
|
|
398
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
399
|
+
pub struct VisiblePeers {
|
|
400
|
+
/// Sorted live peer ids within the sender's spawn-time owner-team scope.
|
|
401
|
+
pub peers: Vec<AgentId>,
|
|
402
|
+
/// The resolving team scope (`None` when no owner team env is set).
|
|
403
|
+
pub sender_team_id: Option<TeamKey>,
|
|
404
|
+
/// Always [`Scope::Team`] for this query.
|
|
405
|
+
pub scope: Scope,
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/// Summary of one stdio server run (`main`'s loop accounting) — frames in/out, the
|
|
409
|
+
/// notification skips, and whether the loop exited on EOF cleanly. Rich return so a
|
|
410
|
+
/// harness can assert the session shape without scraping stdout.
|
|
411
|
+
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
|
412
|
+
pub struct ServerRunReport {
|
|
413
|
+
pub requests_read: u64,
|
|
414
|
+
pub responses_written: u64,
|
|
415
|
+
/// `notifications/*` lines that produced no frame.
|
|
416
|
+
pub notifications_skipped: u64,
|
|
417
|
+
/// Lines that surfaced an error frame (parse / `-32000` / `-32601`).
|
|
418
|
+
pub error_frames: u64,
|
|
419
|
+
/// Clean EOF on stdin (`for line in sys.stdin` exhausted).
|
|
420
|
+
pub clean_eof: bool,
|
|
421
|
+
}
|