Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
88a4310
docs(crew): design contract for open workspaces and automatic setup
Broccolito Oct 17, 2026
bcc68e6
crew: add the RemoteAccess level type (design OW-6)
Broccolito Oct 17, 2026
f787a7a
crew(ui): model for Crew tasks, pane seed and composer run-start rout…
Broccolito Oct 17, 2026
7c6fd59
crew: runs carry remote_access and remote_scope reports it (OW-6)
Broccolito Oct 17, 2026
137d285
crew: full access in the member's bridge, bridge.hello/probe and doct…
Broccolito Oct 17, 2026
d641c4d
docs(crew): protocol contract for full access, bridge-local methods a…
Broccolito Oct 17, 2026
2781a82
crew broker: open governance, deletion and the workspace context
Broccolito Oct 17, 2026
12402d4
crew(ui): start an agent task from the composer with @agent, /agent a…
Broccolito Oct 17, 2026
5088705
crew broker: contract tests for governance, deletion and the context …
Broccolito Oct 17, 2026
cc0885f
docs(crew): protocol contract for governance, deletion and the contex…
Broccolito Oct 17, 2026
a066911
settings(models): a Crew tasks row for the model Crew tasks start on …
Broccolito Oct 17, 2026
ae8abf6
crew(ui): pane tests for the Crew task model, the @agent seed and wid…
Broccolito Oct 17, 2026
7d5ab57
crew: an early cancel keeps a job from starting; bound the probe's st…
Broccolito Oct 17, 2026
8210fcd
crew(ui): sort the composer's presentation imports
Broccolito Oct 17, 2026
a839f2d
build(crew): bundle the Linux Crew broker with a manifest in desktop …
Broccolito Oct 17, 2026
4b59bf9
crew daemon: setup service, full agent access, workspace delete route…
Broccolito Oct 17, 2026
0ca695d
crew cli: setup, doctor, host, delete, join, governance, context, set…
Broccolito Oct 17, 2026
19aae45
crew(ui): setup flows, open workspaces, deletion, context editor and …
Broccolito Oct 17, 2026
9b84c69
Merge remote-tracking branch 'origin/claude/crew-w-broker-gov' into c…
Broccolito Oct 17, 2026
f3677cf
Merge remote-tracking branch 'origin/claude/crew-w-broker-bridge' int…
Broccolito Oct 17, 2026
c6c85a6
Merge remote-tracking branch 'origin/claude/crew-w-ui-composer' into …
Broccolito Oct 17, 2026
8754d78
crew: regenerate the OpenAPI client and give test fixtures the new co…
Broccolito Oct 17, 2026
665aadf
crew: fix review and live findings (transfers, join authority, deleti…
Broccolito Oct 17, 2026
df8d7f9
crew: regenerate the client for setup access and storage fixes, descr…
Broccolito Oct 17, 2026
70289b3
crew: split the nine new over-long functions into helpers, with no be…
Broccolito Oct 17, 2026
dba7d4c
crew: tell agents that Crew writes the files-used line, so a reply do…
Broccolito Oct 17, 2026
d745606
crew: tell a member the host deleted the workspace even when they wer…
Broccolito Oct 17, 2026
7f83285
crew: save a joiner's own SSH alias when it is the same user, host an…
Broccolito Oct 17, 2026
601c224
crew: give a never-connected connection setup's agent access when cre…
Broccolito Oct 17, 2026
0ba4779
crew: mark the institution at Create when the host chose it, and say …
Broccolito Oct 17, 2026
ff3b507
crew: connections remove connects a down connection once, so a member…
Broccolito Oct 17, 2026
9ba1192
crew(ui): say a deleted channel or workspace was deleted: the closed-…
Broccolito Oct 17, 2026
e4ea78e
Merge remote-tracking branch 'origin/main' into claude/crew-auto-setup
Broccolito Oct 17, 2026
a42ce96
serve: split handle_serve and the daemon's run under the line limit (…
Broccolito Oct 17, 2026
f25efdf
fix(providers): a status code inside a word or hex id is not that status
Broccolito Oct 17, 2026
0f7f00b
test(crew): expect the identity file made absolute on Windows; exempt…
Broccolito Oct 18, 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
2 changes: 1 addition & 1 deletion .github/workflows/frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ jobs:
run: npm ci

- name: Packaged dependency isolation regressions
run: node --test scripts/verify-packaged-dependencies.test.cjs scripts/npm-command.test.cjs scripts/prepare-native-dependencies.test.cjs scripts/vite-optional-ws.test.mjs scripts/fetch-esbuild.test.cjs
run: node --test scripts/verify-packaged-dependencies.test.cjs scripts/npm-command.test.cjs scripts/prepare-native-dependencies.test.cjs scripts/vite-optional-ws.test.mjs scripts/fetch-esbuild.test.cjs scripts/crew-broker-resources.test.cjs

# Windows allocates a NEW, VISIBLE console for every console-subsystem
# child of a process that owns none — which the Electron main process is.
Expand Down
33 changes: 33 additions & 0 deletions .github/workflows/linux-gui-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,25 @@ jobs:
- name: Re-assert the glibc floor on the downloaded binaries
run: bash scripts/check-glibc-floor.sh

# The Crew setup service installs the Linux broker on a server from the copy a package
# carries (OW-9). Staged here from the artifact's own broker, with the manifest the
# service trusts; `build-linux-deb.sh` copies target/crew-broker/linux-x86_64 into the GUI
# packages, and `build-cli-linux-packages.sh` stages its own copy for the CLI ones.
#
# ⚠ Non-fatal when the artifact has no broker: the GUI packages then carry none and
# prepare-platform-binaries.js warns instead of failing, because this workflow does not
# set BIOROUTER_REQUIRE_CREW_BROKER. Today the chmod step above names the broker, so a
# missing one fails there first; this guards a later change to the artifact. A broker
# that IS present but fails staging (wrong ELF machine, glibc floor, version) still fails.
- name: Stage the Crew broker for the GUI packages
run: |
broker=target/x86_64-unknown-linux-gnu/release/biorouter-crew
if [ ! -f "$broker" ]; then
echo "::warning::the linux-backend artifact has no biorouter-crew; the GUI packages will carry no Crew broker"
exit 0
fi
bash scripts/stage-crew-broker.sh "$broker" target/crew-broker/linux-x86_64

- uses: actions/setup-node@v4
with:
node-version: '24'
Expand Down Expand Up @@ -257,6 +276,20 @@ jobs:
[ -d "$res/bin/llamacpp" ] || { echo "::error::no llamacpp sidecar in the deb — prepare-platform-binaries.js did not run"; ls -la "$res/bin"; exit 1; }
[ -d "$res/web" ] || { echo "::error::no browser interface bundle in the deb"; exit 1; }

# The Crew broker, whenever the staging step found one: in the shipped .deb, the bytes
# its manifest describes, and the very broker the artifact carried.
if [ -f target/crew-broker/linux-x86_64/manifest.json ]; then
node -e '
const { inspectCrewBroker } = require("./ui/desktop/scripts/crew-broker-resources");
const result = inspectCrewBroker(process.argv[1], { required: true, appVersion: process.argv[2] });
result.problems.forEach((problem) => console.log(`::error::${problem}`));
process.exit(result.problems.length > 0 ? 1 : 0);
' "$res/bin" "$v"
cmp "$res/bin/crew-broker/linux-x86_64/biorouter-crew" target/x86_64-unknown-linux-gnu/release/biorouter-crew \
|| { echo "::error::the deb's Crew broker is not the linux-backend artifact's"; exit 1; }
echo "the deb carries the Crew broker and its manifest"
fi

# `ocu` at mode 0200 ships non-executable and Biorouter Copilot does
# not work on Linux, with nothing in the test suite catching it. That
# is the mode-mangling this whole workflow exists to avoid, so read it
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/windows-gui-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,29 @@ jobs:
target/x86_64-pc-windows-gnu/release/biorouterd.exe
echo "source commit: $(cat target/x86_64-pc-windows-gnu/release/package-source-commit.txt)"

# The Crew setup service installs the Linux broker on a server from the copy the Windows
# app carries (OW-9). This workflow builds no Linux backend, so it builds the broker alone
# (scripts/build-crew-broker-linux.sh: the release's cross recipe, about a minute on this
# runner) and stages it with the manifest the service trusts. Its bytes differ from the
# broker in the Linux packages, because Rust builds are not reproducible; each package's
# manifest describes its own copy, so that is expected rather than a mismatch.
#
# ⚠ Non-fatal by design: if this step fails, the Windows packages are still built, without
# a broker, and prepare-platform-binaries.js warns rather than fails because this workflow
# does not set BIOROUTER_REQUIRE_CREW_BROKER. The packages job prints a warning saying so.
- name: Build and stage the Linux Crew broker
id: crew-broker
continue-on-error: true
run: bash scripts/build-crew-broker-linux.sh target/crew-broker/linux-x86_64

- uses: actions/upload-artifact@v4
if: steps.crew-broker.outcome == 'success'
with:
name: windows-crew-broker-${{ inputs.version }}
path: target/crew-broker/linux-x86_64/
if-no-files-found: warn
retention-days: 7

- uses: actions/upload-artifact@v4
with:
name: windows-backend-${{ inputs.version }}
Expand All @@ -88,6 +111,13 @@ jobs:
with:
name: windows-backend-${{ inputs.version }}
path: target/x86_64-pc-windows-gnu/release/
# Missing when the backend job could not build the broker; see "Build and stage the
# Linux Crew broker" there. Non-fatal for the same reason.
- uses: actions/download-artifact@v4
continue-on-error: true
with:
name: windows-crew-broker-${{ inputs.version }}
path: target/crew-broker/linux-x86_64/

- uses: actions/setup-node@v4
with:
Expand Down Expand Up @@ -145,6 +175,20 @@ jobs:
cp -f target/x86_64-pc-windows-gnu/release/*.dll ui/desktop/src/bin/
ls -l ui/desktop/src/bin

# After the step above, which empties src/bin. prepare-platform-binaries.js checks the
# copy against its manifest; without one the package is built with a warning.
- name: Stage the Linux Crew broker into src/bin
shell: bash
run: |
staged=target/crew-broker/linux-x86_64
if [ ! -f "$staged/biorouter-crew" ] || [ ! -f "$staged/manifest.json" ]; then
echo "::warning::no Linux Crew broker was built for this run, so the Windows packages carry none and Crew setup from them cannot install a broker on a server"
exit 0
fi
mkdir -p ui/desktop/src/bin/crew-broker/linux-x86_64
cp -f "$staged/biorouter-crew" "$staged/manifest.json" ui/desktop/src/bin/crew-broker/linux-x86_64/
ls -l ui/desktop/src/bin/crew-broker/linux-x86_64

# ⚠ USE THE CANONICAL SCRIPT. Do not open-code build-main + download-mingit
# + `npm run make`. `npm run make` is
# `check-package-prereqs.mjs && fix-node-pty-permissions.mjs && electron-forge make`,
Expand Down Expand Up @@ -249,6 +293,18 @@ jobs:
fi
echo "packaged resources/bin carries the platform tooling and the llamacpp sidecar"

# The Crew broker, whenever one was staged: packaged, and the bytes its manifest
# describes, which is all the setup service will accept.
if [ -f target/crew-broker/linux-x86_64/manifest.json ]; then
node -e '
const { inspectCrewBroker } = require("./ui/desktop/scripts/crew-broker-resources");
const result = inspectCrewBroker(process.argv[1], { required: true, appVersion: process.argv[2] });
result.problems.forEach((problem) => console.log(`::error::${problem}`));
process.exit(result.problems.length > 0 ? 1 : 0);
' "$bin" "$v"
echo "packaged resources/bin carries the Crew broker and its manifest"
fi

# The two jobs check out the same ref of the same run, so this cannot
# currently disagree. Asserting it costs one line and turns an
# invariant into a check.
Expand Down
24 changes: 24 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2115,6 +2115,30 @@ replaced a standalone `biorouter-headless` binary and its Linux tarball, both de
biorouter-server` first. CI runs it in the `serve` job, because the workspace test job is
`--lib --bins` and never runs an integration binary.

### Crew (lab workspaces on a shared server)

User manual: [`docs/crew/`](docs/crew/README.md). Design contracts: `docs/crew/design/`, the October 2026
setup, open governance, deletion and full-access contract in
[`open-workspaces-and-automatic-setup.md`](docs/crew/design/open-workspaces-and-automatic-setup.md).

- **Where the code is.** One Linux binary, `biorouter-crew`, is both the host's broker and each member's
bridge: `crates/biorouter-crew` (`broker.rs`, `broker/join.rs`, `remote.rs` for folder mode,
`remote_full.rs` for full access, `probe.rs`). The daemon side is `crates/biorouter/src/crew/` (`mod.rs`
the manager, `setup.rs` the setup service the GUI and CLI share, `context.rs`, `host_start.rs`), routes in
`crates/biorouter-server/src/routes/crew*.rs`, agent tools in `agents/crew_extension.rs`, the CLI in
`crates/biorouter-cli/src/commands/crew/`, the GUI in `ui/desktop/src/components/crew/`.
- **Every build carries the broker** (`crew-broker/linux-x86_64/` beside `biorouterd`, with a manifest), and
setup sends it over SSH. Cross-build and stage it with
`scripts/build-crew-broker-linux.sh ui/desktop/src/bin/crew-broker/linux-x86_64` (`just stage-crew-broker`,
needs Docker); `BIOROUTER_CREW_BROKER_DIR` points a dev daemon at another copy.
- ⚠ **Folder mode needs Landlock ABI 3 (Linux 6.2+).** On an older kernel (Ubuntu 22.04's 5.15, such as
`leo.ucsf.edu`) every folder command is refused, and only full access ("As me on the server") runs commands.
- **The live two-account harness is not in the repo.** It lives in `~/biorouter-runs/crewleo/` (findings,
evidence and scripts against real accounts): read it for context, never commit it.
- `node scripts/check-crew-manual.mjs` holds the manual to the code (mutant suite:
`node --test scripts/check-crew-manual.test.mjs`). A new `crew_*` code, quoted string or data path needs
its line in `docs/crew/`.

### Communication Flow

```
Expand Down
15 changes: 15 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ make-ui-linux:
. scripts/cross-env.sh
echo "Step 1/2: Cross-compiling Rust binaries for Linux x64 via Docker ($LINUX_RUST_IMG)..."
cross_linux "cargo build --release"
# build-linux-deb.sh copies this into the package; it cannot stage it
# itself, because staging needs Docker and it runs inside a container.
./scripts/stage-crew-broker.sh target/x86_64-unknown-linux-gnu/release target/crew-broker/linux-x86_64
echo "Step 2/2: Packaging .deb via Docker (linux/amd64)..."
docker volume create biorouter-linux-npm-cache || true
docker run --rm \
Expand Down Expand Up @@ -163,6 +166,18 @@ build-cross:
./scripts/check-glibc-floor.sh
./scripts/check-crew-broker-join.sh

# Cross-build the Linux x86_64 Crew broker alone and stage it, with the manifest
# the setup service trusts, where the desktop app carries it (OW-9):
# ui/desktop/src/bin/crew-broker/linux-x86_64/{biorouter-crew,manifest.json}.
# The same cross recipe as the release (scripts/cross-env.sh), on a persistent
# Docker volume, so a rebuild takes about a minute. Needs Docker. `copy-binary`
# leaves it in place, but `make-ui-windows` empties src/bin before it packages,
# so its package carries no broker. A dev package without one builds with a
# warning; a release build refuses (prepare-platform-binaries.js with
# BIOROUTER_REQUIRE_CREW_BROKER=1).
stage-crew-broker:
./scripts/build-crew-broker-linux.sh ui/desktop/src/bin/crew-broker/linux-x86_64

# Build for Intel Mac
release-intel:
@echo "Building release version for Intel Mac..."
Expand Down
Loading
Loading