@team-agent/installer 0.5.42 → 0.5.44
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 +1 -1
- package/Cargo.toml +1 -1
- package/crates/team-agent/src/cli/adapters.rs +129 -54
- package/crates/team-agent/src/cli/diagnose.rs +1 -2
- package/crates/team-agent/src/cli/emit.rs +1 -7
- package/crates/team-agent/src/cli/helpers.rs +3 -1
- package/crates/team-agent/src/cli/leader.rs +2 -1
- package/crates/team-agent/src/cli/mod.rs +126 -16
- package/crates/team-agent/src/cli/named_address.rs +14 -5
- package/crates/team-agent/src/cli/profile.rs +19 -7
- package/crates/team-agent/src/cli/send.rs +9 -3
- package/crates/team-agent/src/cli/status.rs +8 -30
- package/crates/team-agent/src/cli/status_port.rs +1341 -1272
- package/crates/team-agent/src/cli/tests/base.rs +738 -660
- package/crates/team-agent/src/cli/tests/compile.rs +45 -18
- package/crates/team-agent/src/cli/tests/divergence.rs +462 -444
- package/crates/team-agent/src/cli/tests/lane_c.rs +365 -282
- package/crates/team-agent/src/cli/tests/leader_watch.rs +356 -329
- package/crates/team-agent/src/cli/tests/main_preserved.rs +672 -564
- package/crates/team-agent/src/cli/tests/missing_subcommands.rs +284 -224
- package/crates/team-agent/src/cli/tests/mod.rs +17 -7
- package/crates/team-agent/src/cli/tests/named_address.rs +8 -2
- package/crates/team-agent/src/cli/tests/peer_allow.rs +10 -2
- package/crates/team-agent/src/cli/tests/run_delegation.rs +314 -273
- package/crates/team-agent/src/cli/tests/shutdown_kill_plan.rs +26 -15
- package/crates/team-agent/src/cli/tests/status_send.rs +707 -629
- package/crates/team-agent/src/cli/tests/verb_install_skill.rs +20 -4
- package/crates/team-agent/src/cli/tests/verb_profile.rs +46 -17
- package/crates/team-agent/src/cli/tests/verb_validate.rs +15 -3
- package/crates/team-agent/src/codex_app_server.rs +2 -5
- package/crates/team-agent/src/compiler/tests.rs +139 -33
- package/crates/team-agent/src/compiler.rs +55 -22
- package/crates/team-agent/src/conpty/backend.rs +23 -33
- package/crates/team-agent/src/coordinator/backoff.rs +2 -7
- package/crates/team-agent/src/coordinator/conpty_shim.rs +55 -67
- package/crates/team-agent/src/coordinator/health.rs +46 -31
- package/crates/team-agent/src/coordinator/mod.rs +3 -3
- package/crates/team-agent/src/coordinator/orphan.rs +22 -10
- package/crates/team-agent/src/coordinator/steps/abnormal.rs +51 -56
- package/crates/team-agent/src/coordinator/tests/abnormal.rs +55 -19
- package/crates/team-agent/src/coordinator/tests/basics.rs +179 -41
- package/crates/team-agent/src/coordinator/tests/daemon.rs +53 -13
- package/crates/team-agent/src/coordinator/tests/health_sync.rs +78 -19
- package/crates/team-agent/src/coordinator/tests/main_preserved.rs +61 -11
- package/crates/team-agent/src/coordinator/tests/mod.rs +33 -39
- package/crates/team-agent/src/coordinator/tests/spine.rs +52 -12
- package/crates/team-agent/src/coordinator/tests/takeover.rs +73 -15
- package/crates/team-agent/src/coordinator/tests/tick_core.rs +50 -15
- package/crates/team-agent/src/coordinator/tests/watch.rs +74 -20
- package/crates/team-agent/src/db/message_store.rs +138 -30
- package/crates/team-agent/src/db/migration.rs +249 -61
- package/crates/team-agent/src/db/schema.rs +303 -82
- package/crates/team-agent/src/diagnose/comms.rs +9 -2
- package/crates/team-agent/src/diagnose/mod.rs +1 -3
- package/crates/team-agent/src/diagnose/orphans.rs +79 -61
- package/crates/team-agent/src/event_log.rs +70 -16
- package/crates/team-agent/src/layout/manager.rs +15 -4
- package/crates/team-agent/src/layout/mod.rs +4 -4
- package/crates/team-agent/src/layout/overlay.rs +10 -3
- package/crates/team-agent/src/layout/placement.rs +5 -1
- package/crates/team-agent/src/layout/recovery.rs +4 -2
- package/crates/team-agent/src/layout/runtime_sessions.rs +7 -7
- package/crates/team-agent/src/layout/sessions.rs +17 -9
- package/crates/team-agent/src/layout/tmux_endpoint.rs +1 -1
- package/crates/team-agent/src/layout/worker_env.rs +87 -19
- package/crates/team-agent/src/leader/helpers.rs +7 -1
- package/crates/team-agent/src/leader/lease.rs +199 -89
- package/crates/team-agent/src/leader/owner_bind.rs +55 -22
- package/crates/team-agent/src/leader/provider_attribution.rs +25 -6
- package/crates/team-agent/src/leader/rediscover/tests.rs +88 -24
- package/crates/team-agent/src/leader/rediscover.rs +74 -25
- package/crates/team-agent/src/leader/registry.rs +1 -1
- package/crates/team-agent/src/leader/start.rs +75 -54
- package/crates/team-agent/src/leader/takeover.rs +46 -11
- package/crates/team-agent/src/leader/tests/basics.rs +320 -167
- package/crates/team-agent/src/leader/tests/byte_findings.rs +361 -219
- package/crates/team-agent/src/leader/tests/identity.rs +428 -356
- package/crates/team-agent/src/leader/tests/idle.rs +285 -254
- package/crates/team-agent/src/leader/tests/lease_api.rs +338 -274
- package/crates/team-agent/src/leader/tests/lease_claim.rs +643 -593
- package/crates/team-agent/src/leader/tests/mod.rs +115 -99
- package/crates/team-agent/src/leader/tests/rediscover.rs +74 -22
- package/crates/team-agent/src/leader/tests/wake_start_owner.rs +237 -211
- package/crates/team-agent/src/lib.rs +4 -4
- package/crates/team-agent/src/lifecycle/display.rs +7 -3
- package/crates/team-agent/src/lifecycle/launch.rs +55 -15
- package/crates/team-agent/src/lifecycle/mod.rs +9 -1
- package/crates/team-agent/src/lifecycle/profile_launch.rs +77 -34
- package/crates/team-agent/src/lifecycle/profile_smoke.rs +3 -1
- package/crates/team-agent/src/lifecycle/restart/agent.rs +1 -6
- package/crates/team-agent/src/lifecycle/restart/common.rs +6 -2
- package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +1 -4
- package/crates/team-agent/src/lifecycle/restart/preflight.rs +6 -5
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +26 -22
- package/crates/team-agent/src/lifecycle/restart/remove.rs +45 -35
- package/crates/team-agent/src/lifecycle/restart/team_state.rs +63 -17
- package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +251 -84
- package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +198 -48
- package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +2 -1
- package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +152 -32
- package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +1 -5
- package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +3 -0
- package/crates/team-agent/src/lifecycle/tests.rs +2 -2
- package/crates/team-agent/src/main.rs +4 -4
- package/crates/team-agent/src/mcp_server/lifecycle_tools/agent_ops.rs +47 -20
- package/crates/team-agent/src/mcp_server/mod.rs +11 -2
- package/crates/team-agent/src/mcp_server/types.rs +14 -3
- package/crates/team-agent/src/mcp_server/wire.rs +230 -68
- package/crates/team-agent/src/messaging/delivery.rs +20 -18
- package/crates/team-agent/src/messaging/helpers.rs +25 -4
- package/crates/team-agent/src/messaging/leader_receiver.rs +4 -5
- package/crates/team-agent/src/messaging/mod.rs +2 -3
- package/crates/team-agent/src/messaging/selftest.rs +46 -26
- package/crates/team-agent/src/messaging/tests/main_preserved.rs +47 -12
- package/crates/team-agent/src/messaging/tests/runtime.rs +57 -22
- package/crates/team-agent/src/messaging/tests/spine.rs +154 -40
- package/crates/team-agent/src/messaging/tests/wave2.rs +31 -32
- package/crates/team-agent/src/messaging/trust.rs +25 -2
- package/crates/team-agent/src/messaging/watchers.rs +37 -9
- package/crates/team-agent/src/model/enums.rs +65 -16
- package/crates/team-agent/src/model/ids.rs +12 -3
- package/crates/team-agent/src/model/paths.rs +28 -7
- package/crates/team-agent/src/model/permissions.rs +176 -33
- package/crates/team-agent/src/model/routing.rs +66 -20
- package/crates/team-agent/src/model/spec.rs +365 -69
- package/crates/team-agent/src/model/task_graph.rs +36 -9
- package/crates/team-agent/src/model/yaml/tests.rs +24 -6
- package/crates/team-agent/src/model/yaml.rs +7 -6
- package/crates/team-agent/src/packaging/install.rs +23 -9
- package/crates/team-agent/src/packaging/migrate.rs +5 -7
- package/crates/team-agent/src/packaging/mod.rs +9 -1
- package/crates/team-agent/src/packaging/repair.rs +13 -6
- package/crates/team-agent/src/packaging/tests.rs +63 -16
- package/crates/team-agent/src/packaging/types.rs +22 -7
- package/crates/team-agent/src/platform/argv.rs +4 -1
- package/crates/team-agent/src/platform/file_lock.rs +22 -8
- package/crates/team-agent/src/platform/process.rs +54 -24
- package/crates/team-agent/src/provider/adapters/claude.rs +1 -3
- package/crates/team-agent/src/provider/approvals/parsing.rs +134 -26
- package/crates/team-agent/src/provider/approvals/runtime_prompts.rs +13 -3
- package/crates/team-agent/src/provider/classify.rs +127 -42
- package/crates/team-agent/src/provider/faults.rs +17 -5
- package/crates/team-agent/src/provider/helpers.rs +6 -5
- package/crates/team-agent/src/provider/startup_prompt.rs +75 -27
- package/crates/team-agent/src/state/persist.rs +28 -0
- package/crates/team-agent/src/state/repository.rs +8 -3
- package/crates/team-agent/src/tmux_backend/tests.rs +1637 -1398
- package/crates/team-agent/src/tmux_backend.rs +80 -44
- package/crates/team-agent/src/topology.rs +40 -20
- package/crates/team-agent/src/transport/test_support.rs +20 -23
- package/crates/team-agent/src/transport/tests/behavior.rs +292 -293
- package/crates/team-agent/src/transport/tests/mod.rs +178 -187
- package/crates/team-agent/src/transport/tests/wire.rs +561 -525
- package/crates/team-agent/src/transport.rs +12 -17
- package/crates/team-agent/src/transport_factory.rs +29 -14
- package/package.json +4 -4
|
@@ -38,32 +38,86 @@ const INDEX_SQL: &[&str] = &[
|
|
|
38
38
|
|
|
39
39
|
// 各表 required 列(`schema.py` 的 *_COLUMNS 集合;此处用有序数组,成员判定与集合等价)。
|
|
40
40
|
const MESSAGE_COLUMNS: &[&str] = &[
|
|
41
|
-
"owner_team_id",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
41
|
+
"owner_team_id",
|
|
42
|
+
"message_id",
|
|
43
|
+
"task_id",
|
|
44
|
+
"sender",
|
|
45
|
+
"recipient",
|
|
46
|
+
"reply_to",
|
|
47
|
+
"requires_ack",
|
|
48
|
+
"status",
|
|
49
|
+
"content",
|
|
50
|
+
"artifact_refs",
|
|
51
|
+
"created_at",
|
|
52
|
+
"updated_at",
|
|
53
|
+
"delivered_at",
|
|
54
|
+
"acknowledged_at",
|
|
55
|
+
"error",
|
|
56
|
+
"delivery_attempts",
|
|
57
|
+
];
|
|
58
|
+
const RESULT_COLUMNS: &[&str] = &[
|
|
59
|
+
"owner_team_id",
|
|
60
|
+
"result_id",
|
|
61
|
+
"task_id",
|
|
62
|
+
"agent_id",
|
|
63
|
+
"envelope",
|
|
64
|
+
"status",
|
|
65
|
+
"created_at",
|
|
44
66
|
];
|
|
45
|
-
const RESULT_COLUMNS: &[&str] =
|
|
46
|
-
&["owner_team_id", "result_id", "task_id", "agent_id", "envelope", "status", "created_at"];
|
|
47
67
|
const SCHEDULED_EVENT_COLUMNS: &[&str] = &[
|
|
48
|
-
"id",
|
|
49
|
-
"
|
|
68
|
+
"id",
|
|
69
|
+
"owner_team_id",
|
|
70
|
+
"due_at",
|
|
71
|
+
"target",
|
|
72
|
+
"kind",
|
|
73
|
+
"payload_json",
|
|
74
|
+
"status",
|
|
75
|
+
"created_at",
|
|
76
|
+
"fired_at",
|
|
77
|
+
"result_json",
|
|
50
78
|
];
|
|
51
79
|
const DELIVERY_TOKEN_COLUMNS: &[&str] = &[
|
|
52
|
-
"message_id",
|
|
80
|
+
"message_id",
|
|
81
|
+
"unique_token",
|
|
82
|
+
"injected_at",
|
|
83
|
+
"visible_at",
|
|
84
|
+
"consumed_at",
|
|
85
|
+
"failed_at",
|
|
53
86
|
"failure_reason",
|
|
54
87
|
];
|
|
55
88
|
const AGENT_HEALTH_COLUMNS: &[&str] = &[
|
|
56
|
-
"owner_team_id",
|
|
89
|
+
"owner_team_id",
|
|
90
|
+
"agent_id",
|
|
91
|
+
"status",
|
|
92
|
+
"last_output_at",
|
|
93
|
+
"context_usage_pct",
|
|
94
|
+
"current_task_id",
|
|
57
95
|
"updated_at",
|
|
58
96
|
];
|
|
59
97
|
const PEER_ALLOWLIST_COLUMNS: &[&str] = &["a", "b", "created_at"];
|
|
60
98
|
const RESULT_WATCHER_COLUMNS: &[&str] = &[
|
|
61
|
-
"owner_team_id",
|
|
62
|
-
"
|
|
99
|
+
"owner_team_id",
|
|
100
|
+
"watcher_id",
|
|
101
|
+
"task_id",
|
|
102
|
+
"agent_id",
|
|
103
|
+
"message_id",
|
|
104
|
+
"leader_id",
|
|
105
|
+
"status",
|
|
106
|
+
"created_at",
|
|
107
|
+
"completed_at",
|
|
108
|
+
"result_id",
|
|
109
|
+
"notified_message_id",
|
|
110
|
+
"error",
|
|
63
111
|
];
|
|
64
112
|
const LEADER_NOTIFICATION_LOG_COLUMNS: &[&str] = &[
|
|
65
|
-
"result_id",
|
|
66
|
-
"
|
|
113
|
+
"result_id",
|
|
114
|
+
"owner_team_id",
|
|
115
|
+
"owner_epoch",
|
|
116
|
+
"leader_session_uuid",
|
|
117
|
+
"notified_message_id",
|
|
118
|
+
"notified_at",
|
|
119
|
+
"leader_pane_id_at_notify",
|
|
120
|
+
"envelope_content_hash",
|
|
67
121
|
];
|
|
68
122
|
|
|
69
123
|
/// 打开 `team.db` 并设 pragmas(`core.py:60-61`:busy_timeout=30000 + WAL)。
|
|
@@ -91,7 +145,9 @@ fn retry_sqlite<T>(mut op: impl FnMut() -> rusqlite::Result<T>) -> Result<T, DbE
|
|
|
91
145
|
}
|
|
92
146
|
match last_error {
|
|
93
147
|
Some(error) => Err(error.into()),
|
|
94
|
-
None => Err(DbError::Schema(
|
|
148
|
+
None => Err(DbError::Schema(
|
|
149
|
+
"sqlite retry exhausted without an error".to_string(),
|
|
150
|
+
)),
|
|
95
151
|
}
|
|
96
152
|
}
|
|
97
153
|
|
|
@@ -176,7 +232,10 @@ fn migrate_agent_health_owner_team_id(conn: &Connection) -> Result<(), DbError>
|
|
|
176
232
|
|
|
177
233
|
/// `schema.py:initialize_schema`:建表 + 列迁移 + agent_health 重建 + 索引 + user_version。
|
|
178
234
|
/// 一个事务内完成(对应 Python `with conn:`)。
|
|
179
|
-
pub fn initialize_schema(
|
|
235
|
+
pub fn initialize_schema(
|
|
236
|
+
conn: &Connection,
|
|
237
|
+
db_path: Option<&std::path::Path>,
|
|
238
|
+
) -> Result<(), DbError> {
|
|
180
239
|
// Gap 46 入口门(`schema.py:117`):先检测/修复物理列序漂移(legacy DB)。
|
|
181
240
|
// fresh DB 下 no-op(无 managed 表 → 无 diff);随后建表 + 列迁移在自己的事务里。
|
|
182
241
|
crate::db::migration::ensure_table_layout(conn, SCHEMA_VERSION, db_path)?;
|
|
@@ -197,18 +256,53 @@ pub fn initialize_schema(conn: &Connection, db_path: Option<&std::path::Path>) -
|
|
|
197
256
|
"messages",
|
|
198
257
|
MESSAGE_COLUMNS,
|
|
199
258
|
&[
|
|
200
|
-
(
|
|
201
|
-
|
|
259
|
+
(
|
|
260
|
+
"delivery_attempts",
|
|
261
|
+
"alter table messages add column delivery_attempts integer not null default 0",
|
|
262
|
+
),
|
|
263
|
+
(
|
|
264
|
+
"owner_team_id",
|
|
265
|
+
"alter table messages add column owner_team_id text",
|
|
266
|
+
),
|
|
202
267
|
],
|
|
203
268
|
)?;
|
|
204
|
-
ensure_table_columns(
|
|
205
|
-
|
|
269
|
+
ensure_table_columns(
|
|
270
|
+
&tx,
|
|
271
|
+
"results",
|
|
272
|
+
RESULT_COLUMNS,
|
|
273
|
+
&[(
|
|
274
|
+
"owner_team_id",
|
|
275
|
+
"alter table results add column owner_team_id text",
|
|
276
|
+
)],
|
|
277
|
+
)?;
|
|
278
|
+
ensure_table_columns(
|
|
279
|
+
&tx,
|
|
280
|
+
"scheduled_events",
|
|
281
|
+
SCHEDULED_EVENT_COLUMNS,
|
|
282
|
+
&[(
|
|
283
|
+
"owner_team_id",
|
|
284
|
+
"alter table scheduled_events add column owner_team_id text",
|
|
285
|
+
)],
|
|
286
|
+
)?;
|
|
206
287
|
ensure_table_columns(&tx, "delivery_tokens", DELIVERY_TOKEN_COLUMNS, &[])?;
|
|
207
288
|
migrate_agent_health_owner_team_id(&tx)?;
|
|
208
289
|
ensure_table_columns(&tx, "peer_allowlist", PEER_ALLOWLIST_COLUMNS, &[])?;
|
|
209
|
-
ensure_table_columns(
|
|
290
|
+
ensure_table_columns(
|
|
291
|
+
&tx,
|
|
292
|
+
"result_watchers",
|
|
293
|
+
RESULT_WATCHER_COLUMNS,
|
|
294
|
+
&[(
|
|
295
|
+
"owner_team_id",
|
|
296
|
+
"alter table result_watchers add column owner_team_id text",
|
|
297
|
+
)],
|
|
298
|
+
)?;
|
|
210
299
|
tx.execute(CREATE_LEADER_NOTIFICATION_LOG, [])?;
|
|
211
|
-
ensure_table_columns(
|
|
300
|
+
ensure_table_columns(
|
|
301
|
+
&tx,
|
|
302
|
+
"leader_notification_log",
|
|
303
|
+
LEADER_NOTIFICATION_LOG_COLUMNS,
|
|
304
|
+
&[],
|
|
305
|
+
)?;
|
|
212
306
|
ensure_schema_indexes(&tx)?;
|
|
213
307
|
tx.execute_batch(&format!("pragma user_version = {SCHEMA_VERSION}"))?;
|
|
214
308
|
tx.commit()?;
|
|
@@ -254,14 +348,17 @@ mod tests {
|
|
|
254
348
|
("results", "table"),
|
|
255
349
|
("scheduled_events", "table"),
|
|
256
350
|
];
|
|
257
|
-
let got_ref: Vec<(&str, &str)> =
|
|
351
|
+
let got_ref: Vec<(&str, &str)> =
|
|
352
|
+
got.iter().map(|(n, t)| (n.as_str(), t.as_str())).collect();
|
|
258
353
|
assert_eq!(got_ref, want);
|
|
259
354
|
}
|
|
260
355
|
|
|
261
356
|
#[test]
|
|
262
357
|
fn user_version_is_three() {
|
|
263
358
|
let conn = fresh();
|
|
264
|
-
let v: i64 = conn
|
|
359
|
+
let v: i64 = conn
|
|
360
|
+
.query_row("pragma user_version", [], |r| r.get(0))
|
|
361
|
+
.unwrap();
|
|
265
362
|
assert_eq!(v, SCHEMA_VERSION);
|
|
266
363
|
assert_eq!(v, 3);
|
|
267
364
|
}
|
|
@@ -272,9 +369,22 @@ mod tests {
|
|
|
272
369
|
assert_eq!(
|
|
273
370
|
table_layout(&conn, "messages").unwrap(),
|
|
274
371
|
vec![
|
|
275
|
-
"message_id",
|
|
276
|
-
"
|
|
277
|
-
"
|
|
372
|
+
"message_id",
|
|
373
|
+
"owner_team_id",
|
|
374
|
+
"task_id",
|
|
375
|
+
"sender",
|
|
376
|
+
"recipient",
|
|
377
|
+
"reply_to",
|
|
378
|
+
"requires_ack",
|
|
379
|
+
"status",
|
|
380
|
+
"content",
|
|
381
|
+
"artifact_refs",
|
|
382
|
+
"created_at",
|
|
383
|
+
"updated_at",
|
|
384
|
+
"delivered_at",
|
|
385
|
+
"acknowledged_at",
|
|
386
|
+
"error",
|
|
387
|
+
"delivery_attempts",
|
|
278
388
|
]
|
|
279
389
|
);
|
|
280
390
|
}
|
|
@@ -286,7 +396,11 @@ mod tests {
|
|
|
286
396
|
initialize_schema(&conn, None).unwrap();
|
|
287
397
|
assert_eq!(table_layout(&conn, "messages").unwrap().len(), 16);
|
|
288
398
|
let idx: i64 = conn
|
|
289
|
-
.query_row(
|
|
399
|
+
.query_row(
|
|
400
|
+
"select count(*) from sqlite_master where type='index' and sql is not null",
|
|
401
|
+
[],
|
|
402
|
+
|r| r.get(0),
|
|
403
|
+
)
|
|
290
404
|
.unwrap();
|
|
291
405
|
assert_eq!(idx, 6, "二次 init 后 6 个 named index 仍在");
|
|
292
406
|
}
|
|
@@ -296,51 +410,126 @@ mod tests {
|
|
|
296
410
|
fn per_column_table_info_all_eight_tables() {
|
|
297
411
|
type Col = (&'static str, &'static str, i64, Option<&'static str>, i64);
|
|
298
412
|
let golden: &[(&str, &[Col])] = &[
|
|
299
|
-
(
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
413
|
+
(
|
|
414
|
+
"messages",
|
|
415
|
+
&[
|
|
416
|
+
("message_id", "TEXT", 0, None, 1),
|
|
417
|
+
("owner_team_id", "TEXT", 0, None, 0),
|
|
418
|
+
("task_id", "TEXT", 0, None, 0),
|
|
419
|
+
("sender", "TEXT", 0, None, 0),
|
|
420
|
+
("recipient", "TEXT", 0, None, 0),
|
|
421
|
+
("reply_to", "TEXT", 0, None, 0),
|
|
422
|
+
("requires_ack", "INTEGER", 0, None, 0),
|
|
423
|
+
("status", "TEXT", 0, None, 0),
|
|
424
|
+
("content", "TEXT", 0, None, 0),
|
|
425
|
+
("artifact_refs", "TEXT", 0, None, 0),
|
|
426
|
+
("created_at", "TEXT", 0, None, 0),
|
|
427
|
+
("updated_at", "TEXT", 0, None, 0),
|
|
428
|
+
("delivered_at", "TEXT", 0, None, 0),
|
|
429
|
+
("acknowledged_at", "TEXT", 0, None, 0),
|
|
430
|
+
("error", "TEXT", 0, None, 0),
|
|
431
|
+
("delivery_attempts", "INTEGER", 1, Some("0"), 0),
|
|
432
|
+
],
|
|
433
|
+
),
|
|
434
|
+
(
|
|
435
|
+
"results",
|
|
436
|
+
&[
|
|
437
|
+
("result_id", "TEXT", 0, None, 1),
|
|
438
|
+
("owner_team_id", "TEXT", 0, None, 0),
|
|
439
|
+
("task_id", "TEXT", 1, None, 0),
|
|
440
|
+
("agent_id", "TEXT", 1, None, 0),
|
|
441
|
+
("envelope", "TEXT", 1, None, 0),
|
|
442
|
+
("status", "TEXT", 1, None, 0),
|
|
443
|
+
("created_at", "TEXT", 1, None, 0),
|
|
444
|
+
],
|
|
445
|
+
),
|
|
446
|
+
(
|
|
447
|
+
"scheduled_events",
|
|
448
|
+
&[
|
|
449
|
+
("id", "INTEGER", 0, None, 1),
|
|
450
|
+
("owner_team_id", "TEXT", 0, None, 0),
|
|
451
|
+
("due_at", "TEXT", 1, None, 0),
|
|
452
|
+
("target", "TEXT", 1, None, 0),
|
|
453
|
+
("kind", "TEXT", 1, None, 0),
|
|
454
|
+
("payload_json", "TEXT", 1, None, 0),
|
|
455
|
+
("status", "TEXT", 1, None, 0),
|
|
456
|
+
("created_at", "TEXT", 1, None, 0),
|
|
457
|
+
("fired_at", "TEXT", 0, None, 0),
|
|
458
|
+
("result_json", "TEXT", 0, None, 0),
|
|
459
|
+
],
|
|
460
|
+
),
|
|
461
|
+
(
|
|
462
|
+
"delivery_tokens",
|
|
463
|
+
&[
|
|
464
|
+
("message_id", "TEXT", 0, None, 1),
|
|
465
|
+
("unique_token", "TEXT", 1, None, 0),
|
|
466
|
+
("injected_at", "TEXT", 1, None, 0),
|
|
467
|
+
("visible_at", "TEXT", 0, None, 0),
|
|
468
|
+
("consumed_at", "TEXT", 0, None, 0),
|
|
469
|
+
("failed_at", "TEXT", 0, None, 0),
|
|
470
|
+
("failure_reason", "TEXT", 0, None, 0),
|
|
471
|
+
],
|
|
472
|
+
),
|
|
473
|
+
(
|
|
474
|
+
"agent_health",
|
|
475
|
+
&[
|
|
476
|
+
("owner_team_id", "TEXT", 0, None, 0),
|
|
477
|
+
("agent_id", "TEXT", 1, None, 0),
|
|
478
|
+
("status", "TEXT", 1, None, 0),
|
|
479
|
+
("last_output_at", "TEXT", 0, None, 0),
|
|
480
|
+
("context_usage_pct", "INTEGER", 0, None, 0),
|
|
481
|
+
("current_task_id", "TEXT", 0, None, 0),
|
|
482
|
+
("updated_at", "TEXT", 1, None, 0),
|
|
483
|
+
],
|
|
484
|
+
),
|
|
485
|
+
(
|
|
486
|
+
"peer_allowlist",
|
|
487
|
+
&[
|
|
488
|
+
("a", "TEXT", 1, None, 1),
|
|
489
|
+
("b", "TEXT", 1, None, 2),
|
|
490
|
+
("created_at", "TEXT", 1, None, 0),
|
|
491
|
+
],
|
|
492
|
+
),
|
|
493
|
+
(
|
|
494
|
+
"result_watchers",
|
|
495
|
+
&[
|
|
496
|
+
("watcher_id", "TEXT", 0, None, 1),
|
|
497
|
+
("owner_team_id", "TEXT", 0, None, 0),
|
|
498
|
+
("task_id", "TEXT", 0, None, 0),
|
|
499
|
+
("agent_id", "TEXT", 0, None, 0),
|
|
500
|
+
("message_id", "TEXT", 0, None, 0),
|
|
501
|
+
("leader_id", "TEXT", 1, None, 0),
|
|
502
|
+
("status", "TEXT", 1, None, 0),
|
|
503
|
+
("created_at", "TEXT", 1, None, 0),
|
|
504
|
+
("completed_at", "TEXT", 0, None, 0),
|
|
505
|
+
("result_id", "TEXT", 0, None, 0),
|
|
506
|
+
("notified_message_id", "TEXT", 0, None, 0),
|
|
507
|
+
("error", "TEXT", 0, None, 0),
|
|
508
|
+
],
|
|
509
|
+
),
|
|
510
|
+
(
|
|
511
|
+
"leader_notification_log",
|
|
512
|
+
&[
|
|
513
|
+
("result_id", "TEXT", 1, None, 1),
|
|
514
|
+
("owner_team_id", "TEXT", 1, Some("''"), 2),
|
|
515
|
+
("owner_epoch", "INTEGER", 1, Some("0"), 3),
|
|
516
|
+
("leader_session_uuid", "TEXT", 0, None, 0),
|
|
517
|
+
("notified_message_id", "TEXT", 1, None, 0),
|
|
518
|
+
("notified_at", "TEXT", 1, None, 0),
|
|
519
|
+
("leader_pane_id_at_notify", "TEXT", 0, None, 0),
|
|
520
|
+
("envelope_content_hash", "TEXT", 0, None, 0),
|
|
521
|
+
],
|
|
522
|
+
),
|
|
338
523
|
];
|
|
339
524
|
let conn = fresh();
|
|
340
525
|
for (table, cols) in golden {
|
|
341
|
-
let mut stmt = conn
|
|
526
|
+
let mut stmt = conn
|
|
527
|
+
.prepare(&format!("pragma table_info({table})"))
|
|
528
|
+
.unwrap();
|
|
342
529
|
let got: Vec<(String, String, i64, Option<String>, i64)> = stmt
|
|
343
|
-
.query_map([], |r|
|
|
530
|
+
.query_map([], |r| {
|
|
531
|
+
Ok((r.get(1)?, r.get(2)?, r.get(3)?, r.get(4)?, r.get(5)?))
|
|
532
|
+
})
|
|
344
533
|
.unwrap()
|
|
345
534
|
.collect::<Result<_, _>>()
|
|
346
535
|
.unwrap();
|
|
@@ -358,7 +547,9 @@ mod tests {
|
|
|
358
547
|
let mut stmt = conn.prepare("select name, sql from sqlite_master where type='index' and sql is not null order by name").unwrap();
|
|
359
548
|
let idx: Vec<(String, String)> = stmt
|
|
360
549
|
.query_map([], |r| Ok((r.get(0)?, r.get(1)?)))
|
|
361
|
-
.unwrap()
|
|
550
|
+
.unwrap()
|
|
551
|
+
.collect::<Result<_, _>>()
|
|
552
|
+
.unwrap();
|
|
362
553
|
let want: Vec<(&str, &str)> = vec![
|
|
363
554
|
("idx_agent_health_owner_team_id", "CREATE INDEX idx_agent_health_owner_team_id on agent_health(owner_team_id)"),
|
|
364
555
|
("idx_leader_notification_log_team_epoch", "CREATE INDEX idx_leader_notification_log_team_epoch on leader_notification_log(owner_team_id, owner_epoch, notified_at)"),
|
|
@@ -371,13 +562,26 @@ mod tests {
|
|
|
371
562
|
assert_eq!(got, want);
|
|
372
563
|
// 7 个 sqlite_autoindex(每个有 pk/unique 约束的表各一)。
|
|
373
564
|
let auto: Vec<String> = conn
|
|
374
|
-
.prepare(
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
565
|
+
.prepare(
|
|
566
|
+
"select name from sqlite_master where type='index' and sql is null order by name",
|
|
567
|
+
)
|
|
568
|
+
.unwrap()
|
|
569
|
+
.query_map([], |r| r.get(0))
|
|
570
|
+
.unwrap()
|
|
571
|
+
.collect::<Result<_, _>>()
|
|
572
|
+
.unwrap();
|
|
573
|
+
assert_eq!(
|
|
574
|
+
auto,
|
|
575
|
+
vec![
|
|
576
|
+
"sqlite_autoindex_agent_health_1",
|
|
577
|
+
"sqlite_autoindex_delivery_tokens_1",
|
|
578
|
+
"sqlite_autoindex_leader_notification_log_1",
|
|
579
|
+
"sqlite_autoindex_messages_1",
|
|
580
|
+
"sqlite_autoindex_peer_allowlist_1",
|
|
581
|
+
"sqlite_autoindex_result_watchers_1",
|
|
582
|
+
"sqlite_autoindex_results_1",
|
|
583
|
+
]
|
|
584
|
+
);
|
|
381
585
|
}
|
|
382
586
|
|
|
383
587
|
#[test]
|
|
@@ -388,9 +592,13 @@ mod tests {
|
|
|
388
592
|
let path = dir.join("team.db");
|
|
389
593
|
let _ = std::fs::remove_file(&path);
|
|
390
594
|
let conn = open_db(&path).unwrap();
|
|
391
|
-
let jm: String = conn
|
|
595
|
+
let jm: String = conn
|
|
596
|
+
.query_row("pragma journal_mode", [], |r| r.get(0))
|
|
597
|
+
.unwrap();
|
|
392
598
|
assert_eq!(jm.to_lowercase(), "wal");
|
|
393
|
-
let bt: i64 = conn
|
|
599
|
+
let bt: i64 = conn
|
|
600
|
+
.query_row("pragma busy_timeout", [], |r| r.get(0))
|
|
601
|
+
.unwrap();
|
|
394
602
|
assert_eq!(bt, 30000);
|
|
395
603
|
}
|
|
396
604
|
|
|
@@ -398,13 +606,26 @@ mod tests {
|
|
|
398
606
|
fn ensure_table_columns_unsupported_missing_errors_with_sorted_names() {
|
|
399
607
|
// results 只建了 result_id → 缺 owner_team_id(有 migration)+ 其余(无 migration,unsupported)。
|
|
400
608
|
let conn = Connection::open_in_memory().unwrap();
|
|
401
|
-
conn.execute("create table results (result_id text primary key)", [])
|
|
609
|
+
conn.execute("create table results (result_id text primary key)", [])
|
|
610
|
+
.unwrap();
|
|
402
611
|
let err = ensure_table_columns(
|
|
403
612
|
&conn,
|
|
404
613
|
"results",
|
|
405
|
-
&[
|
|
406
|
-
|
|
407
|
-
|
|
614
|
+
&[
|
|
615
|
+
"owner_team_id",
|
|
616
|
+
"result_id",
|
|
617
|
+
"task_id",
|
|
618
|
+
"agent_id",
|
|
619
|
+
"envelope",
|
|
620
|
+
"status",
|
|
621
|
+
"created_at",
|
|
622
|
+
],
|
|
623
|
+
&[(
|
|
624
|
+
"owner_team_id",
|
|
625
|
+
"alter table results add column owner_team_id text",
|
|
626
|
+
)],
|
|
627
|
+
)
|
|
628
|
+
.unwrap_err();
|
|
408
629
|
assert_eq!(
|
|
409
630
|
err.to_string(),
|
|
410
631
|
"schema: team.db table results is missing required column(s): agent_id, created_at, envelope, status, task_id"
|
|
@@ -96,7 +96,10 @@ fn receiver_binding_snapshot(workspace: &Path, team: Option<&TeamKey>) -> Value
|
|
|
96
96
|
.or_else(|| crate::state::ownership::read_owner_value(&state, "").cloned())
|
|
97
97
|
.and_then(|v| v.get("pane_id").cloned())
|
|
98
98
|
.unwrap_or(Value::Null);
|
|
99
|
-
let caller_pane_id = std::env::var("TMUX_PANE")
|
|
99
|
+
let caller_pane_id = std::env::var("TMUX_PANE")
|
|
100
|
+
.ok()
|
|
101
|
+
.map(Value::String)
|
|
102
|
+
.unwrap_or(Value::Null);
|
|
100
103
|
let pane_id = receiver
|
|
101
104
|
.and_then(|r| r.get("pane_id"))
|
|
102
105
|
.cloned()
|
|
@@ -140,7 +143,11 @@ fn receiver_binding_snapshot(workspace: &Path, team: Option<&TeamKey>) -> Value
|
|
|
140
143
|
fn receiver_pane_stale(socket: &str, pane_id: &str) -> bool {
|
|
141
144
|
crate::tmux_backend::TmuxBackend::for_tmux_endpoint(socket)
|
|
142
145
|
.list_targets()
|
|
143
|
-
.map(|targets|
|
|
146
|
+
.map(|targets| {
|
|
147
|
+
!targets
|
|
148
|
+
.iter()
|
|
149
|
+
.any(|target| target.pane_id.as_str() == pane_id)
|
|
150
|
+
})
|
|
144
151
|
.unwrap_or(true)
|
|
145
152
|
}
|
|
146
153
|
|