Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
69b76d9
feat(composer): add Tiptap rich-text composer foundation (Phase 0)
xintaofei Jun 10, 2026
b7932b0
feat(composer): add inline reference node + badge rendering (Phase 1)
xintaofei Jun 10, 2026
d00aa73
feat(composer): add unified @ mention panel (Phase 2)
xintaofei Jun 10, 2026
5ea830c
Merge remote-tracking branch 'origin/main'
xintaofei Jun 11, 2026
46b416a
feat(composer): add send/restore serializers and configurable key han…
xintaofei Jun 11, 2026
a9dcfc7
feat(composer): add draft v2 (Tiptap doc) persistence with v1 migrati…
xintaofei Jun 11, 2026
c8e4f43
feat(composer): add useReferenceSearch data-source provider for the @…
xintaofei Jun 11, 2026
a16f9e4
feat(composer): replace the message-input textarea with the Tiptap Ri…
xintaofei Jun 11, 2026
391e362
feat(composer): restore queued-message badges + attachments on edit (…
xintaofei Jun 11, 2026
9a99d8d
feat(composer): viewport-aware positioning for the @ mention panel (P…
xintaofei Jun 11, 2026
c3c8567
feat(composer): accessibility for the @ mention panel and reference b…
xintaofei Jun 11, 2026
ab28ed4
feat(composer): truncation hint + localized @ panel chrome (Phase 4c)
xintaofei Jun 11, 2026
6ee3239
feat(composer): shared codeg uri parser + session <agent_type>_<exter…
xintaofei Jun 11, 2026
6ab4bd3
feat(transcript): render codeg:// reference links as inline badges (P5b)
xintaofei Jun 11, 2026
9fabb86
feat(composer): agent codeg://agent/<type> routing anchor (P5c)
xintaofei Jun 11, 2026
1e152de
feat(composer): tabbed @ mention panel (agent-first, five fixed tabs)…
xintaofei Jun 11, 2026
1086edd
fix(transcript): keep @session/@commit/@agent inline as badges in use…
xintaofei Jun 11, 2026
20b4439
fix(transcript): let codeg:// links survive sanitization → inline bad…
xintaofei Jun 12, 2026
0c8b791
Merge remote-tracking branch 'origin/main'
xintaofei Jun 12, 2026
a659af8
feat(composer): per-type tinted reference badges + skill prefix seria…
xintaofei Jun 12, 2026
f669192
refactor(composer): drop the skill tab from the @ panel (P8b)
xintaofei Jun 12, 2026
9da1294
feat(composer): / $ and expert menu insert inline badges (P8c)
xintaofei Jun 12, 2026
a05b316
feat(composer): click the input's empty chrome to focus the editor (P8d)
xintaofei Jun 12, 2026
1267a0e
feat(composer): unify badge icon to the command glyph + text-only col…
xintaofei Jun 12, 2026
14990c1
feat(transcript): badge bare /command · $skill tokens in user message…
xintaofei Jun 12, 2026
e7459d9
Merge remote-tracking branch 'origin/main'
xintaofei Jun 12, 2026
7ae209d
Merge branch 'main-06-12'
xintaofei Jun 13, 2026
5184dac
feat(chat): show attached files as inline file badges in user messages
xintaofei Jun 13, 2026
d6400a4
feat(composer): click-to-place caret and a text cursor across the input
xintaofei Jun 13, 2026
e03d7e4
feat(conversations): fold reference badge links to their label in titles
xintaofei Jun 13, 2026
94d8fcf
feat(composer): conversation-icon session badges and folded @ panel t…
xintaofei Jun 13, 2026
f51d853
feat(mcp): add get_session_info tool to resolve @-mentioned sessions
xintaofei Jun 14, 2026
cd647ec
fix(conversations): fold file reference links to labels in titles
xintaofei Jun 14, 2026
01ad20b
feat(appearance): default the interface font to System Monospace
xintaofei Jun 14, 2026
1670ebd
feat(editor): add selected lines to the conversation as a line-range …
xintaofei Jun 14, 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
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@
"@tauri-apps/plugin-process": "^2.3.1",
"@tauri-apps/plugin-updater": "^2.10.0",
"@tauri-apps/plugin-window-state": "~2.4.1",
"@tiptap/core": "3.26.0",
"@tiptap/extension-placeholder": "3.26.0",
"@tiptap/markdown": "3.26.0",
"@tiptap/pm": "3.26.0",
"@tiptap/react": "3.26.0",
"@tiptap/starter-kit": "3.26.0",
"@tiptap/suggestion": "3.26.0",
"@xterm/addon-fit": "^0.11.0",
"@xterm/addon-ligatures": "^0.10.0",
"@xterm/addon-web-links": "^0.12.0",
Expand Down
518 changes: 518 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

46 changes: 33 additions & 13 deletions src-tauri/src/acp/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,11 @@ pub struct DelegationInjection {
/// of the three is on, and the companion's `--features` lists `ask` to expose
/// the `ask_user_question` tool.
pub ask: crate::acp::question::QuestionRuntimeConfig,
/// Hot-swappable "is get-session-info enabled?" flag. Read at injection time
/// alongside the other three so `codeg-mcp` is injected when ANY of the four
/// is on, and the companion's `--features` lists `sessions` to expose the
/// `get_session_info` tool. No teardown handle (the lookup is stateless).
pub sessions: crate::acp::session_info::SessionInfoRuntimeConfig,
/// Question registry handle for the teardown cascade. The `run_connection`
/// cleanup guard calls `cancel_questions_by_parent` through this so a pending
/// `ask_user_question` is reclaimed synchronously on disconnect, mirroring
Expand Down Expand Up @@ -1064,16 +1069,17 @@ fn is_executable_file(path: &Path) -> bool {
/// delegate tool silently. Skipping leaves the agent fully functional minus
/// `delegate_to_agent`, which is the right degradation when codeg-mcp didn't
/// make it into the install.
/// The `--features` value for a companion launch given the three feature flags,
/// The `--features` value for a companion launch given the four feature flags,
/// or `None` when none is enabled (the companion isn't injected at all).
/// Pulled out as a pure function so the inject/skip decision is unit-testable
/// without a real binary on disk or a live broker.
fn companion_features_arg(
delegation_enabled: bool,
feedback_enabled: bool,
ask_enabled: bool,
sessions_enabled: bool,
) -> Option<String> {
if !delegation_enabled && !feedback_enabled && !ask_enabled {
if !delegation_enabled && !feedback_enabled && !ask_enabled && !sessions_enabled {
return None;
}
let mut features: Vec<&str> = Vec::new();
Expand All @@ -1086,6 +1092,9 @@ fn companion_features_arg(
if ask_enabled {
features.push("ask");
}
if sessions_enabled {
features.push("sessions");
}
Some(features.join(","))
}

Expand All @@ -1110,15 +1119,20 @@ async fn inject_codeg_mcp(
let delegation_enabled = injection.broker.config_snapshot().await.enabled;
let feedback_enabled = injection.feedback.is_enabled().await;
let ask_enabled = injection.ask.is_enabled().await;
let sessions_enabled = injection.sessions.is_enabled().await;
// `None` (no feature enabled) short-circuits the whole injection.
let features_arg =
companion_features_arg(delegation_enabled, feedback_enabled, ask_enabled)?;
let features_arg = companion_features_arg(
delegation_enabled,
feedback_enabled,
ask_enabled,
sessions_enabled,
)?;
let Some(binary_path) = locate_codeg_mcp_binary() else {
eprintln!(
"[delegation][WARN] codeg-mcp companion binary not found (checked CODEG_MCP_BIN, \
exe sibling, and PATH); skipping delegate_to_agent / check_user_feedback / \
ask_user_question tool injection for connection {parent_connection_id}. Reinstall \
codeg or set CODEG_MCP_BIN to fix."
ask_user_question / get_session_info tool injection for connection \
{parent_connection_id}. Reinstall codeg or set CODEG_MCP_BIN to fix."
);
return None;
};
Expand Down Expand Up @@ -1147,7 +1161,7 @@ async fn inject_codeg_mcp(
// (any platform).
"--parent-pid".to_string(),
std::process::id().to_string(),
// Tool groups to expose this launch (delegation and/or feedback).
// Tool groups to expose this launch (delegation / feedback / ask / sessions).
"--features".to_string(),
features_arg,
]);
Expand Down Expand Up @@ -4581,6 +4595,7 @@ mod tests {
socket_path: std::path::PathBuf::from("/tmp/codeg-mcp.sock"),
feedback: crate::acp::feedback::FeedbackRuntimeConfig::new(),
ask: crate::acp::question::QuestionRuntimeConfig::new(),
sessions: crate::acp::session_info::SessionInfoRuntimeConfig::new(),
questions: Arc::new(NoQuestions)
as Arc<dyn crate::acp::question::SessionQuestionAccess>,
};
Expand Down Expand Up @@ -4617,27 +4632,32 @@ mod tests {
#[test]
fn companion_features_arg_inject_skip_decision() {
// All off → no companion at all.
assert_eq!(companion_features_arg(false, false, false), None);
assert_eq!(companion_features_arg(false, false, false, false), None);
// Delegation only.
assert_eq!(
companion_features_arg(true, false, false),
companion_features_arg(true, false, false, false),
Some("delegation".to_string())
);
// Feedback only — the decoupling: companion injected for feedback even
// when delegation is off.
assert_eq!(
companion_features_arg(false, true, false),
companion_features_arg(false, true, false, false),
Some("feedback".to_string())
);
// Ask only — likewise injects the companion on its own.
assert_eq!(
companion_features_arg(false, false, true),
companion_features_arg(false, false, true, false),
Some("ask".to_string())
);
// Sessions only — likewise injects the companion on its own.
assert_eq!(
companion_features_arg(false, false, false, true),
Some("sessions".to_string())
);
// All on → comma-joined, in declaration order.
assert_eq!(
companion_features_arg(true, true, true),
Some("delegation,feedback,ask".to_string())
companion_features_arg(true, true, true, true),
Some("delegation,feedback,ask,sessions".to_string())
);
}
}
Loading
Loading