@team-agent/installer 0.5.54 → 0.5.55

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 CHANGED
@@ -575,7 +575,7 @@ dependencies = [
575
575
 
576
576
  [[package]]
577
577
  name = "team-agent"
578
- version = "0.5.54"
578
+ version = "0.5.55"
579
579
  dependencies = [
580
580
  "anyhow",
581
581
  "chrono",
package/Cargo.toml CHANGED
@@ -9,7 +9,7 @@ members = ["crates/team-agent", "crates/win-conpty-phase0", "crates/conpty-trans
9
9
 
10
10
  [workspace.package]
11
11
  edition = "2021"
12
- version = "0.5.54"
12
+ version = "0.5.55"
13
13
  license = "AGPL-3.0"
14
14
  rust-version = "1.95"
15
15
 
@@ -3208,6 +3208,72 @@ fn gate054_rebind_replay_requeues_failed_leader_message_on_attach() {
3208
3208
  );
3209
3209
  }
3210
3210
 
3211
+ #[test]
3212
+ fn claim_requeues_pending_acceptance_for_leader_only() {
3213
+ let ws = tmp_ws("claim-pending-acceptance");
3214
+ let store = store_for(&ws);
3215
+ let log = EventLog::new(&ws);
3216
+ let team_id = "mailbox-team";
3217
+ let leader_message = store
3218
+ .create_message(
3219
+ None,
3220
+ "worker",
3221
+ "leader",
3222
+ "leader canary",
3223
+ None,
3224
+ false,
3225
+ Some(team_id),
3226
+ )
3227
+ .unwrap();
3228
+ let worker_message = store
3229
+ .create_message(
3230
+ None,
3231
+ "worker",
3232
+ "worker-b",
3233
+ "worker canary",
3234
+ None,
3235
+ false,
3236
+ Some(team_id),
3237
+ )
3238
+ .unwrap();
3239
+ let conn = crate::db::schema::open_db(store.db_path()).unwrap();
3240
+ for message_id in [&leader_message, &worker_message] {
3241
+ conn.execute(
3242
+ "update messages set status = 'submitted_pending_acceptance' where message_id = ?1",
3243
+ [message_id],
3244
+ )
3245
+ .unwrap();
3246
+ }
3247
+
3248
+ let team = TeamKey::new(team_id);
3249
+ let pane = PaneId::new("%leader");
3250
+ requeue_after_claim_leader(&ws, &store, &log, &team, &pane, None).unwrap();
3251
+
3252
+ let row = |message_id: &str| {
3253
+ conn.query_row(
3254
+ "select status, delivered_at, error from messages where message_id = ?1",
3255
+ [message_id],
3256
+ |row| {
3257
+ Ok((
3258
+ row.get::<_, String>(0)?,
3259
+ row.get::<_, Option<String>>(1)?,
3260
+ row.get::<_, Option<String>>(2)?,
3261
+ ))
3262
+ },
3263
+ )
3264
+ .unwrap()
3265
+ };
3266
+ assert_eq!(row(&leader_message), ("accepted".to_string(), None, None));
3267
+ assert_eq!(
3268
+ row(&worker_message),
3269
+ (
3270
+ "submitted_pending_acceptance".to_string(),
3271
+ None,
3272
+ None
3273
+ )
3274
+ );
3275
+ }
3276
+
3211
3277
  #[test]
3212
3278
  fn gate054_status_surfaces_pending_leader_notifications() {
3213
3279
  // Round-2: user-facing visibility — status must show the blocked leader
@@ -470,12 +470,13 @@ pub fn requeue_after_claim_leader(
470
470
  /// 0.5.5 gate054 round-2: attach-leader (and claim-leader) requeue for leader messages
471
471
  /// that were refused with `rebind_required` while no leader pane was attached.
472
472
  ///
473
- /// #231 C-5 semantics: same row, same message_id — flip `status` back from
474
- /// `failed`/`leader_not_attached` to `accepted` so `deliver_pending_messages`
475
- /// replays it through the SAME pipeline. The `leader_notification_log` PK is
476
- /// already there (primitive wrote it before the unbound check), so this replay
477
- /// cannot create a duplicate notification exactly-once across rebind, no new
478
- /// send/notify rows and no second replay mechanism.
473
+ /// #231 C-5 semantics: same row, same message_id — flip an eligible status back
474
+ /// to `accepted` so `deliver_pending_messages` replays it through the SAME
475
+ /// pipeline. The `leader_notification_log` PK prevents a second notification
476
+ /// row for watcher-backed messages. A `submitted_pending_acceptance` row has
477
+ /// already crossed the transport boundary, so its recovery is intentionally
478
+ /// at-least-once: the stable message id/receipt token is preserved, but a replay
479
+ /// can repeat the physical submit if a same-pane claim races the receipt window.
479
480
  pub(crate) fn requeue_blocked_leader_messages(
480
481
  conn: &rusqlite::Connection,
481
482
  event_log: &EventLog,
@@ -489,7 +490,10 @@ pub(crate) fn requeue_blocked_leader_messages(
489
490
  // `deliver_pending_messages` picks them up as `accepted` and injects
490
491
  // exactly once. status `queued_until_leader_attach` is deliberately NOT
491
492
  // in the `claim_for_delivery` eligible set (see message_store.rs) so it
492
- // could not have churned while the leader was unattached.
493
+ // could not have churned while the leader was unattached. In contrast,
494
+ // `submitted_pending_acceptance` is an explicit at-least-once recovery arm:
495
+ // claim convergence favors an eventual receipt over preserving an
496
+ // unobservable in-flight submit.
493
497
  let requeued = conn.execute(
494
498
  "update messages
495
499
  set status = 'accepted',
@@ -500,6 +504,7 @@ pub(crate) fn requeue_blocked_leader_messages(
500
504
  and (
501
505
  (status = 'failed' and error = 'leader_not_attached')
502
506
  or status = 'queued_until_leader_attach'
507
+ or status = 'submitted_pending_acceptance'
503
508
  )",
504
509
  params![owner_team_id.as_str(), chrono::Utc::now().to_rfc3339()],
505
510
  )?;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-agent/installer",
3
- "version": "0.5.54",
3
+ "version": "0.5.55",
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.54",
24
- "@team-agent/cli-darwin-x64": "0.5.54",
25
- "@team-agent/cli-linux-x64": "0.5.54"
23
+ "@team-agent/cli-darwin-arm64": "0.5.55",
24
+ "@team-agent/cli-darwin-x64": "0.5.55",
25
+ "@team-agent/cli-linux-x64": "0.5.55"
26
26
  },
27
27
  "scripts": {
28
28
  "postinstall": "node npm/bincheck.mjs",