Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ _bundle-unix:
GOOSE_DEV_MODE=required GOOSE_BUILD_PROFILE=release ./scripts/ensure-local-goose.sh
fi
GOOSE_BUILD_PROFILE=release ./scripts/prepare-goose-sidecar.sh
VITE_FEEDBACK="${VITE_FEEDBACK:-0}" CARGO_TARGET_DIR="$TAURI_CARGO_TARGET_DIR" ./scripts/prepare-berdctl-sidecar.sh
VITE_FEEDBACK="${VITE_FEEDBACK:-0}" VITE_AUTOMATIONS="${VITE_AUTOMATIONS:-0}" CARGO_TARGET_DIR="$TAURI_CARGO_TARGET_DIR" ./scripts/prepare-berdctl-sidecar.sh
./scripts/prepare-catch-sidecar.sh

CARGO_FEATURES=(berdctl)
Expand Down Expand Up @@ -421,7 +421,7 @@ _bundle-debug-unix:
GOOSE_DEV_MODE=required GOOSE_BUILD_PROFILE=debug ./scripts/ensure-local-goose.sh
fi
GOOSE_BUILD_PROFILE=debug ./scripts/prepare-goose-sidecar.sh
VITE_FEEDBACK="${VITE_FEEDBACK:-0}" CARGO_TARGET_DIR="$TAURI_CARGO_TARGET_DIR" ./scripts/prepare-berdctl-sidecar.sh
VITE_FEEDBACK="${VITE_FEEDBACK:-0}" VITE_AUTOMATIONS="${VITE_AUTOMATIONS:-0}" CARGO_TARGET_DIR="$TAURI_CARGO_TARGET_DIR" ./scripts/prepare-berdctl-sidecar.sh
./scripts/prepare-catch-sidecar.sh

CARGO_FEATURES=(berdctl devtools)
Expand Down Expand Up @@ -512,6 +512,7 @@ dev:
# because tauri.dev.conf.json blanks externalBin.
BERDCTL_FEATURES=()
[[ "${VITE_FEEDBACK:-0}" == "1" ]] && BERDCTL_FEATURES+=(--features block-feedback)
[[ "${VITE_AUTOMATIONS:-0}" == "1" ]] && BERDCTL_FEATURES+=(--features block-automations)
# ${arr[@]+...} guards the empty-array expansion, which bash 3.2 (stock
# macOS) treats as an unbound variable under `set -u`.
(cd src-tauri && cargo build -p berdctl ${BERDCTL_FEATURES[@]+"${BERDCTL_FEATURES[@]}"})
Expand Down
1 change: 1 addition & 0 deletions scripts/dev-e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export VITE_APP_VERSION="$BERD_APP_VERSION_RICH"

BERDCTL_FEATURES=()
[[ "${VITE_FEEDBACK:-0}" == "1" ]] && BERDCTL_FEATURES+=(--features block-feedback)
[[ "${VITE_AUTOMATIONS:-0}" == "1" ]] && BERDCTL_FEATURES+=(--features block-automations)
# ${arr[@]+...} guards the empty-array expansion, which bash 3.2 (stock
# macOS) treats as an unbound variable under `set -u`.
(cd src-tauri && cargo build -p berdctl ${BERDCTL_FEATURES[@]+"${BERDCTL_FEATURES[@]}"})
Expand Down
30 changes: 27 additions & 3 deletions scripts/generate-berdctl-contract.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const packageJson = JSON.parse(
fs.readFileSync(path.join(repoRoot, "package.json"), "utf8"),
);

