Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
138 commits
Select commit Hold shift + click to select a range
1dee1f2
test(tui): require agent hook journal events to drive agent records
lawrence703 Aug 27, 2026
b8b9b38
fix(tui): feed agent records from committed hook journal events
lawrence703 Aug 27, 2026
6ecbde8
fix(tui): drop the agent record when its session ends
lawrence703 Aug 27, 2026
fce4a34
feat(tui): derive the agent roster from the session journal
lawrence703 Aug 28, 2026
8da5643
feat(tui): carry the agent adapter id through the roster to views
lawrence703 Aug 28, 2026
d8d7abe
fix(tui): force socket roster source precedence
lawrencecchen Aug 28, 2026
8d556ed
Merge socket source precedence repair
lawrencecchen Aug 28, 2026
2bcc44d
Merge current main into agent status records
lawrencecchen Aug 28, 2026
aefa610
fix(tui): keep reducer agent identity semantics stable
lawrencecchen Aug 28, 2026
a21ed15
fix(tui): carry optional agent identity through records
lawrencecchen Aug 29, 2026
377291d
fix(tui): restore optional agent identity
lawrencecchen Aug 29, 2026
c9ad558
style(tui): apply hosted cargo fmt
lawrencecchen Aug 29, 2026
869b19c
test(tui): require durable agent roster lifecycle
lawrencecchen Aug 29, 2026
cef6b90
fix(tui): connect agent roster to journal lifecycle
lawrencecchen Aug 29, 2026
1823ffa
test(tui): fix roster restore surface selector
lawrencecchen Aug 29, 2026
a115901
test(tui): cover ordered roster replay and snapshot recovery
lawrencecchen Aug 29, 2026
9d050ad
fix(tui): fold roster journal prefix safely
lawrencecchen Aug 29, 2026
147a70a
fix(tui): require a visible roster fold target
lawrencecchen Aug 29, 2026
58e3ffd
fix(tui): fence retired roster terminals and coalesce echoes
lawrencecchen Aug 29, 2026
8171dbd
fix(tui): keep roster tombstones at terminal retirement
lawrencecchen Aug 29, 2026
b0356d4
fix(tui): preserve agent retirement cleanup errors
lawrencecchen Aug 29, 2026
0558132
fix(tui): return successful retirement cleanup
lawrencecchen Aug 29, 2026
d9edfb1
fix(tui): retry terminal agent cleanup on startup
lawrencecchen Aug 30, 2026
47974c8
fix(tui): retain ended hook roster fences
lawrencecchen Aug 30, 2026
d02f5ed
Merge remote-tracking branch 'canonical/main' into repair-pr11002-age…
lawrencecchen Aug 30, 2026
f5c5cf5
test(tui): cover paged roster folding
lawrencecchen Aug 30, 2026
7773314
fix(tui): page roster folds to committed target
lawrencecchen Aug 30, 2026
d97d36f
test(tui): cover terminal cleanup and stale roster recovery
lawrencecchen Aug 30, 2026
18c5be9
fix(tui): finish terminal cleanup and reconcile roster removals
lawrencecchen Aug 30, 2026
6747ca1
Merge remote-tracking branch 'canonical/main' into repair-pr11002-age…
lawrencecchen Aug 30, 2026
3d1b369
test(tui): cover roster fence retention and authority
lawrencecchen Aug 30, 2026
a63e7af
fix(tui): bound and validate roster fences
lawrencecchen Aug 30, 2026
afa5f4c
Merge current main into agent status records
lawrencecchen Aug 30, 2026
f3c0f71
fix(tui): reconcile roster state safely
lawrencecchen Aug 30, 2026
9f3b96c
fix(tui): persist socket report freshness
lawrencecchen Aug 30, 2026
324f2db
test(tui): scope roster removal authority and coalesced freshness
lawrencecchen Aug 30, 2026
de1931e
fix(tui): scope roster authority and coalesce socket echoes
lawrencecchen Aug 30, 2026
6ec4009
fix: preserve reconnecting agent state during cleanup
lawrencecchen Aug 30, 2026
7c2ce06
fix(tui): fail closed on corrupt roster metadata
lawrencecchen Aug 30, 2026
2425bb7
chore(tui): drop obsolete CDP context import
lawrencecchen Aug 30, 2026
8b58228
fix(tui): fold agent roster incrementally and reject direct hooks
lawrencecchen Aug 30, 2026
1c90262
fix(tui): journal socket reports before projection
lawrencecchen Aug 30, 2026
656dffc
test(tui): reject direct hook compatibility reports
lawrencecchen Aug 30, 2026
5324764
fix(tui): restore ordered roster checkpoints
lawrencecchen Aug 30, 2026
2e1ce6a
fix(tui): correct agent report compile references
lawrencecchen Aug 30, 2026
703a40c
fix(tui): commit agent echoes with projections
lawrencecchen Aug 30, 2026
ce89026
fix(tui): borrow terminal identity during report
lawrencecchen Aug 30, 2026
e2b6621
fix(tui): fold atomic agent echoes into roster
lawrencecchen Aug 30, 2026
a6c2948
test(tui): verify socket report roster coalescing
lawrencecchen Aug 30, 2026
bbefc52
fix(tui): bound roster recovery folds
lawrencecchen Aug 30, 2026
27267fe
test(tui): route compatibility hook through journal
lawrencecchen Aug 30, 2026
3e70a09
fix(tui): bound startup roster replay
lawrencecchen Aug 30, 2026
a47269c
test(tui): cover roster purge snapshot failure
lawrencecchen Aug 30, 2026
ff62bff
fix(tui): clear side tables after roster snapshot failure
lawrencecchen Aug 30, 2026
9ca0544
test(tui): cover hook-owned socket echo coalescing
lawrencecchen Aug 30, 2026
8e66362
fix(tui): skip socket echoes for hook-owned roster entries
lawrencecchen Aug 30, 2026
506b90c
fix(tui): remove arbitrary roster replay cap
lawrencecchen Aug 30, 2026
9ab8fe2
test: guard roster cache timestamp ordering
lawrencecchen Aug 30, 2026
7938910
fix: preserve newer agent report timestamps
lawrencecchen Aug 30, 2026
71fbf1c
test: retain all retired terminal fences
lawrencecchen Aug 30, 2026
88d5c8c
fix: keep retirement fences until journal compaction
lawrencecchen Aug 30, 2026
46e1e4a
style: format roster regression tests
lawrencecchen Aug 30, 2026
8fbbc61
test(tui): keep hook cursor behind unapplied socket echo
lawrencecchen Aug 30, 2026
5b12a6d
fix(tui): keep socket echoes out of hook cursor
lawrencecchen Aug 30, 2026
6064c70
test(tui): cover retired roster fence compaction
lawrencecchen Aug 30, 2026
30d1ebe
fix(tui): compact retired roster fences at sealed checkpoints
lawrencecchen Aug 30, 2026
f0b8105
fix(tui): normalize journal echo commit tuple
lawrencecchen Aug 30, 2026
56c81f3
style(tui): apply rustfmt to agent projection match
lawrencecchen Aug 30, 2026
9de1541
test(tui): seed agent rows through detected reports
lawrencecchen Aug 30, 2026
f2b48e7
test(tui): route core hook fixtures through journal
lawrencecchen Aug 30, 2026
634c94d
style(tui): format hook journal fixtures
lawrencecchen Aug 30, 2026
253f1b6
test(tui): reserve socket adapter name
lawrencecchen Aug 30, 2026
e11dc8b
fix(tui): reject reserved socket hook source
lawrencecchen Aug 30, 2026
502d249
test(tui): recover terminal retirement after roster snapshot loss
lawrencecchen Aug 30, 2026
33bda6c
fix(tui): restore retirement fences from terminal tombstones
lawrencecchen Aug 30, 2026
fea0d3c
test(tui): fence retired ingress and detected reports
lawrencecchen Aug 30, 2026
8f3cf1f
fix(tui): enforce roster authority and coalesce snapshots
lawrencecchen Aug 30, 2026
64c360d
test(tui): coalesce repeated socket Done reports
lawrencecchen Aug 30, 2026
600d952
fix(tui): retain socket receipt after Done removal
lawrencecchen Aug 30, 2026
1d5c678
test(tui): fence roster folds behind pending projections
lawrencecchen Aug 30, 2026
d7754e8
test(tui): cover orphaned terminal tombstones
lawrencecchen Aug 30, 2026
aeaab8d
fix(tui): fence roster replay behind durable projection
lawrencecchen Aug 30, 2026
5fcb670
test(tui): cap one roster fold pass
lawrencecchen Aug 30, 2026
84445fa
fix(tui): bound synchronous roster replay
lawrencecchen Aug 30, 2026
33e9382
fix(tui): continue bounded roster replay safely
lawrencecchen Aug 30, 2026
26d5891
fix(tui): serialize roster quarantine replay
lawrencecchen Aug 30, 2026
b96d664
fix(tui): wake roster replay after projection recovery
lawrencecchen Aug 30, 2026
f2795b9
test(tui): keep persistent roster replay coverage
lawrencecchen Aug 30, 2026
bcd0cc3
test(tui): assert roster state behind pending projection
lawrencecchen Aug 30, 2026
e10f28e
fix(tui): keep roster retirement and socket coalescing durable
lawrencecchen Aug 30, 2026
118b8b4
fix(cmux-tui): bound roster startup and serialize socket echoes
lawrencecchen Aug 30, 2026
bc6e736
fix tui agent roster projection notifications
lawrencecchen Aug 30, 2026
3b2d153
fix(tui): release hook fences before roster folds
lawrencecchen Aug 30, 2026
d7f1b1f
fix(tui): serialize terminal retirement with hook admission
lawrencecchen Aug 30, 2026
2e95d1b
fix(tui): restore external agent lifecycle continuity
lawrencecchen Aug 30, 2026
f496d66
fix: qualify roster cache helper
lawrencecchen Aug 30, 2026
138fffc
fix(cmux-tui): serialize roster fences through replay
lawrencecchen Aug 31, 2026
fbc5edc
fix(cmux-tui): serialize roster fences through replay
lawrencecchen Aug 31, 2026
ff9f355
fix(cmux-tui): key direct echoes from live records
lawrencecchen Aug 31, 2026
282bd1e
fix(cmux-tui): coalesce cross-adapter done echoes
lawrencecchen Aug 31, 2026
2dae422
fix(cmux-tui): preserve socket authority over detection
lawrencecchen Aug 31, 2026
f13dafd
fix(cmux-tui): enforce report source precedence
lawrencecchen Aug 31, 2026
c0516ce
test(cmux-tui): cover ABA echo transitions
lawrencecchen Aug 31, 2026
c10fb49
fix(cmux-tui): make ABA echo keys monotonic
lawrencecchen Aug 31, 2026
d69c981
fix(cmux-tui): bound roster replay retries
lawrencecchen Aug 31, 2026
ff0d010
test(cmux-tui): cover fresh external lifecycle after hook end
lawrencecchen Aug 31, 2026
155111b
fix(cmux-tui): bound roster projection checks
lawrencecchen Aug 31, 2026
8686d8f
fix(cmux-tui): bound roster shutdown recovery
lawrencecchen Aug 31, 2026
a7d2d34
fix(cmux-tui): restore durable agent identity
lawrencecchen Aug 31, 2026
b6d1c3c
test(cmux-tui): quarantine missing terminal events
lawrencecchen Aug 31, 2026
bf5ff61
fix(cmux-tui): quarantine gone terminal events
lawrencecchen Aug 31, 2026
4734aa0
test(cmux-tui): separate resource refresh from echo coalescing
lawrencecchen Aug 31, 2026
9b2eb83
chore(cmux-tui): remove temporary roster diagnostic
lawrencecchen Aug 31, 2026
7187fac
test(cmux-tui): cover lifecycle fence races
lawrencecchen Aug 31, 2026
cd581a2
fix(cmux-tui): fence delayed roster lifecycles
lawrencecchen Aug 31, 2026
5806746
test(cmux-tui): hold roster worker during fence race
lawrencecchen Aug 31, 2026
83ebc4b
test(cmux-tui): bound done echoes during blocked roster replay
lawrencecchen Aug 31, 2026
318f4d0
fix(cmux-tui): use durable projection for echo coalescing
lawrencecchen Aug 31, 2026
c378cf1
test(cmux-tui): allow reused hook session reopening
lawrencecchen Aug 31, 2026
e1ae84c
fix(cmux-tui): reopen reused hook session ids
lawrencecchen Aug 31, 2026
465c139
fix(cmux-tui): close journal before waiting for roster worker
lawrencecchen Aug 31, 2026
59d5ffd
fix(cmux-tui): wake roster worker after journal close
lawrencecchen Aug 31, 2026
099707f
fix(cmux-tui): cancel roster folds during shutdown
lawrencecchen Aug 31, 2026
e2cf3ed
fix(cmux-tui): wait for roster workers without fold lock
lawrencecchen Aug 31, 2026
2bf59af
test(cmux-tui): fence retired terminal session starts
lawrencecchen Aug 31, 2026
4d52018
fix(cmux-tui): keep retired terminal ids fenced
lawrencecchen Aug 31, 2026
f7c0f3f
test(cmux-tui): preserve agent echo on projection read errors
lawrencecchen Aug 31, 2026
c38ee5b
fix(cmux-tui): fail reports when echo authority is unreadable
lawrencecchen Aug 31, 2026
cf63a5e
fix(cmux-tui): bound durable echo authority reads
lawrencecchen Aug 31, 2026
02428a4
test(cmux-tui): fence journal target owner lifetime
lawrencecchen Aug 31, 2026
c0e91e4
fix(cmux-tui): avoid retaining mux in journal reader
lawrencecchen Aug 31, 2026
ff1cd1e
test(cmux-tui): trace persistent mux shutdown ownership
lawrencecchen Aug 31, 2026
93e4dfb
Fence PTY child reaper shutdown
lawrencecchen Sep 1, 2026
90484df
fix(cmux-tui): fence roster fold worker completion
lawrencecchen Sep 1, 2026
e7346b4
fix(cmux-tui): release journal writer mux before waits
lawrencecchen Sep 1, 2026
b7a5bec
style(cmux-tui): format lifecycle fence
lawrencecchen Sep 1, 2026
9d65f88
fix(cmux-tui): release roster registry guards before waits
lawrencecchen Sep 1, 2026
39fbc23
fix(cmux-tui): join roster worker during mux drop
lawrencecchen Sep 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion cmux-tui/crates/cmux-tui-cdp/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use std::sync::mpsc::{
use std::sync::{Arc, Condvar, Mutex, Weak};
use std::time::{Duration, Instant};

use anyhow::Context;
use base64::Engine;
use serde_json::{Value, json};
use tungstenite::client::IntoClientRequest;
Expand Down
14 changes: 13 additions & 1 deletion cmux-tui/crates/cmux-tui-core/src/agent_hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{

pub const AGENT_HOOK_PRODUCER_ID: &str = "cmux_agent";
pub const AGENT_HOOK_MANIFEST_VERSION: u32 = 1;
const AGENT_HOOK_FORMAT: &str = "cmux.agent-hook.v1";
pub(crate) const AGENT_HOOK_FORMAT: &str = "cmux.agent-hook.v1";
const MAX_AGENT_SOURCE_BYTES: usize = 64;
const MAX_NATIVE_EVENT_BYTES: usize = 128;
const NORMALIZED_TEXT_BYTES: usize = 8 * 1024;
Expand Down Expand Up @@ -220,6 +220,11 @@ fn validate_agent_source(source: &str) -> anyhow::Result<()> {
}),
"agent source must contain 1 to {MAX_AGENT_SOURCE_BYTES} lowercase ASCII letters, digits, hyphens, or underscores"
);
anyhow::ensure!(
source != crate::journal_reducers::SOCKET_REPORT_ADAPTER
&& source != crate::journal_reducers::DETECTED_REPORT_ADAPTER,
"agent source is reserved for internal report adapters"
);
Ok(())
}

