mirror of
https://github.com/block/buzz.git
synced 2026-11-04 08:21:48 +00:00
fix(desktop): remove stale sprout-admin prereq, add sidecar tooling (#371)
This commit is contained in:
@@ -6,7 +6,7 @@ use crate::{
|
||||
managed_agents::{
|
||||
command_availability, discover_local_acp_providers, AcpProviderInfo,
|
||||
DiscoverManagedAgentPrereqsRequest, ManagedAgentPrereqsInfo, RelayAgentInfo,
|
||||
DEFAULT_ACP_COMMAND, DEFAULT_ADMIN_COMMAND, DEFAULT_MCP_COMMAND,
|
||||
DEFAULT_ACP_COMMAND, DEFAULT_MCP_COMMAND,
|
||||
},
|
||||
relay::{build_authed_request, send_json_request},
|
||||
};
|
||||
@@ -37,7 +37,6 @@ pub fn discover_managed_agent_prereqs(
|
||||
ManagedAgentPrereqsInfo {
|
||||
acp: command_availability(acp_command, Some(&app)),
|
||||
mcp: command_availability(mcp_command, Some(&app)),
|
||||
admin: command_availability(DEFAULT_ADMIN_COMMAND, Some(&app)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -273,7 +273,6 @@ pub struct DiscoverManagedAgentPrereqsRequest {
|
||||
pub struct ManagedAgentPrereqsInfo {
|
||||
pub acp: CommandAvailabilityInfo,
|
||||
pub mcp: CommandAvailabilityInfo,
|
||||
pub admin: CommandAvailabilityInfo,
|
||||
}
|
||||
|
||||
/// Patch request for updating a managed agent's mutable fields.
|
||||
@@ -374,7 +373,6 @@ pub struct UpdateTeamRequest {
|
||||
}
|
||||
|
||||
pub const DEFAULT_ACP_COMMAND: &str = "sprout-acp";
|
||||
pub const DEFAULT_ADMIN_COMMAND: &str = "sprout-admin";
|
||||
pub const DEFAULT_AGENT_COMMAND: &str = "goose";
|
||||
pub const DEFAULT_MCP_COMMAND: &str = "sprout-mcp-server";
|
||||
/// ~5 min (320s) — matches the CLI harness default (SPROUT_ACP_IDLE_TIMEOUT).
|
||||
|
||||
@@ -99,11 +99,9 @@ export function CreateAgentDialog({
|
||||
// Use this everywhere instead of raw `mintToken` for validation/rendering.
|
||||
const effectiveMintToken = isProviderMode || mintToken;
|
||||
|
||||
const isMintSupported = prereqs?.admin.available ?? false;
|
||||
const isSpawnSupported =
|
||||
prereqs?.acp.available === true && prereqs?.mcp.available === true;
|
||||
const mintToggleDisabled =
|
||||
prereqsQuery.isLoading || (prereqs !== null && !isMintSupported);
|
||||
const mintToggleDisabled = prereqsQuery.isLoading;
|
||||
const spawnToggleDisabled =
|
||||
prereqsQuery.isLoading || (prereqs !== null && !isSpawnSupported);
|
||||
const isDiscoveryPending = providersQuery.isLoading || prereqsQuery.isLoading;
|
||||
@@ -126,15 +124,6 @@ export function CreateAgentDialog({
|
||||
providersQuery.isLoading,
|
||||
]);
|
||||
|
||||
React.useEffect(() => {
|
||||
// Don't auto-disable minting in provider mode — it's required.
|
||||
if (!prereqs || prereqs.admin.available || !mintToken || isProviderMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
setMintToken(false);
|
||||
}, [mintToken, prereqs, isProviderMode]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (
|
||||
!prereqs ||
|
||||
@@ -305,7 +294,6 @@ export function CreateAgentDialog({
|
||||
name.trim().length > 0 &&
|
||||
(!effectiveMintToken || selectedScopes.size > 0) &&
|
||||
!isDiscoveryPending &&
|
||||
!(effectiveMintToken && prereqs !== null && !isMintSupported) &&
|
||||
!(
|
||||
!isProviderMode &&
|
||||
spawnAfterCreate &&
|
||||
@@ -464,7 +452,6 @@ export function CreateAgentDialog({
|
||||
) : null}
|
||||
|
||||
<CreateAgentOptionToggles
|
||||
isMintSupported={isMintSupported}
|
||||
isSpawnSupported={isSpawnSupported}
|
||||
mintToken={effectiveMintToken}
|
||||
mintToggleDisabled={isProviderMode || mintToggleDisabled}
|
||||
|
||||
@@ -325,7 +325,6 @@ export function CreateAgentRuntimeFields({
|
||||
}
|
||||
|
||||
export function CreateAgentOptionToggles({
|
||||
isMintSupported,
|
||||
isSpawnSupported,
|
||||
mintToken,
|
||||
mintToggleDisabled,
|
||||
@@ -338,7 +337,6 @@ export function CreateAgentOptionToggles({
|
||||
onToggleStartOnAppLaunch,
|
||||
onToggleSpawnAfterCreate,
|
||||
}: {
|
||||
isMintSupported: boolean;
|
||||
isSpawnSupported: boolean;
|
||||
mintToken: boolean;
|
||||
mintToggleDisabled: boolean;
|
||||
@@ -369,9 +367,7 @@ export function CreateAgentOptionToggles({
|
||||
>
|
||||
<p className="text-sm font-semibold tracking-tight">Mint token</p>
|
||||
<p className="mt-1 text-sm text-foreground/70">
|
||||
{prereqs !== null && !isMintSupported
|
||||
? `Unavailable until ${prereqs.admin.command} is installed.`
|
||||
: "Use sprout-admin to create a bearer token for this agent."}
|
||||
Mint a relay API token for this agent.
|
||||
</p>
|
||||
</button>
|
||||
|
||||
|
||||
@@ -141,8 +141,8 @@ function SetupHelpCard() {
|
||||
<code className="rounded bg-background px-1.5 py-0.5 font-mono text-[12px]">
|
||||
cargo build --release --workspace
|
||||
</code>{" "}
|
||||
when you want the desktop app to mint tokens or spawn ACP harnesses
|
||||
from this checkout.
|
||||
when you want the desktop app to spawn ACP harnesses from this
|
||||
checkout.
|
||||
</p>
|
||||
<p>
|
||||
If you keep binaries outside your PATH, use the custom ACP and MCP
|
||||
@@ -168,13 +168,6 @@ export function DoctorSettingsPanel() {
|
||||
const isRefreshing = providersQuery.isFetching || prereqsQuery.isFetching;
|
||||
|
||||
const toolChecks = [
|
||||
{
|
||||
id: "admin",
|
||||
label: "Token minting",
|
||||
purpose:
|
||||
"Desktop uses `sprout-admin` to mint managed-agent bearer tokens.",
|
||||
availability: prereqs?.admin ?? null,
|
||||
},
|
||||
{
|
||||
id: "acp",
|
||||
label: "ACP harness",
|
||||
@@ -192,10 +185,7 @@ export function DoctorSettingsPanel() {
|
||||
];
|
||||
|
||||
const hasMissingSproutTools =
|
||||
prereqs !== null &&
|
||||
(!prereqs.admin.available ||
|
||||
!prereqs.acp.available ||
|
||||
!prereqs.mcp.available);
|
||||
prereqs !== null && (!prereqs.acp.available || !prereqs.mcp.available);
|
||||
|
||||
return (
|
||||
<section className="space-y-5" data-testid="settings-doctor">
|
||||
@@ -306,11 +296,6 @@ export function DoctorSettingsPanel() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="mt-3 text-xs text-muted-foreground">
|
||||
Token minting always checks the default{" "}
|
||||
<code className="font-mono">sprout-admin</code> command.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -289,7 +289,6 @@ type RawCommandAvailability = {
|
||||
};
|
||||
|
||||
type RawManagedAgentPrereqs = {
|
||||
admin: RawCommandAvailability;
|
||||
acp: RawCommandAvailability;
|
||||
mcp: RawCommandAvailability;
|
||||
};
|
||||
@@ -1046,7 +1045,6 @@ export async function discoverManagedAgentPrereqs(input: {
|
||||
);
|
||||
|
||||
return {
|
||||
admin: fromRawCommandAvailability(response.admin),
|
||||
acp: fromRawCommandAvailability(response.acp),
|
||||
mcp: fromRawCommandAvailability(response.mcp),
|
||||
};
|
||||
|
||||
@@ -386,7 +386,6 @@ export type CommandAvailability = {
|
||||
};
|
||||
|
||||
export type ManagedAgentPrereqs = {
|
||||
admin: CommandAvailability;
|
||||
acp: CommandAvailability;
|
||||
mcp: CommandAvailability;
|
||||
};
|
||||
|
||||
@@ -348,7 +348,6 @@ type RawCommandAvailability = {
|
||||
};
|
||||
|
||||
type RawManagedAgentPrereqs = {
|
||||
admin: RawCommandAvailability;
|
||||
acp: RawCommandAvailability;
|
||||
mcp: RawCommandAvailability;
|
||||
};
|
||||
@@ -3056,11 +3055,6 @@ async function handleDiscoverManagedAgentPrereqs(args: {
|
||||
};
|
||||
}): Promise<RawManagedAgentPrereqs> {
|
||||
return {
|
||||
admin: {
|
||||
command: "sprout-admin",
|
||||
resolved_path: "/Users/wesb/dev/sprout/target/debug/sprout-admin",
|
||||
available: true,
|
||||
},
|
||||
acp: {
|
||||
command: args.input?.acpCommand ?? "sprout-acp",
|
||||
resolved_path: "/Users/wesb/dev/sprout/target/debug/sprout-acp",
|
||||
|
||||
@@ -393,9 +393,6 @@ test("shows doctor checks for local sprout tooling", async ({ page }) => {
|
||||
await openSettings(page, "doctor");
|
||||
|
||||
await expect(page.getByTestId("settings-doctor")).toBeVisible();
|
||||
await expect(page.getByTestId("doctor-check-admin")).toContainText(
|
||||
"sprout-admin",
|
||||
);
|
||||
await expect(page.getByTestId("doctor-check-acp")).toContainText(
|
||||
"sprout-acp",
|
||||
);
|
||||
|
||||
26
justfile
26
justfile
@@ -85,14 +85,18 @@ desktop-tauri-fmt:
|
||||
desktop-tauri-fmt-check:
|
||||
cargo fmt --manifest-path {{desktop_tauri_manifest}} --all -- --check
|
||||
|
||||
# Check the desktop Tauri Rust crate compiles
|
||||
desktop-tauri-check:
|
||||
# Ensure sidecar placeholder binaries exist (Tauri validates externalBin at compile time)
|
||||
_ensure-sidecar-stubs:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
TARGET=$(rustc -vV | sed -n 's|host: ||p')
|
||||
mkdir -p desktop/src-tauri/binaries
|
||||
touch "desktop/src-tauri/binaries/sprout-acp-$TARGET"
|
||||
touch "desktop/src-tauri/binaries/sprout-mcp-server-$TARGET"
|
||||
for bin in sprout-acp sprout-mcp-server; do
|
||||
touch "desktop/src-tauri/binaries/${bin}-${TARGET}"
|
||||
done
|
||||
|
||||
# Check the desktop Tauri Rust crate compiles
|
||||
desktop-tauri-check: _ensure-sidecar-stubs
|
||||
cargo check --manifest-path {{desktop_tauri_manifest}}
|
||||
|
||||
# Build the full desktop Tauri app locally (unsigned, for testing)
|
||||
@@ -156,31 +160,21 @@ proxy-release:
|
||||
cargo run -p sprout-proxy --release
|
||||
|
||||
# Run the desktop Tauri app in dev mode (ports and identity derived from worktree)
|
||||
dev *ARGS:
|
||||
dev *ARGS: _ensure-sidecar-stubs
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd {{desktop_dir}}
|
||||
[[ -d node_modules ]] || pnpm install
|
||||
# Ensure sidecar placeholder binaries exist (Tauri validates externalBin at compile time)
|
||||
TARGET=$(rustc -vV | sed -n 's|host: ||p')
|
||||
mkdir -p src-tauri/binaries
|
||||
touch "src-tauri/binaries/sprout-acp-$TARGET"
|
||||
touch "src-tauri/binaries/sprout-mcp-server-$TARGET"
|
||||
source ../scripts/instance-env.sh
|
||||
echo "Starting on Vite port ${SPROUT_VITE_PORT}, relay ${SPROUT_RELAY_URL}"
|
||||
pnpm exec tauri dev --config "$SPROUT_TAURI_CONFIG" {{ARGS}}
|
||||
|
||||
# Run the desktop app against the internal staging relay (installs deps + builds agent tools automatically)
|
||||
staging *ARGS:
|
||||
staging *ARGS: _ensure-sidecar-stubs
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd {{desktop_dir}}
|
||||
pnpm install
|
||||
# Ensure sidecar placeholder binaries exist (Tauri validates externalBin at compile time)
|
||||
TARGET=$(rustc -vV | sed -n 's|host: ||p')
|
||||
mkdir -p src-tauri/binaries
|
||||
touch "src-tauri/binaries/sprout-acp-$TARGET"
|
||||
touch "src-tauri/binaries/sprout-mcp-server-$TARGET"
|
||||
cd ..
|
||||
cargo build --release -p sprout-acp -p sprout-mcp
|
||||
cd {{desktop_dir}}
|
||||
|
||||
22
scripts/bundle-sidecars.sh
Executable file
22
scripts/bundle-sidecars.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SIDECARS=(sprout-acp sprout-mcp-server)
|
||||
TARGET=${1:-$(rustc -vV | sed -n 's|host: ||p')}
|
||||
BINARIES_DIR="desktop/src-tauri/binaries"
|
||||
|
||||
missing=()
|
||||
for bin in "${SIDECARS[@]}"; do
|
||||
[[ -f "target/release/$bin" ]] || missing+=("$bin")
|
||||
done
|
||||
if [[ ${#missing[@]} -gt 0 ]]; then
|
||||
echo "Error: missing release binaries: ${missing[*]}" >&2
|
||||
echo "Run 'cargo build --release -p sprout-acp -p sprout-mcp' first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$BINARIES_DIR"
|
||||
for bin in "${SIDECARS[@]}"; do
|
||||
cp "target/release/$bin" "$BINARIES_DIR/${bin}-${TARGET}"
|
||||
done
|
||||
echo "Sidecars bundled for $TARGET"
|
||||
Reference in New Issue
Block a user