fix(adapters,sandboxes): tell agents where git works and make the refusal explicit (#223)

* fix(adapters,sandboxes): tell agents where git works and make the refusal explicit

Agents searched for the project repository in mounted host folders and read
the broker refusal as a missing broker. The prompt now names the folder where
git and gh work, and the refusal says to cd there instead of looking elsewhere.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tgvrj34NMnaqvtgvruYQZZ

* test(web): wait for the automatic voice start before switching speaking on

Clicking the switch while the app was still turning the voice on by itself
could turn it off again, which failed the voice settings e2e twice in a row.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tgvrj34NMnaqvtgvruYQZZ

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
cynarAI 2026-10-22 23:51:31 +02:00 committed by GitHub
parent de95cf1b91
commit 8a98bfe79f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 17 additions and 4 deletions

View File

@ -9,7 +9,14 @@ async function turnOnSpeaking(page: Page) {
await expect(voice.getByLabel("API key", { exact: true })).toHaveCount(0);
// The app turns the local voice on by itself the first time it starts.
const speaking = voice.getByRole("switch", { name: "Speaking on or off" });
if ((await speaking.getAttribute("aria-checked")) !== "true") await speaking.click();
// Clicking before the automatic start has settled would turn the voice off again.
const startedByItself = await expect(speaking)
.toHaveAttribute("aria-checked", "true", { timeout: 5_000 })
.then(
() => true,
() => false,
);
if (!startedByItself) await speaking.click();
await expect(speaking).toHaveAttribute("aria-checked", "true");
await expect(voice.getByTestId("voice-carousel")).toBeVisible();
return voice;

View File

@ -13,6 +13,7 @@ import {
gitProcessIdentity,
hostGitInvocation,
hostPathFor,
outsideWorkspaceMessage,
} from "./github-broker.js";
import {
demuxDockerLogs,
@ -76,7 +77,7 @@ describe("github broker host git", () => {
it("refuses paths outside the mounted workspace", () => {
expect(hostGitInvocation(session, ["git", "clone", "https://x/y.git"], "/tmp")).toEqual({
error: "Run git inside /home/rakazo.",
error: outsideWorkspaceMessage("/home/rakazo"),
});
expect(
hostGitInvocation(session, ["git", "clone", "https://x/y.git", "/etc/y"], "/home/rakazo"),

View File

@ -60,6 +60,11 @@ export function explainGitFailure(stderr: string): string {
return `${stderr.trimEnd()}\nGitHub rejected the token evOo stores for this user. Tell the user to reconnect GitHub under Settings, Integrations. Do not ask for a token or set one up yourself.\n`;
}
/** Names the one place git works, so a model does not read the refusal as a missing broker or hunt for the repository elsewhere. */
export function outsideWorkspaceMessage(root: string): string {
return `git only works inside ${root}, which holds this project's repository. Run: cd ${root}. Other folders, mounted host folders and ssh are not part of it. Do not ask for a token.`;
}
/** Host argv and cwd for a git call made in the computer, or an error when it leaves the workspace. */
export function hostGitInvocation(
session: GithubBrokerSession,
@ -67,7 +72,7 @@ export function hostGitInvocation(
containerCwd: string | undefined,
): { argv: string[]; cwd: string } | { error: string } {
const cwd = containerCwd ? hostPathFor(session, containerCwd) : session.workspacePath;
if (!cwd) return { error: `Run git inside ${session.containerRoot}.` };
if (!cwd) return { error: outsideWorkspaceMessage(session.containerRoot) };
const mapped: string[] = [];
for (const part of argv.slice(1)) {
if (!part.startsWith("/")) {

View File

@ -1720,7 +1720,7 @@ export function createRunExecutor(deps: ExecutorDeps) {
teamComputer: computerMode === "team",
});
const gitBrokerPolicySuffix = githubIntegrationToken
? " Git push and opening pull requests require the user's approval once per run; never force-push or push to the default branch."
? ` git and gh work only inside ${projectWorkspacePath ? "/home/rakazo/project" : "/home/rakazo"}${projectWorkspacePath ? ", the space's repository" : ""}; look for the repository and its branches there, not in other folders, and never over ssh. Git push and opening pull requests require the user's approval once per run; never force-push or push to the default branch.`
: "";
const hostAccessNote = process.env.RAKAZO_HOST_ACCESS_NOTE?.trim();
const desktopHostSuffix = isDesktopHost