M2 audit: excise managed connectors and xAI media-gen tools

Managed connectors (grok.com MCP admin) removed root-and-branch:
- The managed-MCP fetch/injection pipeline is gone, including the whole
  kigi-shell-session-support crate (managed-config fetch client, gateway
  tool catalog + dispatch, header injection, refresh task), reactive
  managed re-auth, mcp_doctor's grok.com-source discovery, and the
  [managed_mcps] config surface.
- TUI: the 'Managed by grok.com' section, connectors URL/deep-link,
  Action::OpenManagedConnectors, and session_team_id are gone. Local MCP
  management (list/toggle/add/remove/auth/tools) is fully intact.
- Kept as LOCAL policy: managed-settings.json MCP allow/deny enforcement,
  the multi-source local MCP merge, folder-trust gating. PluginOrigin
  Project/User labels kept (they tag locally discovered plugin dirs).

imagine/media-gen tools (xAI image/video generation) removed:
- image_gen, image_edit, video_gen, image_to_video, reference_to_video
  implementations, registrations, ToolKind/ToolInput/Output variants
  (serde-safe), config plumbing end to end, ZDR video machinery,
  /imagine + /imagine-video commands and guidance text, the bundled
  imagine skill (added to legacy cleanup so user installs delete it),
  and the media-gen render path.
- Kept: image INPUT (paste/attach, [Image #N] meta, pdf/image fetch,
  clipboard wrap), generic media-ref rendering, and the generic tool
  401-retry machinery (tests renamed, assertions unweakened).
- deploy_app stays: it is a permanently-disabled local stub deploying
  nowhere.

121 files changed, 8 deleted. Gates: workspace check/clippy 0/0, fmt,
deny ok; suites green (tools 2554, shell 4862, tui 6608, workspace
1042). Remaining grok.com strings live only in the auth-method ids and
changelog archives (§9/M3 sweep).
This commit is contained in:
2026-07-17 23:45:05 -04:00
parent fa75eb139a
commit 5e4e24db99
120 changed files with 301 additions and 11327 deletions
@@ -79,7 +79,8 @@ pub const MAX_PLACEHOLDER_AGGREGATE_BYTES: usize = 200 * 1024 * 1024;
/// `_meta` key under which an attached image's `[Image #N]` display number
/// is recorded on its ACP image block, so the server can resolve
/// `[Image #N]` tokens to the right attachment by number rather than list
/// position (the two diverge — see `AttachedImages` in `kigi-tools`).
/// position (numbers are not renumbered when a chip is removed
/// mid-compose, so the two diverge).
pub const IMAGE_DISPLAY_NUMBER_META_KEY: &str = "xai.dev/imageDisplayNumber";
/// Build an ACP image-block `_meta` value carrying `display_number` under
@@ -102,34 +103,6 @@ pub fn display_number_from_meta(meta: Option<&agent_client_protocol::Meta>) -> O
.and_then(|n| usize::try_from(n).ok())
}
/// Build the per-turn `[Image #N]` → reference registry (see
/// [`AttachedImages`](kigi_tools::types::resources::AttachedImages))
/// from the user's inline attached images.
///
/// The display number comes from each block's `_meta` (set by the TUI),
/// falling back to 1-based position for callers that don't record it. The
/// reference is one `image_edit`'s resolver can read directly: the bare
/// durable path (from the `file://` URI) when present, else a
/// `data:<mime>;base64,<data>` URL.
pub fn attached_image_references(
images: &[agent_client_protocol::ImageContent],
) -> Vec<(usize, String)> {
images
.iter()
.enumerate()
.map(|(idx, image)| {
let display_number = display_number_from_meta(image.meta.as_ref()).unwrap_or(idx + 1);
let reference =
if let Some(path) = image.uri.as_deref().and_then(|u| u.strip_prefix("file://")) {
path.to_owned()
} else {
format!("data:{};base64,{}", image.mime_type, image.data)
};
(display_number, reference)
})
.collect()
}
/// File extensions accepted by the placeholder loader.
///
/// SVG is intentionally **not** in this list: SVG is XML text with no
@@ -1460,67 +1433,4 @@ mod tests {
assert_eq!(loaded.mime_type, "image/png");
assert_eq!(loaded.data, PNG_BYTES);
}
#[test]
fn attached_image_references_prefers_file_path_over_data() {
// `[Image #N]` resolution should hand `image_edit` a bare on-disk
// path (from the durable `file://` URI) so it reads the session
// copy rather than re-decoding a large base64 blob.
let img = agent_client_protocol::ImageContent::new("AAAA", "image/png")
.uri(Some(
"file:///Users/me/.kigi/sessions/s/images/image-1.png".into(),
))
.meta(display_number_meta(1));
let refs = attached_image_references(std::slice::from_ref(&img));
assert_eq!(
refs,
vec![(
1,
"/Users/me/.kigi/sessions/s/images/image-1.png".to_string()
)]
);
}
#[test]
fn attached_image_references_falls_back_to_data_url() {
// No durable URI (e.g. persistence failed): keep the inline bytes
// as a data URL so the token still resolves to the right image.
let img = agent_client_protocol::ImageContent::new("BBBB", "image/jpeg")
.meta(display_number_meta(2));
let refs = attached_image_references(std::slice::from_ref(&img));
assert_eq!(refs, vec![(2, "data:image/jpeg;base64,BBBB".to_string())]);
}
#[test]
fn attached_image_references_keys_by_meta_number_not_position() {
// Non-contiguous numbers (`#1`, `#3`) survive a mid-compose chip
// removal; the registry must key on the recorded number, not the
// list position.
let mk = |data: &str, n: usize| {
agent_client_protocol::ImageContent::new(data, "image/png").meta(display_number_meta(n))
};
let refs = attached_image_references(&[mk("first", 1), mk("third", 3)]);
assert_eq!(
refs,
vec![
(1, "data:image/png;base64,first".to_string()),
(3, "data:image/png;base64,third".to_string()),
]
);
}
#[test]
fn attached_image_references_falls_back_to_position_without_meta() {
// Older client / non-TUI caller with no recorded number: fall back
// to 1-based position so the common contiguous case still resolves.
let mk = |data: &str| agent_client_protocol::ImageContent::new(data, "image/png");
let refs = attached_image_references(&[mk("first"), mk("second")]);
assert_eq!(
refs,
vec![
(1, "data:image/png;base64,first".to_string()),
(2, "data:image/png;base64,second".to_string()),
]
);
}
}