Expand Down Expand Up @@ -880,6 +885,13 @@ mod tests {
assert_eq!(grok.kind, "agent.session.ended");
}

#[test]
fn socket_adapter_name_is_reserved_for_internal_reports() {
let error =
agent_hook_journal_ingress("socket", "PermissionRequest", None, json!({})).unwrap_err();
assert!(error.to_string().contains("reserved for internal report adapters"));
}

#[test]
fn provider_envelopes_normalize_structural_fields_and_redact_message_data() {
let native = json!({
Expand Down
4 changes: 4 additions & 0 deletions cmux-tui/crates/cmux-tui-core/src/event_bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,13 +466,15 @@ mod tests {
state: format!("one-{index}").into(),
source: "hook".into(),
session: None,
agent: None,
updated_at_ms: index,
});
broadcaster.emit(MuxEvent::AgentChanged {
surface: 2,
state: format!("two-{index}").into(),
source: "socket".into(),
session: Some("agent-session".into()),
agent: None,
updated_at_ms: index,
});
}
Expand All @@ -493,6 +495,7 @@ mod tests {
state,
source,
session: Some(session),
agent: None,
updated_at_ms: 9_999,
} if state.as_ref() == "two-9999"
&& source.as_ref() == "socket"
Expand Down Expand Up @@ -558,6 +561,7 @@ mod tests {
state: "working".into(),
source: "hook".into(),
session: None,
agent: None,
updated_at_ms: 1,
});
broadcaster.emit(MuxEvent::SurfaceExited(4));
Expand Down
18 changes: 13 additions & 5 deletions cmux-tui/crates/cmux-tui-core/src/journal_ingress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const JOURNAL_DURABLE_BATCH_BYTES: usize = 8 * 1024 * 1024;
pub(crate) const TERMINAL_OUTPUT_INGRESS_BYTES: usize = 64 * 1024;
const TERMINAL_OUTPUT_BATCH_BYTES: usize = 256 * 1024;
const JOURNAL_TERMINAL_FAILURE_RETRY_ATTEMPTS: usize = 6;
const JOURNAL_DURABLE_WAIT: Duration = Duration::from_secs(2);
pub(crate) const JOURNAL_DURABLE_WAIT: Duration = Duration::from_secs(2);
const JOURNAL_COMMIT_RESULT_WAIT: Duration = Duration::from_secs(1);
const JOURNAL_WRITER_SHUTDOWN_WAIT: Duration = Duration::from_secs(1);
const JOURNAL_SQLITE_RETRY_SLICE: Duration = Duration::from_millis(100);
Expand Down Expand Up @@ -1010,8 +1010,14 @@ fn run(mux: Weak<Mux>, receivers: JournalIngressReceivers) {
return;
}
if retryable_sqlite_error(&error) {
let epoch = mux.journal_event_epoch();
mux.wait_for_journal_event(epoch, delay.min(remaining));
let journal = mux.shared_journal_handle();
let epoch = journal.epoch();
drop(mux);
// Keep the retry wake independent from the owning
// mux so a blocked writer cannot keep shutdown
// alive. The journal kernel receives the same
// commit and shutdown notifications.
journal.wait(epoch, delay.min(remaining));
delay = (delay * 2).min(Duration::from_secs(1));
continue;
}
Expand All @@ -1028,8 +1034,10 @@ fn run(mux: Weak<Mux>, receivers: JournalIngressReceivers) {
if receivers.state.pause_nonretryable_failure_for_test() {
continue;
}
let epoch = mux.journal_event_epoch();
mux.wait_for_journal_event(epoch, delay);
let journal = mux.shared_journal_handle();
let epoch = journal.epoch();
drop(mux);
journal.wait(epoch, delay);
delay = (delay * 2).min(Duration::from_secs(1));
continue;
} else if batch[0].completion.is_none() {
Expand Down
Loading
Loading