async function loadContracts(feedbackEnabled) {
async function loadContracts({ feedbackEnabled, automationsEnabled }) {
// Mirror the app's vite resolution (the `@` alias and build-feature defines)
// so each generated projection comes from the exact renderer registry that
// its build will dispatch.
Expand All @@ -51,6 +51,9 @@ async function loadContracts(feedbackEnabled) {
"import.meta.env.VITE_FEEDBACK": JSON.stringify(
feedbackEnabled ? "1" : "0",
),
"import.meta.env.VITE_AUTOMATIONS": JSON.stringify(
automationsEnabled ? "1" : "0",
),
},
server: { middlewareMode: true, hmr: false },
optimizeDeps: { noDiscovery: true },
Expand All @@ -69,8 +72,25 @@ async function loadContracts(feedbackEnabled) {
}
}

const publicContracts = await loadContracts(false);
const feedbackContracts = await loadContracts(true);
// One variant per gate combination: the gates are independent renderer
// build flags, and the embedded CLI artifacts must never advertise a group
// the matching renderer build filters out of TOOL_GROUPS.
const publicContracts = await loadContracts({
feedbackEnabled: false,
automationsEnabled: false,
});
const feedbackContracts = await loadContracts({
feedbackEnabled: true,
automationsEnabled: false,
});
const automationsContracts = await loadContracts({
feedbackEnabled: false,
automationsEnabled: true,
});
const blockContracts = await loadContracts({
feedbackEnabled: true,
automationsEnabled: true,
});

// Resolve the repo's biome binary (same pattern as
// scripts/design-system-manifest.mjs) so the emitted JSON matches the
Expand Down Expand Up @@ -106,6 +126,10 @@ for (const [fileName, contract] of [
["cli-surface.json", publicContracts.surface],
["api-surface-feedback.json", feedbackContracts.api],
["cli-surface-feedback.json", feedbackContracts.surface],
["api-surface-automations.json", automationsContracts.api],
["cli-surface-automations.json", automationsContracts.surface],
["api-surface-block.json", blockContracts.api],
["cli-surface-block.json", blockContracts.surface],
]) {
const target = path.join(crateDir, fileName);
const rendered = render(fileName, contract);
Expand Down
10 changes: 8 additions & 2 deletions scripts/prepare-berdctl-sidecar.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,14 @@ fi

EXPLICIT_TRIPLE="${1:-${BERDCTL_TRIPLE:-}}"
CARGO_ARGS=(build -p berdctl --release)
if [[ "${VITE_FEEDBACK:-0}" == "1" ]]; then
CARGO_ARGS+=(--features block-feedback)
# Each renderer gate maps to its own cargo feature so the embedded CLI
# contract always matches the renderer registry variant it ships with; the
# renderer registry still refuses at dispatch (the trust boundary).
BERDCTL_FEATURE_LIST=()
[[ "${VITE_FEEDBACK:-0}" == "1" ]] && BERDCTL_FEATURE_LIST+=(block-feedback)
[[ "${VITE_AUTOMATIONS:-0}" == "1" ]] && BERDCTL_FEATURE_LIST+=(block-automations)
if [[ ${#BERDCTL_FEATURE_LIST[@]} -gt 0 ]]; then
CARGO_ARGS+=(--features "$(IFS=,; echo "${BERDCTL_FEATURE_LIST[*]}")")
fi
if [[ -n "$EXPLICIT_TRIPLE" ]]; then
TRIPLE="$EXPLICIT_TRIPLE"
Expand Down
2 changes: 1 addition & 1 deletion scripts/release/build-macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ echo "+++ :hammer: pnpm tauri build (unsigned)"
GOOSE_BUILD_PROFILE=release ./scripts/prepare-goose-sidecar.sh
# ACP bridges are installed into the managed Node runtime on demand; they are
# no longer staged as build resources.
VITE_FEEDBACK="$VITE_FEEDBACK_VALUE" ./scripts/prepare-berdctl-sidecar.sh "$TARGET_TRIPLE"
VITE_FEEDBACK="$VITE_FEEDBACK_VALUE" VITE_AUTOMATIONS="$VITE_AUTOMATIONS_VALUE" ./scripts/prepare-berdctl-sidecar.sh "$TARGET_TRIPLE"
if [[ "$VITE_AGENT_TOOLS_VALUE" == "1" ]]; then
./scripts/prepare-bb-cli-resource.sh "$TARGET_TRIPLE"
tmp="$(mktemp)"
Expand Down
20 changes: 19 additions & 1 deletion scripts/release/tests/release-scripts.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,9 @@ describe("development Block-feature resources", () => {
expect(source).toContain(
`[[ "\${VITE_FEEDBACK:-0}" == "1" ]] && BERDCTL_FEATURES+=(--features block-feedback)`,
);
expect(source).toContain(
`[[ "\${VITE_AUTOMATIONS:-0}" == "1" ]] && BERDCTL_FEATURES+=(--features block-automations)`,
);
expect(source).toContain(
`cargo build -p berdctl \${BERDCTL_FEATURES[@]+"\${BERDCTL_FEATURES[@]}"}`,
);
Expand All @@ -502,6 +505,21 @@ describe("development Block-feature resources", () => {
});
});

describe("Windows sidecar staging Block-feature seam", () => {
it("maps each gated CLI family onto the berdctl.exe build args", async () => {
const script = await readFile(
join(repo, "scripts/windows/Stage-Sidecar-Windows.ps1"),
"utf8",
);
expect(script).toContain('if ($env:VITE_FEEDBACK -eq "1") {');
expect(script).toContain('$cargoArgs += @("--features", "block-feedback")');
expect(script).toContain('if ($env:VITE_AUTOMATIONS -eq "1") {');
expect(script).toContain(
'$cargoArgs += @("--features", "block-automations")',
);
});
});

describe("build-macos Block-service feature seam", () => {
it("defaults all six families off and maps each opt-in to packaging", async () => {
const script = await readFile(
Expand Down Expand Up @@ -535,7 +553,7 @@ describe("build-macos Block-service feature seam", () => {
'jq \'.bundle.resources["../resources/bb"] = "bb"\'',
);
expect(script).toContain(
'VITE_FEEDBACK="$VITE_FEEDBACK_VALUE" ./scripts/prepare-berdctl-sidecar.sh',
'VITE_FEEDBACK="$VITE_FEEDBACK_VALUE" VITE_AUTOMATIONS="$VITE_AUTOMATIONS_VALUE" ./scripts/prepare-berdctl-sidecar.sh',
);
});

Expand Down
3 changes: 3 additions & 0 deletions scripts/windows/Stage-Sidecar-Windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ $cargoArgs = @("build", "-p", "berdctl", "--release")
if ($env:VITE_FEEDBACK -eq "1") {
$cargoArgs += @("--features", "block-feedback")
}
if ($env:VITE_AUTOMATIONS -eq "1") {
$cargoArgs += @("--features", "block-automations")
}
if (-not [string]::IsNullOrWhiteSpace($hostTriple) -and $Triple -ne $hostTriple) {
$cargoArgs += @("--target", $Triple)
$berdctlReleaseDir = Join-Path (Join-Path $tauriTargetDir $Triple) "release"
Expand Down
1 change: 1 addition & 0 deletions src-tauri/crates/berdctl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ ureq = { version = "3", features = ["json"] }
[features]
default = []
block-feedback = []
block-automations = []
Loading
Loading